From 937fc48b37fafe3ffc8f4b52bd9a171bbb4d3a37 Mon Sep 17 00:00:00 2001 From: Owen Lin <> Date: Tue, 14 Apr 2009 02:02:51 -0700 Subject: AI 146099: 1. Use ICancelable to replace several different interfaces, such as IGetBooleanCancelable. 2. Remove some warnings. Automated import of CL 146099 --- src/com/android/camera/BitmapManager.java | 96 ++++----- src/com/android/camera/Camera.java | 26 +-- src/com/android/camera/CropImage.java | 24 +-- src/com/android/camera/DrmWallpaper.java | 2 + src/com/android/camera/ExifInterface.java | 35 ++-- src/com/android/camera/GalleryPicker.java | 18 +- src/com/android/camera/HighlightView.java | 75 ++++--- src/com/android/camera/ImageGallery2.java | 90 +++------ src/com/android/camera/ImageManager.java | 53 +++-- src/com/android/camera/ImageViewTouchBase.java | 63 +++--- src/com/android/camera/MenuHelper.java | 14 +- src/com/android/camera/MovieView.java | 9 +- .../android/camera/PhotoAppWidgetConfigure.java | 18 +- src/com/android/camera/PhotoAppWidgetProvider.java | 29 ++- src/com/android/camera/ThumbnailController.java | 4 +- src/com/android/camera/Util.java | 214 ++++++++++++++++++++ src/com/android/camera/VideoCamera.java | 5 +- src/com/android/camera/VideoPreview.java | 1 - src/com/android/camera/ViewImage.java | 44 ++--- src/com/android/camera/Wallpaper.java | 2 - src/com/android/camera/gallery/BaseCancelable.java | 2 +- src/com/android/camera/gallery/BaseImage.java | 14 +- src/com/android/camera/gallery/BaseImageList.java | 8 +- .../camera/gallery/IAddImageCancelable.java | 10 - src/com/android/camera/gallery/ICancelable.java | 4 +- .../camera/gallery/IGetBitmapCancelable.java | 27 --- .../camera/gallery/IGetBooleanCancelable.java | 24 --- src/com/android/camera/gallery/IImage.java | 2 +- src/com/android/camera/gallery/Image.java | 19 +- src/com/android/camera/gallery/ImageList.java | 1 + src/com/android/camera/gallery/ImageListUber.java | 1 - src/com/android/camera/gallery/MiniThumbFile.java | 9 +- .../android/camera/gallery/SingleImageList.java | 9 +- src/com/android/camera/gallery/Util.java | 216 --------------------- src/com/android/camera/gallery/VideoList.java | 5 +- src/com/android/camera/gallery/VideoObject.java | 6 +- 36 files changed, 530 insertions(+), 649 deletions(-) create mode 100644 src/com/android/camera/Util.java delete mode 100644 src/com/android/camera/gallery/IAddImageCancelable.java delete mode 100644 src/com/android/camera/gallery/IGetBitmapCancelable.java delete mode 100644 src/com/android/camera/gallery/IGetBooleanCancelable.java delete mode 100644 src/com/android/camera/gallery/Util.java (limited to 'src') diff --git a/src/com/android/camera/BitmapManager.java b/src/com/android/camera/BitmapManager.java index 7aa237b..84eae54 100644 --- a/src/com/android/camera/BitmapManager.java +++ b/src/com/android/camera/BitmapManager.java @@ -30,8 +30,8 @@ import java.util.WeakHashMap; /** * This class provides several utilities to cancel/prevent potential heavy * loading of CPU in bitmap decoding. - * - * To use this class, be sure to call setAllowDecoding(true) in onResume + * + * To use this class, be sure to call setAllowDecoding(true) in onResume * and turn it off by cancelAllDecoding() in onPause, and replace all * BitmapFactory.decodeFileDescriptor with BitmapManager.decodeFileDescriptor. * @@ -45,13 +45,15 @@ public class BitmapManager { private static class ThreadStatus { public State state = State.WAIT; public BitmapFactory.Options options; + + @Override public String toString() { String s; if (state == State.RUNNING) { s = "Running"; } else if (state == State.CANCEL) { s = "Cancel"; - } else { + } else { s = "Wait"; } s = "thread state = " + s + ", options = " + options; @@ -74,19 +76,19 @@ public class BitmapManager { private BitmapManager() { } - + public synchronized void setCheckResourceLock(boolean b) { mCheckResourceLock = b; } - + private synchronized boolean checkResourceLock() { return mCheckResourceLock; } - + /** * Get thread status and create one if specified. */ - private synchronized ThreadStatus getThreadStatus(Thread t, + private synchronized ThreadStatus getThreadStatus(Thread t, boolean createNew) { ThreadStatus status = mThreadStatus.get(t); if (status == null && createNew) { @@ -97,23 +99,23 @@ public class BitmapManager { } /** - * Since Bitmap related operations are resource-intensive (CPU/Memory), + * Since Bitmap related operations are resource-intensive (CPU/Memory), * we can't affort too many threads running at the same time, so only * thread that acquire the lock can proceed, others have to wait in the * queue. It can also be canceled and removed by other thread to avoid * starvation. - */ + */ public synchronized boolean acquireResourceLock() { Thread t = Thread.currentThread(); ThreadStatus status = getThreadStatus(t, true); - + if (VERBOSE) { Log.v(TAG, "lock... thread " + t + "(" + t.getId() + ")"); } while (mLocked) { try { - if (VERBOSE) { + if (VERBOSE) { Log.v(TAG, "waiting... thread " + t.getId()); } wait(); @@ -127,7 +129,7 @@ public class BitmapManager { } catch (InterruptedException ex) { Log.e(TAG, ex.toString()); } - + } if (VERBOSE) { Log.v(TAG, "locked... thread " + t + "(" + t.getId() + ")"); @@ -136,7 +138,7 @@ public class BitmapManager { mLocked = true; return true; } - + /** * Make sure "acquire/release" are pairing correctly */ @@ -150,10 +152,10 @@ public class BitmapManager { } /** - * The following three methods are used to keep track of + * The following three methods are used to keep track of * BitmapFaction.Options used for decoding and cancelling. - */ - private synchronized void setDecodingOptions(Thread t, + */ + private synchronized void setDecodingOptions(Thread t, BitmapFactory.Options options) { if (VERBOSE) { Log.v(TAG, "setDecodingOptions for thread " + t.getId() @@ -161,12 +163,12 @@ public class BitmapManager { } getThreadStatus(t, true).options = options; } - + synchronized BitmapFactory.Options getDecodingOptions(Thread t) { ThreadStatus status = mThreadStatus.get(t); return status != null ? status.options : null; } - + synchronized void removeDecodingOptions(Thread t) { if (VERBOSE) { Log.v(TAG, "removeDecodingOptions for thread " + t.getId()); @@ -185,8 +187,8 @@ public class BitmapManager { Log.v(TAG, "can't find status for thread " + t); return false; } - - boolean result = (status.state == State.RUNNING) || + + boolean result = (status.state == State.RUNNING) || (status.state != State.CANCEL && !mCheckResourceLock); if (VERBOSE) { Log.v(TAG, "canThread " + t + " allow to decode " @@ -194,17 +196,17 @@ public class BitmapManager { } return result; } - + public synchronized void allowThreadDecoding(Thread t) { if (VERBOSE) { Log.v(TAG, "allowThreadDecoding: " + t + "(" + t.getId() + ")"); } getThreadStatus(t, true).state = State.WAIT; } - + public synchronized void cancelThreadDecoding(Thread t) { if (VERBOSE) { - Log.v(TAG, "[Cancel Thread] cancelThreadDecode: " + Log.v(TAG, "[Cancel Thread] cancelThreadDecode: " + t + "(" + t.getId() + ")"); } ThreadStatus status = getThreadStatus(t, true); @@ -215,13 +217,13 @@ public class BitmapManager { } status.options.requestCancelDecode(); } - + // Wake up threads in waiting list notifyAll(); } - + /** - * The following four methods are used to control global switch of + * The following four methods are used to control global switch of * bitmap decoding. */ public synchronized void cancelAllDecoding() { @@ -238,49 +240,49 @@ public class BitmapManager { status.options.requestCancelDecode(); } } - + // Wake up all threads in the waiting list notifyAll(); } - + public synchronized void allowAllDecoding() { allowAllDecoding(true); } - + public synchronized void allowAllDecoding(boolean reset) { if (VERBOSE) { Log.v(TAG, ">>>>>>>> allowAllDecoding <<<<<<<"); } mAllowDecoding = true; - if (reset) { + if (reset) { mThreadStatus.clear(); } } - + public synchronized boolean canDecode() { return mAllowDecoding; } - + /** * A debugging routine. */ public synchronized void dump() { - Iterator> i = + Iterator> i = mThreadStatus.entrySet().iterator(); - + while (i.hasNext()) { Map.Entry entry = i.next(); - Log.v(TAG, "[Dump] Thread " + entry.getKey() + " (" + Log.v(TAG, "[Dump] Thread " + entry.getKey() + " (" + entry.getKey().getId() + ")'s status is " + entry.getValue()); } } - + /** * The real place to delegate bitmap decoding to BitmapFactory. */ - public Bitmap decodeFileDescriptor(FileDescriptor fd, - Rect outPadding, + public Bitmap decodeFileDescriptor(FileDescriptor fd, + Rect outPadding, BitmapFactory.Options options) { // Does the global switch turn on? if (!canDecode() || options.mCancel) { @@ -288,9 +290,9 @@ public class BitmapManager { Log.v(TAG, "Not allowed to decode."); } return null; - } - - // Can current thread decode? + } + + // Can current thread decode? Thread thread = Thread.currentThread(); if (!canThreadDecoding(thread)) { if (VERBOSE) { @@ -299,27 +301,27 @@ public class BitmapManager { } return null; } - + setDecodingOptions(thread, options); if (VERBOSE) { - Log.v(TAG, "decodeFileDescriptor: " + options + ", cancel=" + Log.v(TAG, "decodeFileDescriptor: " + options + ", cancel=" + options.mCancel); } long t = System.currentTimeMillis(); Bitmap b = BitmapFactory.decodeFileDescriptor(fd, null, options); - + // In case legacy code cancel it in traditional way if (options.mCancel) { cancelThreadDecoding(thread); } if (VERBOSE) { - Log.v(TAG, "decodeFileDescriptor done: options=" + options - + ", cancel=" + options.mCancel + ", it takes " + Log.v(TAG, "decodeFileDescriptor done: options=" + options + + ", cancel=" + options.mCancel + ", it takes " + (System.currentTimeMillis() - t) + " ms."); } removeDecodingOptions(thread); - + return b; } } diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java index fee6410..d8f6e67 100644 --- a/src/com/android/camera/Camera.java +++ b/src/com/android/camera/Camera.java @@ -16,7 +16,7 @@ package com.android.camera; -import com.android.camera.gallery.IAddImageCancelable; +import com.android.camera.gallery.ICancelable; import com.android.camera.gallery.IImage; import com.android.camera.gallery.IImageList; @@ -227,7 +227,7 @@ public class Camera extends Activity implements View.OnClickListener, } } } - }; + } LocationListener [] mLocationListeners = new LocationListener[] { new LocationListener(LocationManager.GPS_PROVIDER), @@ -308,7 +308,7 @@ public class Camera extends Activity implements View.OnClickListener, public Location current() { return mValid ? mLastLocation : null; } - }; + } private boolean mImageSavingItem = false; @@ -331,7 +331,7 @@ public class Camera extends Activity implements View.OnClickListener, Size pictureSize = mParameters.getPictureSize(); mSurfaceView.setAspectRatio(pictureSize.width, pictureSize.height); } - }; + } private final class RawPictureCallback implements PictureCallback { public void onPictureTaken( @@ -346,7 +346,7 @@ public class Camera extends Activity implements View.OnClickListener, + " ShutterCallback and RawPictureCallback."); } } - }; + } private final class JpegPictureCallback implements PictureCallback { Location mLocation; @@ -384,7 +384,7 @@ public class Camera extends Activity implements View.OnClickListener, RESTART_PREVIEW, Math.max(delay, 0)); } } - }; + } private final class AutoFocusCallback implements android.hardware.Camera.AutoFocusCallback { @@ -421,7 +421,7 @@ public class Camera extends Activity implements View.OnClickListener, } updateFocusIndicator(); } - }; + } private class ImageCapture implements Capturer { @@ -429,7 +429,7 @@ public class Camera extends Activity implements View.OnClickListener, private boolean mCapturing = false; private Uri mLastContentUri; - private IAddImageCancelable mAddImageCancelable; + private ICancelable mAddImageCancelable; Bitmap mCaptureOnlyBitmap; @@ -1443,31 +1443,31 @@ public class Camera extends Activity implements View.OnClickListener, // if we depended on it we would have to query the size again mParameters = mCameraDevice.getParameters(); mParameters.setPreviewSize(mViewFinderWidth, mViewFinderHeight); - + // Set white balance parameter. String whiteBalance = mPreferences.getString( CameraSettings.KEY_WHITE_BALANCE, getString(R.string.pref_camera_whitebalance_default)); mParameters.set(PARM_WHITE_BALANCE, whiteBalance); - + // Set effect parameter. String effect = mPreferences.getString( CameraSettings.KEY_EFFECT, getString(R.string.pref_camera_effect_default)); mParameters.set(PARM_EFFECT, effect); - + // Set picture size parameter. String pictureSize = mPreferences.getString( CameraSettings.KEY_PICTURE_SIZE, getString(R.string.pref_camera_picturesize_default)); mParameters.set(PARM_PICTURE_SIZE, pictureSize); - + // Set JPEG quality parameter. String jpegQuality = mPreferences.getString( CameraSettings.KEY_JPEG_QUALITY, getString(R.string.pref_camera_jpegquality_default)); mParameters.set(PARM_JPEG_QUALITY, jpegQuality); - + mCameraDevice.setParameters(mParameters); } diff --git a/src/com/android/camera/CropImage.java b/src/com/android/camera/CropImage.java index adb3d9c..2702e67 100644 --- a/src/com/android/camera/CropImage.java +++ b/src/com/android/camera/CropImage.java @@ -16,7 +16,7 @@ package com.android.camera; -import com.android.camera.gallery.IAddImageCancelable; +import com.android.camera.gallery.ICancelable; import com.android.camera.gallery.IImage; import com.android.camera.gallery.IImageList; @@ -226,7 +226,7 @@ public class CropImage extends Activity { } }).start(); } - + private void onSaveClicked() { // TODO this code needs to change to use the decode/crop/encode single // step api so that we don't require that the whole (possibly large) @@ -382,9 +382,7 @@ public class CropImage extends Activity { } try { - Uri newUri = ImageManager - .instance() - .addImage( + Uri newUri = ImageManager.instance().addImage( CropImage.this, getContentResolver(), mImage.getTitle(), @@ -398,9 +396,8 @@ public class CropImage extends Activity { directory.toString(), fileName + "-" + x + ".jpg"); - IAddImageCancelable cancelable = - ImageManager.instance() - .storeImage( + ICancelable cancelable = + ImageManager.instance().storeImage( newUri, CropImage.this, getContentResolver(), @@ -424,14 +421,16 @@ public class CropImage extends Activity { Thread t = new Thread(r); t.start(); } - + } - + + @Override public void onResume() { super.onResume(); BitmapManager.instance().allowAllDecoding(); } + @Override public void onPause() { super.onPause(); BitmapManager.instance().cancelAllDecoding(); @@ -528,7 +527,7 @@ public class CropImage extends Activity { // 256 pixels wide is enough. if (mBitmap.getWidth() > 256) { - mScale = 256.0F / (float) mBitmap.getWidth(); + mScale = 256.0F / mBitmap.getWidth(); } Matrix matrix = new Matrix(); matrix.setScale(mScale, mScale); @@ -622,6 +621,7 @@ class CropImageView extends ImageViewTouchBase { super(context, attrs); } + @Override protected void zoomTo(float scale, float centerX, float centerY) { super.zoomTo(scale, centerX, centerY); for (HighlightView hv : mHighlightViews) { @@ -630,6 +630,7 @@ class CropImageView extends ImageViewTouchBase { } } + @Override protected void zoomIn() { super.zoomIn(); for (HighlightView hv : mHighlightViews) { @@ -638,6 +639,7 @@ class CropImageView extends ImageViewTouchBase { } } + @Override protected void zoomOut() { super.zoomOut(); for (HighlightView hv : mHighlightViews) { diff --git a/src/com/android/camera/DrmWallpaper.java b/src/com/android/camera/DrmWallpaper.java index d6bf039..643b876 100644 --- a/src/com/android/camera/DrmWallpaper.java +++ b/src/com/android/camera/DrmWallpaper.java @@ -23,6 +23,8 @@ import android.content.Intent; * action. */ public class DrmWallpaper extends Wallpaper { + + @Override protected void formatIntent(Intent intent) { super.formatIntent(intent); intent.putExtra("pick-drm", true); diff --git a/src/com/android/camera/ExifInterface.java b/src/com/android/camera/ExifInterface.java index 94eab48..9c8d410 100644 --- a/src/com/android/camera/ExifInterface.java +++ b/src/com/android/camera/ExifInterface.java @@ -31,11 +31,11 @@ public class ExifInterface { public static final int ORIENTATION_NORMAL = 1; // left right reversed mirror - public static final int ORIENTATION_FLIP_HORIZONTAL = 2; + public static final int ORIENTATION_FLIP_HORIZONTAL = 2; public static final int ORIENTATION_ROTATE_180 = 3; // upside down mirror - public static final int ORIENTATION_FLIP_VERTICAL = 4; + public static final int ORIENTATION_FLIP_VERTICAL = 4; // flipped about top-left <--> bottom-right axis public static final int ORIENTATION_TRANSPOSE = 5; @@ -51,7 +51,7 @@ public class ExifInterface { // The Exif tag names public static final String TAG_ORIENTATION = "Orientation"; - + static final String TAG_DATE_TIME_ORIGINAL = "DateTimeOriginal"; static final String TAG_MAKE = "Make"; static final String TAG_MODEL = "Model"; @@ -61,7 +61,7 @@ public class ExifInterface { static final String TAG_GPS_LATITUDE = "GPSLatitude"; static final String TAG_GPS_LONGITUDE = "GPSLongitude"; - + static final String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef"; static final String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef"; @@ -97,14 +97,14 @@ public class ExifInterface { --size; } sb.append(size + " "); - Iterator keyIterator = attributes.keySet().iterator(); + Iterator keyIterator = attributes.keySet().iterator(); while (keyIterator.hasNext()) { - String key = (String) keyIterator.next(); + String key = keyIterator.next(); if (key.equals("hasThumbnail")) { // this is a fake attribute not saved as an exif tag continue; } - String val = (String) attributes.get(key); + String val = attributes.get(key); sb.append(key + "="); sb.append(val.length() + " "); sb.append(val); @@ -260,14 +260,14 @@ public class ExifInterface { / Float.parseFloat(pair[1].trim()); float result = degrees + (minutes / 60F) + (seconds / (60F * 60F)); - + String preliminaryResult = String.valueOf(result); if (usePositiveNegative) { String neg = (ref.equals("S") || ref.equals("E")) ? "-" : ""; return neg + preliminaryResult; } else { return preliminaryResult + String.valueOf((char) 186) + " " - + ref; + + ref; } } catch (RuntimeException ex) { // if for whatever reason we can't parse the lat long then return @@ -275,26 +275,25 @@ public class ExifInterface { return null; } } - + public static String makeLatLongString(double d) { d = Math.abs(d); - + int degrees = (int) d; - - double remainder = d - (double) degrees; + + double remainder = d - degrees; int minutes = (int) (remainder * 60D); // really seconds * 1000 int seconds = (int) (((remainder * 60D) - minutes) * 60D * 1000D); - - String retVal = degrees + "/1," + minutes + "/1," + (int) seconds - + "/1000"; + + String retVal = degrees + "/1," + minutes + "/1," + seconds + "/1000"; return retVal; } - + public static String makeLatStringRef(double lat) { return lat >= 0D ? "N" : "S"; } - + public static String makeLonStringRef(double lon) { return lon >= 0D ? "W" : "E"; } diff --git a/src/com/android/camera/GalleryPicker.java b/src/com/android/camera/GalleryPicker.java index 25c0e42..30e8b72 100644 --- a/src/com/android/camera/GalleryPicker.java +++ b/src/com/android/camera/GalleryPicker.java @@ -46,19 +46,19 @@ import android.provider.MediaStore.Images; import android.util.Config; import android.util.Log; import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; -import android.view.MenuItem.OnMenuItemClickListener; import android.view.View; import android.view.ViewGroup; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.MenuItem.OnMenuItemClickListener; import android.widget.AdapterView; -import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.BaseAdapter; import android.widget.GridView; import android.widget.TextView; import android.widget.Toast; +import android.widget.AdapterView.AdapterContextMenuInfo; import java.util.ArrayList; import java.util.HashMap; @@ -177,7 +177,7 @@ public class GalleryPicker extends Activity { launchFolderGallery(position); } }); - + mGridView.setOnCreateContextMenuListener( new View.OnCreateContextMenuListener() { public void onCreateContextMenu(ContextMenu menu, View v, @@ -185,10 +185,10 @@ public class GalleryPicker extends Activity { onCreateGalleryPickerContextMenu(menu, menuInfo); } }); - + ImageManager.ensureOSXCompatibleFolder(); } - + // This is called when we receive media-related broadcast. private void onReceiveMediaBroadcast(Intent intent) { if (Config.LOGV) { @@ -594,7 +594,7 @@ public class GalleryPicker extends Activity { TextView titleView = (TextView) v.findViewById(R.id.title); - GalleryPickerItem iv = + GalleryPickerItem iv = (GalleryPickerItem) v.findViewById(R.id.thumbnail); iv.setOverlay(mItems.get(position).getOverlay()); ItemInfo info = mItems.get(position).mThumb; @@ -610,13 +610,13 @@ public class GalleryPicker extends Activity { return v; } - }; + } @Override public void onPause() { super.onPause(); mPausing = true; - + BitmapManager.instance().cancelAllDecoding(); unregisterReceiver(mReceiver); diff --git a/src/com/android/camera/HighlightView.java b/src/com/android/camera/HighlightView.java index ed8a9fb..4565bf8 100644 --- a/src/com/android/camera/HighlightView.java +++ b/src/com/android/camera/HighlightView.java @@ -24,9 +24,6 @@ import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region; import android.graphics.drawable.Drawable; -import android.util.Config; -import android.util.Log; -import android.view.KeyEvent; import android.view.View; // This class is used by CropImage to display a highlighted cropping rectangle @@ -34,6 +31,8 @@ import android.view.View; // image, another is screen. computeLayout() uses mMatrix to map from image // space to screen space. class HighlightView { + + @SuppressWarnings("unused") private static final String TAG = "HighlightView"; View mContext; // The View displaying the image. @@ -43,7 +42,7 @@ class HighlightView { public static final int GROW_TOP_EDGE = (1 << 3); public static final int GROW_BOTTOM_EDGE = (1 << 4); public static final int MOVE = (1 << 5); - + public HighlightView(View ctx) { mContext = ctx; } @@ -57,26 +56,26 @@ class HighlightView { mResizeDrawableDiagonal = resources.getDrawable(R.drawable.indicator_autocrop); } - + boolean mIsFocused; boolean mHidden; - + public boolean hasFocus() { return mIsFocused; } - + public void setFocus(boolean f) { mIsFocused = f; } - + public void setHidden(boolean hidden) { mHidden = hidden; } - + protected void draw(Canvas canvas) { if (mHidden) { return; - } + } canvas.save(); Path path = new Path(); if (!hasFocus()) { @@ -88,9 +87,9 @@ class HighlightView { if (mCircle) { float width = mDrawRect.width(); float height = mDrawRect.height(); - path.addCircle(mDrawRect.left + (width / 2), + path.addCircle(mDrawRect.left + (width / 2), mDrawRect.top + (height / 2), - width / 2, + width / 2, Path.Direction.CW); mOutlinePaint.setColor(0xFFEF04D6); } else { @@ -108,7 +107,7 @@ class HighlightView { if (mCircle) { int width = mResizeDrawableDiagonal.getIntrinsicWidth(); int height = mResizeDrawableDiagonal.getIntrinsicHeight(); - + int d = (int) Math.round(Math.cos(/*45deg*/Math.PI / 4D) * (mDrawRect.width() / 2D)); int x = mDrawRect.left @@ -154,42 +153,42 @@ class HighlightView { mResizeDrawableHeight.setBounds(xMiddle - heightWidth, top - heightHeight, xMiddle + heightWidth, - top + heightHeight); + top + heightHeight); mResizeDrawableHeight.draw(canvas); mResizeDrawableHeight.setBounds(xMiddle - heightWidth, bottom - heightHeight, xMiddle + heightWidth, - bottom + heightHeight); + bottom + heightHeight); mResizeDrawableHeight.draw(canvas); } } } } - + public ModifyMode getMode() { return mMode; } - + public void setMode(ModifyMode mode) { if (mode != mMode) { mMode = mode; mContext.invalidate(); } } - + // Determines which edges are hit by touching at (x, y). public int getHit(float x, float y) { Rect r = computeLayout(); final float hysteresis = 20F; int retval = GROW_NONE; - + if (mCircle) { float distX = x - r.centerX(); float distY = y - r.centerY(); int distanceFromCenter = (int) Math.sqrt(distX * distX + distY * distY); - int radius = (int) (mDrawRect.width()) / 2; + int radius = mDrawRect.width() / 2; int delta = distanceFromCenter - radius; if (Math.abs(delta) <= hysteresis) { if (Math.abs(distY) > Math.abs(distX)) { @@ -254,7 +253,7 @@ class HighlightView { if (((GROW_LEFT_EDGE | GROW_RIGHT_EDGE) & edge) == 0) { dx = 0; } - + if (((GROW_TOP_EDGE | GROW_BOTTOM_EDGE) & edge) == 0) { dy = 0; } @@ -266,20 +265,20 @@ class HighlightView { (((edge & GROW_TOP_EDGE) != 0) ? -1 : 1) * yDelta); } } - + // Grows the cropping rectange by (dx, dy) in image space. void moveBy(float dx, float dy) { Rect invalRect = new Rect(mDrawRect); mCropRect.offset(dx, dy); - + // Put the cropping rectangle inside image rectangle. mCropRect.offset( - Math.max(0, mImageRect.left - mCropRect.left), + Math.max(0, mImageRect.left - mCropRect.left), Math.max(0, mImageRect.top - mCropRect.top)); mCropRect.offset( - Math.min(0, mImageRect.right - mCropRect.right), + Math.min(0, mImageRect.right - mCropRect.right), Math.min(0, mImageRect.bottom - mCropRect.bottom)); mDrawRect = computeLayout(); @@ -287,7 +286,7 @@ class HighlightView { invalRect.inset(-10, -10); mContext.invalidate(invalRect); } - + // Grows the cropping rectange by (dx, dy) in image space. void growBy(float dx, float dy) { if (mMaintainAspectRatio) { @@ -318,7 +317,7 @@ class HighlightView { } r.inset(-dx, -dy); - + // Don't let the cropping rectangle shrink too fast. final float widthCap = 25F; if (r.width() < widthCap) { @@ -330,7 +329,7 @@ class HighlightView { if (r.height() < heightCap) { r.inset(0F, -(heightCap - r.height()) / 2F); } - + // Put the cropping rectangle inside the image rectangle. if (r.left < mImageRect.left) { r.offset(mImageRect.left - r.left, 0F); @@ -347,13 +346,13 @@ class HighlightView { mDrawRect = computeLayout(); mContext.invalidate(); } - + // Returns the cropping rectangle in image space. public Rect getCropRect() { return new Rect((int) mCropRect.left, (int) mCropRect.top, (int) mCropRect.right, (int) mCropRect.bottom); } - + // Maps the cropping rectangle from image space to screen space. private Rect computeLayout() { RectF r = new RectF(mCropRect.left, mCropRect.top, @@ -362,11 +361,11 @@ class HighlightView { return new Rect(Math.round(r.left), Math.round(r.top), Math.round(r.right), Math.round(r.bottom)); } - + public void invalidate() { mDrawRect = computeLayout(); } - + public void setup(Matrix m, Rect imageRect, RectF cropRect, boolean circle, boolean maintainAspectRatio) { if (circle) { @@ -381,7 +380,7 @@ class HighlightView { mInitialAspectRatio = mCropRect.width() / mCropRect.height(); mDrawRect = computeLayout(); - + mFocusPaint.setARGB(125, 50, 50, 50); mNoFocusPaint.setARGB(125, 50, 50, 50); mOutlinePaint.setStrokeWidth(3F); @@ -391,11 +390,11 @@ class HighlightView { mMode = ModifyMode.None; init(); } - - enum ModifyMode { None, Move, Grow }; - + + enum ModifyMode { None, Move, Grow } + private ModifyMode mMode = ModifyMode.None; - + Rect mDrawRect; // in screen space private RectF mImageRect; // in image space RectF mCropRect; // in image space @@ -404,7 +403,7 @@ class HighlightView { private boolean mMaintainAspectRatio = false; private float mInitialAspectRatio; private boolean mCircle = false; - + private Drawable mResizeDrawableWidth; private Drawable mResizeDrawableHeight; private Drawable mResizeDrawableDiagonal; diff --git a/src/com/android/camera/ImageGallery2.java b/src/com/android/camera/ImageGallery2.java index 9efa76b..5c1e8a7 100644 --- a/src/com/android/camera/ImageGallery2.java +++ b/src/com/android/camera/ImageGallery2.java @@ -50,7 +50,6 @@ import android.util.Config; import android.util.Log; import android.view.ContextMenu; import android.view.GestureDetector; -import android.view.GestureDetector.SimpleOnGestureListener; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; @@ -58,6 +57,7 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.Window; +import android.view.GestureDetector.SimpleOnGestureListener; import android.widget.Scroller; import android.widget.TextView; import android.widget.Toast; @@ -160,7 +160,7 @@ public class ImageGallery2 extends Activity { startActivity(intent); return true; } - + private Runnable mDeletePhotoRunnable = new Runnable() { public void run() { mGvs.clearCache(); @@ -215,14 +215,14 @@ public class ImageGallery2 extends Activity { // Don't process event in pause state. return (!mPausing) && (mGvs.mCurrentSpec != null); } - + @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (!canHandleEvent()) return false; - + if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { mGvs.select(-2, false); - + // The keyUp doesn't get called when the longpress menu comes up. We // only get here when the user lets go of the center key before the // longpress menu comes up. @@ -236,11 +236,11 @@ public class ImageGallery2 extends Activity { } return super.onKeyUp(keyCode, event); } - + @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (!canHandleEvent()) return false; - + boolean handled = true; int sel = mGvs.mCurrentSelection; int columns = mGvs.mCurrentSpec.mColumns; @@ -329,7 +329,7 @@ public class ImageGallery2 extends Activity { // return if there image file is not available. return; } - + if (size > mVideoSizeLimit) { DialogInterface.OnClickListener buttonListener = @@ -422,7 +422,7 @@ public class ImageGallery2 extends Activity { public void onPause() { super.onPause(); mPausing = true; - + BitmapManager.instance().cancelAllDecoding(); stopCheckingThumbnails(); mGvs.onPause(); @@ -486,7 +486,7 @@ public class ImageGallery2 extends Activity { @Override public void onResume() { super.onResume(); - + BitmapManager.instance().allowAllDecoding(); try { @@ -687,11 +687,6 @@ public class ImageGallery2 extends Activity { return true; } - private boolean isImageSelected() { - IImage image = mSelectedImageGetter.getCurrentImage(); - return (image != null) && ImageManager.isImage(image); - } - private boolean isVideoSelected() { IImage image = mSelectedImageGetter.getCurrentImage(); return (image != null) && ImageManager.isVideo(image); @@ -871,7 +866,7 @@ class GridViewSpecial extends View { int mCellWidth, mCellHeight; int mLeftEdgePadding, mRightEdgePadding; int mCellSpacing; - }; + } private LayoutSpec [] mCellSizeChoices = new LayoutSpec[] { new LayoutSpec(0, 67, 67, 14, 14, 8), @@ -1127,7 +1122,7 @@ class GridViewSpecial extends View { Bitmap scaleTo(int width, int height, Bitmap b) { Matrix m = new Matrix(); - m.setScale((float) width / 64F, (float) height / 64F); + m.setScale(width / 64F, height / 64F); Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, false); if (b2 != b) { @@ -1344,7 +1339,7 @@ class GridViewSpecial extends View { final int firstVisBlock = Math.max(0, (mScrollY - mCurrentSpec.mCellSpacing) / blockHeight); - final int lastVisBlock = + final int lastVisBlock = (mScrollY - mCurrentSpec.mCellSpacing + getHeight()) / blockHeight; @@ -1447,7 +1442,7 @@ class GridViewSpecial extends View { for (int i = 0; i < numBlocks; i++) { int index = (mBlockCacheStartOffset + i) % numBlocks; ImageBlock block = blocks[index]; - int blockNum = block.mBlockNumber; + int blockNum = block.mBlockNumber; boolean isVis = blockNum >= firstVisBlock && blockNum <= lastVisBlock; block.setVisibility(isVis); @@ -1467,42 +1462,6 @@ class GridViewSpecial extends View { } } - private void check() { - ImageBlock [] blocks = mBlockCache; - int blockLength = blocks.length; - - // check the results - for (int i = 0; i < blockLength; i++) { - int index = (mBlockCacheStartOffset + i) % blockLength; - if (blocks[index].mBlockNumber - != mBlockCacheFirstBlockNumber + i) { - if (blocks[index].mBlockNumber != -1) { - Log.e(TAG, "at " + i - + " block cache corrupted; found " - + blocks[index].mBlockNumber - + " but wanted " - + (mBlockCacheFirstBlockNumber + i) - + "; offset is " + mBlockCacheStartOffset); - } - } - } - if (true) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < blockLength; i++) { - int index = (mBlockCacheStartOffset + i) % blockLength; - ImageBlock b = blocks[index]; - if (b.mRequestedMask != 0) { - sb.append("X"); - } else { - sb.append(String.valueOf(b.mBlockNumber) + " "); - } - } - if (Config.LOGV) { - Log.v(TAG, "moveDataWindow " + sb.toString()); - } - } - } - void doDraw(Canvas canvas) { synchronized (ImageBlockManager.this) { ImageBlockManager.ImageBlock [] blocks = mBlockCache; @@ -1532,11 +1491,11 @@ class GridViewSpecial extends View { currentBlock += 1; continue; } - int effectiveOffset = - (mBlockCacheStartOffset - + (currentBlock++ - mBlockCacheFirstBlockNumber)) + int effectiveOffset = + (mBlockCacheStartOffset + + (currentBlock++ - mBlockCacheFirstBlockNumber)) % blocks.length; - if (effectiveOffset < 0 + if (effectiveOffset < 0 || effectiveOffset >= blocks.length) { break; } @@ -1564,15 +1523,15 @@ class GridViewSpecial extends View { private class ImageBlock { Drawable mCellOutline; Bitmap mBitmap = Bitmap.createBitmap(getWidth(), blockHeight(), - Bitmap.Config.RGB_565);; + Bitmap.Config.RGB_565); Canvas mCanvas = new Canvas(mBitmap); Paint mPaint = new Paint(); int mBlockNumber; // columns which have been requested to the loader - int mRequestedMask; - + int mRequestedMask; + // columns which have been completed from the loader int mCompletedMask; boolean mIsVisible; @@ -1819,7 +1778,7 @@ class GridViewSpecial extends View { int row = 0; // i / mCurrentSpec.mColumns; int col = i - (row * mCurrentSpec.mColumns); - // this is duplicated from getOrKick + // this is duplicated from getOrKick // (TODO: don't duplicate this code) int spacing = mCurrentSpec.mCellSpacing; int leftSpacing = mCurrentSpec.mLeftEdgePadding; @@ -1913,6 +1872,7 @@ class GridViewSpecial extends View { mHandler = handler; } + @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); if (false) { @@ -1934,7 +1894,7 @@ class GridViewSpecial extends View { public void computeScroll() { if (mScroller != null) { boolean more = mScroller.computeScrollOffset(); - scrollTo(0, (int) mScroller.getCurrY()); + scrollTo(0, mScroller.getCurrY()); if (more) { postInvalidate(); // So we draw again } else { @@ -1978,7 +1938,7 @@ class GridViewSpecial extends View { if (!mGallery.canHandleEvent()) { return false; } - + mGestureDetector.onTouchEvent(ev); return true; } diff --git a/src/com/android/camera/ImageManager.java b/src/com/android/camera/ImageManager.java index e091d40..378368b 100755 --- a/src/com/android/camera/ImageManager.java +++ b/src/com/android/camera/ImageManager.java @@ -16,6 +16,19 @@ package com.android.camera; +import com.android.camera.gallery.BaseCancelable; +import com.android.camera.gallery.BaseImageList; +import com.android.camera.gallery.CanceledException; +import com.android.camera.gallery.DrmImageList; +import com.android.camera.gallery.ICancelable; +import com.android.camera.gallery.IImage; +import com.android.camera.gallery.IImageList; +import com.android.camera.gallery.Image; +import com.android.camera.gallery.ImageList; +import com.android.camera.gallery.ImageListUber; +import com.android.camera.gallery.SingleImageList; +import com.android.camera.gallery.VideoList; + import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; @@ -25,7 +38,6 @@ import android.graphics.Bitmap; import android.location.Location; import android.net.Uri; import android.os.Environment; -import android.os.Handler; import android.provider.DrmStore; import android.provider.MediaStore; import android.provider.MediaStore.Images; @@ -33,21 +45,6 @@ import android.provider.MediaStore.Images.ImageColumns; import android.util.Config; import android.util.Log; -import com.android.camera.gallery.BaseCancelable; -import com.android.camera.gallery.BaseImageList; -import com.android.camera.gallery.CanceledException; -import com.android.camera.gallery.DrmImageList; -import com.android.camera.gallery.IAddImageCancelable; -import com.android.camera.gallery.IGetBooleanCancelable; -import com.android.camera.gallery.IImage; -import com.android.camera.gallery.IImageList; -import com.android.camera.gallery.Image; -import com.android.camera.gallery.ImageList; -import com.android.camera.gallery.ImageListUber; -import com.android.camera.gallery.SingleImageList; -import com.android.camera.gallery.Util; -import com.android.camera.gallery.VideoList; - import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -237,7 +234,7 @@ public class ImageManager { if (directory != null && filename != null) { String value = directory + "/" + filename; - values.put("_data", value); + values.put(Images.Media.DATA, value); } long t3 = System.currentTimeMillis(); @@ -249,9 +246,10 @@ public class ImageManager { // "DISPLAY_NAME" field. Extract the filename and jam it into the // display name. String projection[] = new String [] { - ImageColumns._ID, Images.Media.DISPLAY_NAME, "_data"}; + ImageColumns._ID, Images.Media.DISPLAY_NAME, Images.Media.DATA}; Cursor c = cr.query(uri, projection, null, null, null); + //TODO: check why we need this if (c.moveToFirst()) { String filePath = c.getString(2); if (filePath != null) { @@ -268,9 +266,8 @@ public class ImageManager { return uri; } - private static class AddImageCancelable extends BaseCancelable - implements IAddImageCancelable { - private IGetBooleanCancelable mSaveImageCancelable; + private static class AddImageCancelable extends BaseCancelable { + private ICancelable mSaveImageCancelable; private Uri mUri; private Context mCtx; private ContentResolver mCr; @@ -280,6 +277,9 @@ public class ImageManager { public AddImageCancelable(Uri uri, Context ctx, ContentResolver cr, int orientation, Bitmap source, byte[] jpegData) { + if (source == null && jpegData == null) { + throw new IllegalArgumentException("source cannot be null"); + } mUri = uri; mCtx = ctx; mCr = cr; @@ -300,11 +300,7 @@ public class ImageManager { return true; } - public void get() { - if (mSource == null && mJpegData == null) { - throw new IllegalArgumentException("source cannot be null"); - } - + public Void get() { try { long t1 = System.currentTimeMillis(); synchronized (this) { @@ -320,7 +316,7 @@ public class ImageManager { long t5 = System.currentTimeMillis(); String[] projection = new String[] { ImageColumns._ID, - ImageColumns.MINI_THUMB_MAGIC, "_data"}; + ImageColumns.MINI_THUMB_MAGIC, ImageColumns.DATA}; Cursor c = mCr.query(mUri, projection, null, null, null); c.moveToPosition(0); @@ -361,10 +357,11 @@ public class ImageManager { } acknowledgeCancel(); } + return null; } } - public IAddImageCancelable storeImage( + public ICancelable storeImage( Uri uri, Context ctx, ContentResolver cr, int orientation, Bitmap source, byte [] jpegData) { return new AddImageCancelable( diff --git a/src/com/android/camera/ImageViewTouchBase.java b/src/com/android/camera/ImageViewTouchBase.java index e184a05..869c65d 100644 --- a/src/com/android/camera/ImageViewTouchBase.java +++ b/src/com/android/camera/ImageViewTouchBase.java @@ -18,33 +18,31 @@ package com.android.camera; import android.content.Context; import android.graphics.Bitmap; -import android.graphics.Canvas; import android.graphics.Matrix; -import android.graphics.Paint; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.SystemClock; import android.util.AttributeSet; -import android.util.Config; -import android.util.Log; import android.view.KeyEvent; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import android.widget.ImageView; abstract class ImageViewTouchBase extends ImageView { + + @SuppressWarnings("unused") private static final String TAG = "ImageViewTouchBase"; - + // This is the base transformation which is used to show the image // initially. The current computation for this shows the image in // it's entirety, letterboxing as needed. One could choose to - // show the image as cropped instead. + // show the image as cropped instead. // // This matrix is recomputed when we go from the thumbnail image to // the full size image. protected Matrix mBaseMatrix = new Matrix(); - // This is the supplementary transformation which reflects what + // This is the supplementary transformation which reflects what // the user has done in terms of zooming and panning. // // This matrix remains the same when we go from the thumbnail image @@ -62,9 +60,9 @@ abstract class ImageViewTouchBase extends ImageView { protected Bitmap mBitmapDisplayed; int mThisWidth = -1, mThisHeight = -1; - + float mMaxZoom; - + // ImageViewTouchBase will pass a Bitmap to the Recycler if it has finished // its use of that Bitmap. public interface Recycler { @@ -106,10 +104,10 @@ abstract class ImageViewTouchBase extends ImageView { } protected Handler mHandler = new Handler(); - + protected int mLastXTouchPos; protected int mLastYTouchPos; - + @Override public void setImageBitmap(Bitmap bitmap) { super.setImageBitmap(bitmap); @@ -163,7 +161,7 @@ abstract class ImageViewTouchBase extends ImageView { } // Center as much as possible in one or both axis. Centering is - // defined as follows: if the image is scaled down below the + // defined as follows: if the image is scaled down below the // view's dimensions then center it (literally). If the image // is scaled larger than the view and is translated out of view // then translate it back into view (i.e. eliminate black bars). @@ -218,7 +216,7 @@ abstract class ImageViewTouchBase extends ImageView { } setImageMatrix(getImageViewMatrix()); } - + public ImageViewTouchBase(Context context) { super(context); init(); @@ -237,7 +235,7 @@ abstract class ImageViewTouchBase extends ImageView { matrix.getValues(mMatrixValues); return mMatrixValues[whichValue]; } - + // Get the scale factor out of the matrix. protected float getScale(Matrix matrix) { return getValue(matrix, Matrix.MSCALE_X); @@ -246,16 +244,16 @@ abstract class ImageViewTouchBase extends ImageView { protected float getScale() { return getScale(mSuppMatrix); } - + // Setup the base matrix so that the image is centered and scaled properly. private void getProperBaseMatrix(Bitmap bitmap, Matrix matrix) { float viewWidth = getWidth(); float viewHeight = getHeight(); matrix.reset(); - float widthScale = Math.min(viewWidth / (float) bitmap.getWidth(), + float widthScale = Math.min(viewWidth / bitmap.getWidth(), 1.0f); - float heightScale = Math.min(viewHeight / (float) bitmap.getHeight(), + float heightScale = Math.min(viewHeight / bitmap.getHeight(), 1.0f); float scale; if (widthScale > heightScale) { @@ -265,10 +263,10 @@ abstract class ImageViewTouchBase extends ImageView { } matrix.setScale(scale, scale); matrix.postTranslate( - (viewWidth - ((float) bitmap.getWidth() * scale)) / 2F, - (viewHeight - ((float) bitmap.getHeight() * scale)) / 2F); + (viewWidth - (bitmap.getWidth() * scale)) / 2F, + (viewHeight - (bitmap.getHeight() * scale)) / 2F); } - + // Combine the base matrix and the supp matrix to make the final matrix. protected Matrix getImageViewMatrix() { // The final matrix is computed as the concatentation of the base matrix @@ -288,7 +286,7 @@ abstract class ImageViewTouchBase extends ImageView { if (mBitmapDisplayed == null) { return 1F; } - + float fw = (float) mBitmapDisplayed.getWidth() / (float) mThisWidth; float fh = (float) mBitmapDisplayed.getHeight() / (float) mThisHeight; float max = Math.max(fw, fh) * 4; @@ -299,7 +297,7 @@ abstract class ImageViewTouchBase extends ImageView { if (scale > mMaxZoom) { scale = mMaxZoom; } - + float oldScale = getScale(); float deltaScale = scale / oldScale; @@ -307,39 +305,38 @@ abstract class ImageViewTouchBase extends ImageView { setImageMatrix(getImageViewMatrix()); center(true, true, false); } - + protected void zoomTo(final float scale, final float centerX, final float centerY, final float durationMs) { final float incrementPerMs = (scale - getScale()) / durationMs; final float oldScale = getScale(); final long startTime = System.currentTimeMillis(); - + mHandler.post(new Runnable() { public void run() { long now = System.currentTimeMillis(); - float currentMs = Math.min(durationMs, - (float) (now - startTime)); + float currentMs = Math.min(durationMs, now - startTime); float target = oldScale + (incrementPerMs * currentMs); zoomTo(target, centerX, centerY); - + if (currentMs < durationMs) { mHandler.post(this); } } - }); + }); } protected void zoomTo(float scale) { float cx = getWidth() / 2F; float cy = getHeight() / 2F; - + zoomTo(scale, cx, cy); } - + protected void zoomIn() { zoomIn(SCALE_RATE); } - + protected void zoomOut() { zoomOut(SCALE_RATE); } @@ -363,7 +360,7 @@ abstract class ImageViewTouchBase extends ImageView { if (mBitmapDisplayed == null) { return; } - + float cx = getWidth() / 2F; float cy = getHeight() / 2F; @@ -379,7 +376,7 @@ abstract class ImageViewTouchBase extends ImageView { setImageMatrix(getImageViewMatrix()); center(true, true, false); } - + protected void postTranslate(float dx, float dy) { mSuppMatrix.postTranslate(dx, dy); } diff --git a/src/com/android/camera/MenuHelper.java b/src/com/android/camera/MenuHelper.java index a9c3c7f..9859ff7 100644 --- a/src/com/android/camera/MenuHelper.java +++ b/src/com/android/camera/MenuHelper.java @@ -30,19 +30,19 @@ import android.os.Handler; import android.os.StatFs; import android.provider.MediaStore; import android.provider.MediaStore.Images; +import android.text.format.Formatter; import android.util.Config; import android.util.Log; import android.view.Menu; import android.view.MenuItem; -import android.view.MenuItem.OnMenuItemClickListener; import android.view.SubMenu; import android.view.View; +import android.view.MenuItem.OnMenuItemClickListener; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import java.io.Closeable; -import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; @@ -132,7 +132,7 @@ public class MenuHelper { uri.getScheme().equals("content") && uri.getAuthority().equals("mms"); } - + public static void enableShareMenuItem(Menu menu, boolean enabled) { MenuItem item = menu.findItem(MENU_IMAGE_SHARE); if (item != null) { @@ -167,9 +167,9 @@ public class MenuHelper { textView.setText(image.getDisplayName()); long length = getImageFileSize(image); - String lengthString = lengthString = length < 0 ? "" - : android.text.format.Formatter.formatFileSize( - activity, length); + String lengthString = length < 0 + ? "" + : Formatter.formatFileSize(activity, length); ((TextView) d .findViewById(R.id.details_file_size_value)) .setText(lengthString); @@ -257,7 +257,7 @@ public class MenuHelper { bps = String.format( activity.getString( R.string.details_mbps), - ((double) bitRate) / 1000000.0); + (bitRate) / 1000000.0); } ((TextView) d.findViewById( R.id.details_bit_rate_value)) diff --git a/src/com/android/camera/MovieView.java b/src/com/android/camera/MovieView.java index f318d91..956e3b9 100644 --- a/src/com/android/camera/MovieView.java +++ b/src/com/android/camera/MovieView.java @@ -21,9 +21,9 @@ import android.app.Activity; import android.app.AlertDialog; import android.content.ContentValues; import android.content.DialogInterface; +import android.content.Intent; import android.content.DialogInterface.OnCancelListener; import android.content.DialogInterface.OnClickListener; -import android.content.Intent; import android.content.pm.ActivityInfo; import android.database.Cursor; import android.database.sqlite.SQLiteException; @@ -42,6 +42,7 @@ import android.widget.VideoView; */ public class MovieView extends Activity implements MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener { + @SuppressWarnings("unused") private static final String TAG = "MovieView"; // Copied from MediaPlaybackService in the Music Player app. Should be @@ -138,12 +139,12 @@ public class MovieView extends Activity implements MediaPlayer.OnErrorListener, return ("content".equalsIgnoreCase(scheme) && MediaStore.AUTHORITY.equalsIgnoreCase(authority)); } - + private Integer getBookmark() { if (!uriSupportsBookmarks(mUri)) { return null; } - + String[] projection = new String[] { Video.VideoColumns.DURATION, Video.VideoColumns.BOOKMARK @@ -194,7 +195,7 @@ public class MovieView extends Activity implements MediaPlayer.OnErrorListener, if (!uriSupportsBookmarks(mUri)) { return; } - + ContentValues values = new ContentValues(); values.put(Video.VideoColumns.BOOKMARK, Integer.toString(bookmark)); try { diff --git a/src/com/android/camera/PhotoAppWidgetConfigure.java b/src/com/android/camera/PhotoAppWidgetConfigure.java index 626dfe0..6f05ac3 100644 --- a/src/com/android/camera/PhotoAppWidgetConfigure.java +++ b/src/com/android/camera/PhotoAppWidgetConfigure.java @@ -26,18 +26,20 @@ import android.os.Bundle; import android.widget.RemoteViews; class PhotoAppWidgetConfigure extends Activity { + + @SuppressWarnings("unused") private static final String TAG = "PhotoAppWidgetConfigure"; static final int REQUEST_GET_PHOTO = 2; - + int mAppWidgetId = -1; @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); - + // Someone is requesting that we configure the given mAppWidgetId, which // means we prompt the user to pick and crop a photo. - + mAppWidgetId = getIntent().getIntExtra( AppWidgetManager.EXTRA_APPWIDGET_ID, -1); if (mAppWidgetId == -1) { @@ -56,17 +58,17 @@ class PhotoAppWidgetConfigure extends Activity { intent.putExtra("outputY", 192); intent.putExtra("noFaceDetection", true); intent.putExtra("return-data", true); - + startActivityForResult(intent, REQUEST_GET_PHOTO); } - + @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK && mAppWidgetId != -1) { // Store the cropped photo in our database Bitmap bitmap = (Bitmap) data.getParcelableExtra("data"); - + PhotoDatabaseHelper helper = new PhotoDatabaseHelper(this); if (helper.setPhoto(mAppWidgetId, bitmap)) { resultCode = Activity.RESULT_OK; @@ -83,12 +85,12 @@ class PhotoAppWidgetConfigure extends Activity { } else { resultCode = Activity.RESULT_CANCELED; } - + // Make sure we pass back the original mAppWidgetId Intent resultValue = new Intent(); resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); setResult(resultCode, resultValue); finish(); } - + } diff --git a/src/com/android/camera/PhotoAppWidgetProvider.java b/src/com/android/camera/PhotoAppWidgetProvider.java index 3db5b12..5fb7401 100644 --- a/src/com/android/camera/PhotoAppWidgetProvider.java +++ b/src/com/android/camera/PhotoAppWidgetProvider.java @@ -39,7 +39,7 @@ import java.io.IOException; public class PhotoAppWidgetProvider extends AppWidgetProvider { static final String TAG = "PhotoAppWidgetProvider"; static final boolean LOGD = Config.LOGD || true; - + @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { @@ -56,7 +56,7 @@ public class PhotoAppWidgetProvider extends AppWidgetProvider { } helper.close(); } - + @Override public void onDeleted(Context context, int[] appWidgetIds) { // Clean deleted photos out of our database @@ -83,10 +83,8 @@ public class PhotoAppWidgetProvider extends AppWidgetProvider { } static class PhotoDatabaseHelper extends SQLiteOpenHelper { - private final Context mContext; - private static final String DATABASE_NAME = "launcher.db"; - + private static final int DATABASE_VERSION = 2; static final String TABLE_PHOTOS = "photos"; @@ -95,7 +93,6 @@ public class PhotoAppWidgetProvider extends AppWidgetProvider { PhotoDatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); - mContext = context; } @Override @@ -110,14 +107,14 @@ public class PhotoAppWidgetProvider extends AppWidgetProvider { public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { int version = oldVersion; - + if (version != DATABASE_VERSION) { Log.w(TAG, "Destroying all old data."); db.execSQL("DROP TABLE IF EXISTS " + TABLE_PHOTOS); onCreate(db); } } - + /** * Store the given bitmap in this database for the given appWidgetId. */ @@ -137,11 +134,11 @@ public class PhotoAppWidgetProvider extends AppWidgetProvider { values.put(PhotoDatabaseHelper.FIELD_APPWIDGET_ID, appWidgetId); values.put(PhotoDatabaseHelper.FIELD_PHOTO_BLOB, out.toByteArray()); - + SQLiteDatabase db = getWritableDatabase(); db.insertOrThrow(PhotoDatabaseHelper.TABLE_PHOTOS, null, values); - + success = true; } catch (SQLiteException e) { Log.e(TAG, "Could not open database", e); @@ -153,13 +150,13 @@ public class PhotoAppWidgetProvider extends AppWidgetProvider { } return success; } - + static final String[] PHOTOS_PROJECTION = { FIELD_PHOTO_BLOB, }; - + static final int INDEX_PHOTO_BLOB = 0; - + /** * Inflate and return a bitmap for the given appWidgetId. */ @@ -172,7 +169,7 @@ public class PhotoAppWidgetProvider extends AppWidgetProvider { appWidgetId); c = db.query(TABLE_PHOTOS, PHOTOS_PROJECTION, selection, null, null, null, null, null); - + if (c != null && LOGD) { Log.d(TAG, "getPhoto query count=" + c.getCount()); } @@ -193,7 +190,7 @@ public class PhotoAppWidgetProvider extends AppWidgetProvider { } return bitmap; } - + /** * Remove any bitmap associated with the given appWidgetId. */ @@ -208,6 +205,6 @@ public class PhotoAppWidgetProvider extends AppWidgetProvider { } } } - + } diff --git a/src/com/android/camera/ThumbnailController.java b/src/com/android/camera/ThumbnailController.java index b8ad7f3..1147d37 100644 --- a/src/com/android/camera/ThumbnailController.java +++ b/src/com/android/camera/ThumbnailController.java @@ -16,7 +16,6 @@ package com.android.camera; -import com.android.camera.gallery.Util; import android.content.ContentResolver; import android.graphics.Bitmap; @@ -34,7 +33,6 @@ import android.widget.ImageView; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; -import java.io.Closeable; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; @@ -55,6 +53,8 @@ import java.io.IOException; * */ public class ThumbnailController { + + @SuppressWarnings("unused") private static final String TAG = "ThumbnailController"; private ContentResolver mContentResolver; private Uri mUri; diff --git a/src/com/android/camera/Util.java b/src/com/android/camera/Util.java new file mode 100644 index 0000000..c081d02 --- /dev/null +++ b/src/com/android/camera/Util.java @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2009 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; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Matrix; +import android.media.MediaMetadataRetriever; +import android.os.ParcelFileDescriptor; +import android.util.Log; + + +import java.io.ByteArrayOutputStream; +import java.io.Closeable; + +/** + * Collection of utility functions used in this package. + */ +public class Util { + private static final boolean VERBOSE = false; + private static final String TAG = "db.Util"; + + private Util() { + } + + // Rotates the bitmap by the specified degree. + // If a new bitmap is created, the original bitmap is recycled. + public static Bitmap rotate(Bitmap b, int degrees) { + if (degrees != 0 && b != null) { + Matrix m = new Matrix(); + m.setRotate(degrees, + (float) b.getWidth() / 2, (float) b.getHeight() / 2); + try { + Bitmap b2 = Bitmap.createBitmap( + b, 0, 0, b.getWidth(), b.getHeight(), m, true); + if (b != b2) { + b.recycle(); + b = b2; + } + } catch (OutOfMemoryError ex) { + // We have no memory to rotate. Return the original bitmap. + } + } + return b; + } + + /* + * Compute the sample size as a function of the image size and the target. + * Scale the image down so that both the width and height are just above the + * target. If this means that one of the dimension goes from above the + * target to below the target (e.g. given a width of 480 and an image width + * of 600 but sample size of 2 -- i.e. new width 300 -- bump the sample size + * down by 1. + */ + public static int computeSampleSize( + BitmapFactory.Options options, int target) { + int w = options.outWidth; + int h = options.outHeight; + + int candidateW = w / target; + int candidateH = h / target; + int candidate = Math.max(candidateW, candidateH); + + if (candidate == 0) return 1; + + if (candidate > 1) { + if ((w > target) && (w / candidate) < target) candidate -= 1; + } + + if (candidate > 1) { + if ((h > target) && (h / candidate) < target) candidate -= 1; + } + + if (VERBOSE) { + Log.v(TAG, "for w/h " + w + "/" + h + " returning " + candidate + + "(" + (w / candidate) + " / " + (h / candidate)); + } + + return candidate; + } + + /** + * Creates a centered bitmap of the desired size. Recycles the input. + * @param source + */ + public static Bitmap extractMiniThumb( + Bitmap source, int width, int height) { + return Util.extractMiniThumb(source, width, height, true); + } + + public static Bitmap extractMiniThumb( + Bitmap source, int width, int height, boolean recycle) { + if (source == null) { + return null; + } + + float scale; + if (source.getWidth() < source.getHeight()) { + scale = width / (float) source.getWidth(); + } else { + scale = height / (float) source.getHeight(); + } + Matrix matrix = new Matrix(); + matrix.setScale(scale, scale); + Bitmap miniThumbnail = ImageLoader.transform(matrix, source, + width, height, false); + + if (recycle && miniThumbnail != source) { + source.recycle(); + } + return miniThumbnail; + } + + /** + * Creates a byte[] for a given bitmap of the desired size. Recycles the + * input bitmap. + */ + public static byte[] miniThumbData(Bitmap source) { + if (source == null) return null; + + Bitmap miniThumbnail = extractMiniThumb( + source, ImageManager.MINI_THUMB_TARGET_SIZE, + ImageManager.MINI_THUMB_TARGET_SIZE); + + ByteArrayOutputStream miniOutStream = new ByteArrayOutputStream(); + miniThumbnail.compress(Bitmap.CompressFormat.JPEG, 75, miniOutStream); + miniThumbnail.recycle(); + + try { + miniOutStream.close(); + byte [] data = miniOutStream.toByteArray(); + return data; + } catch (java.io.IOException ex) { + Log.e(TAG, "got exception ex " + ex); + } + return null; + } + + /** + * @return true if the mimetype is a video mimetype. + */ + public static boolean isVideoMimeType(String mimeType) { + return mimeType.startsWith("video/"); + } + + /** + * Create a video thumbnail for a video. May return null if the video is + * corrupt. + * + * @param filePath + */ + public static Bitmap createVideoThumbnail(String filePath) { + Bitmap bitmap = null; + MediaMetadataRetriever retriever = new MediaMetadataRetriever(); + try { + retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY); + retriever.setDataSource(filePath); + bitmap = retriever.captureFrame(); + } catch (IllegalArgumentException ex) { + // Assume this is a corrupt video file + } catch (RuntimeException ex) { + // Assume this is a corrupt video file. + } finally { + try { + retriever.release(); + } catch (RuntimeException ex) { + // Ignore failures while cleaning up. + } + } + return bitmap; + } + + public static int indexOf(String [] array, String s) { + for (int i = 0; i < array.length; i++) { + if (array[i].equals(s)) { + return i; + } + } + return -1; + } + + public static void closeSiliently(Closeable c) { + if (c == null) return; + try { + c.close(); + } catch (Throwable t) { + // do nothing + } + } + + public static void closeSiliently(ParcelFileDescriptor c) { + if (c == null) return; + try { + c.close(); + } catch (Throwable t) { + // do nothing + } + } + +} diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java index 14cdccc..b18c94c 100644 --- a/src/com/android/camera/VideoCamera.java +++ b/src/com/android/camera/VideoCamera.java @@ -18,7 +18,6 @@ package com.android.camera; import com.android.camera.gallery.IImage; import com.android.camera.gallery.IImageList; -import com.android.camera.gallery.Util; import android.app.Activity; import android.content.BroadcastReceiver; @@ -48,11 +47,11 @@ import android.util.Log; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; -import android.view.MenuItem.OnMenuItemClickListener; import android.view.SurfaceHolder; import android.view.View; import android.view.Window; import android.view.WindowManager; +import android.view.MenuItem.OnMenuItemClickListener; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.widget.ImageView; @@ -168,7 +167,7 @@ public class VideoCamera extends Activity implements View.OnClickListener, break; } } - }; + } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override diff --git a/src/com/android/camera/VideoPreview.java b/src/com/android/camera/VideoPreview.java index fdcf9ad..cd29e6f 100644 --- a/src/com/android/camera/VideoPreview.java +++ b/src/com/android/camera/VideoPreview.java @@ -20,7 +20,6 @@ import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.SurfaceView; -import android.view.View.MeasureSpec; class VideoPreview extends SurfaceView { private float mAspectRatio; diff --git a/src/com/android/camera/ViewImage.java b/src/com/android/camera/ViewImage.java index f51d8ce..e3e98cb 100644 --- a/src/com/android/camera/ViewImage.java +++ b/src/com/android/camera/ViewImage.java @@ -16,7 +16,7 @@ package com.android.camera; -import com.android.camera.gallery.IGetBitmapCancelable; +import com.android.camera.gallery.ICancelable; import com.android.camera.gallery.IImage; import com.android.camera.gallery.IImageList; @@ -324,6 +324,7 @@ public class ViewImage extends Activity implements View.OnClickListener { public void run(final MenuHelper.MenuCallback cb) { setMode(MODE_NORMAL); Thread t = new Thread() { + @Override public void run() { cb.run(selectedImageGetter.getCurrentImageUri(), selectedImageGetter.getCurrentImage()); @@ -406,17 +407,6 @@ public class ViewImage extends Activity implements View.OnClickListener { return true; } - private void onLayoutChanged() { - // if we get here after "onPause" then ignore the event - if (mGetter == null) { - return; - } - mDismissOnScreenControlsRunnable.run(); - mGetter.cancelCurrent(); - mImageView.clear(); - setImage(mCurrentPosition); - } - @Override public boolean onMenuItemSelected(int featureId, MenuItem item) { boolean b = super.onMenuItemSelected(featureId, item); @@ -435,7 +425,7 @@ public class ViewImage extends Activity implements View.OnClickListener { mImageView.setImageBitmapResetBase(b, true); updateZoomButtonsEnabled(); } - + ImageGetterCallback cb = new ImageGetterCallback() { public void completed(boolean wasCanceled) { if (!mShowActionIcons) { @@ -515,7 +505,7 @@ public class ViewImage extends Activity implements View.OnClickListener { mCache = new BitmapCache(3); mImageView.setRecycler(mCache); - + BitmapManager bitmapManager = BitmapManager.instance(); bitmapManager.setCheckResourceLock(false); bitmapManager.allowAllDecoding(); @@ -914,7 +904,7 @@ public class ViewImage extends Activity implements View.OnClickListener { @Override public void onResume() { super.onResume(); - + BitmapManager.instance().allowAllDecoding(false); init(mSavedUri); @@ -1244,6 +1234,8 @@ interface ImageGetterCallback { } class ImageGetter { + + @SuppressWarnings("unused") private static final String TAG = "ImageGetter"; // The thread which does the work. @@ -1258,7 +1250,7 @@ class ImageGetter { // This is the loader cancelable that gets set while we're loading an image. // If we change position we can cancel the current load using this. - private IGetBitmapCancelable mLoad; + private ICancelable mLoad; // True if we're canceling the current load. private boolean mCancelCurrent = false; @@ -1276,7 +1268,7 @@ class ImageGetter { synchronized (this) { if (!mReady) { mCancelCurrent = true; - IGetBitmapCancelable load = mLoad; + ICancelable load = mLoad; if (load != null) { load.cancel(); } @@ -1290,7 +1282,7 @@ class ImageGetter { final boolean isThumb, final Bitmap bitmap) { return new Runnable() { public void run() { - // check for inflight callbacks that aren't applicable + // check for inflight callbacks that aren't applicable // any longer before delivering them if (!isCanceled() && position == mCurrentPosition) { mCB.imageLoaded(position, offset, bitmap, isThumb); @@ -1316,7 +1308,7 @@ class ImageGetter { mReady = true; ImageGetter.this.notify(); - if (mCurrentPosition == -1 + if (mCurrentPosition == -1 || lastPosition == mCurrentPosition) { try { ImageGetter.this.wait(); @@ -1345,7 +1337,7 @@ class ImageGetter { if (mCB.wantsThumbnail(lastPosition, offset)) { Bitmap b = image.thumbBitmap(); mViewImage.mHandler.postGetterCallback( - callback(lastPosition, offset, + callback(lastPosition, offset, true, b)); } } @@ -1374,7 +1366,7 @@ class ImageGetter { b.recycle(); } else { Runnable cb = callback( - lastPosition, offset, + lastPosition, offset, false, b); mViewImage.mHandler .postGetterCallback(cb); @@ -1461,7 +1453,7 @@ class BitmapCache implements ImageViewTouchBase.Recycler { } private Entry[] mCache; - + public BitmapCache(int size) { mCache = new Entry[size]; for (int i = 0; i < mCache.length; i++) { @@ -1479,7 +1471,7 @@ class BitmapCache implements ImageViewTouchBase.Recycler { } return null; } - + // Returns the thumb bitmap if we have it, otherwise return null. public synchronized Bitmap getBitmap(int pos) { Entry e = findEntry(pos); @@ -1513,7 +1505,7 @@ class BitmapCache implements ImageViewTouchBase.Recycler { } } } - + // Recycle the image being kicked out. // This only works because our current usage is sequential, so we // do not happen to recycle the image being displayed. @@ -1524,7 +1516,7 @@ class BitmapCache implements ImageViewTouchBase.Recycler { best.mPos = pos; best.mBitmap = bitmap; } - + // Recycle all bitmaps in the cache and clear the cache. public synchronized void clear() { for (Entry e : mCache) { @@ -1540,7 +1532,7 @@ class BitmapCache implements ImageViewTouchBase.Recycler { Entry e = findEntry(pos); return (e != null); } - + // Recycle the bitmap if it's not in the cache. // The input must be non-null. public synchronized void recycle(Bitmap b) { diff --git a/src/com/android/camera/Wallpaper.java b/src/com/android/camera/Wallpaper.java index cf29064..27c6779 100644 --- a/src/com/android/camera/Wallpaper.java +++ b/src/com/android/camera/Wallpaper.java @@ -206,8 +206,6 @@ public class Wallpaper extends Activity { } mDoLaunch = false; } catch (FileNotFoundException ex) { - // ignore - } catch (IOException ex) { // ignore } } else { diff --git a/src/com/android/camera/gallery/BaseCancelable.java b/src/com/android/camera/gallery/BaseCancelable.java index dbc46cc..de23521 100644 --- a/src/com/android/camera/gallery/BaseCancelable.java +++ b/src/com/android/camera/gallery/BaseCancelable.java @@ -20,7 +20,7 @@ package com.android.camera.gallery; /** * A base class for the interface ICancelable. */ -public abstract class BaseCancelable implements ICancelable { +public abstract class BaseCancelable implements ICancelable { protected boolean mCancel = false; protected boolean mFinished = false; diff --git a/src/com/android/camera/gallery/BaseImage.java b/src/com/android/camera/gallery/BaseImage.java index f11cc26..8b521d9 100644 --- a/src/com/android/camera/gallery/BaseImage.java +++ b/src/com/android/camera/gallery/BaseImage.java @@ -17,6 +17,7 @@ package com.android.camera.gallery; import com.android.camera.BitmapManager; +import com.android.camera.Util; import android.content.ContentResolver; import android.database.Cursor; @@ -27,7 +28,6 @@ import android.os.ParcelFileDescriptor; import android.provider.MediaStore.Images; import android.util.Log; - import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -74,8 +74,7 @@ public abstract class BaseImage implements IImage { } } - private class CompressImageToFile extends BaseCancelable - implements IGetBooleanCancelable { + private class CompressImageToFile extends BaseCancelable { private ThreadSafeOutputStream mOutputStream = null; private Bitmap mBitmap; @@ -97,7 +96,7 @@ public abstract class BaseImage implements IImage { return false; } - public boolean get() { + public Boolean get() { try { long t1 = System.currentTimeMillis(); OutputStream delegate = mContentResolver.openOutputStream(mUri); @@ -145,7 +144,7 @@ public abstract class BaseImage implements IImage { * @param uri where to store the bitmap * @return true if we succeeded */ - protected IGetBooleanCancelable compressImageToFile( + protected ICancelable compressImageToFile( Bitmap bitmap, byte [] jpegData, Uri uri) { return new CompressImageToFile(bitmap, jpegData, uri); } @@ -178,8 +177,7 @@ public abstract class BaseImage implements IImage { return b; } - private class LoadBitmapCancelable extends BaseCancelable - implements IGetBitmapCancelable { + private class LoadBitmapCancelable extends BaseCancelable { private ParcelFileDescriptor mPFD; private BitmapFactory.Options mOptions = new BitmapFactory.Options(); private long mCancelInitiationTime; @@ -224,7 +222,7 @@ public abstract class BaseImage implements IImage { } - public IGetBitmapCancelable fullSizeBitmapCancelable( + public ICancelable fullSizeBitmapCancelable( int targetWidthHeight) { try { ParcelFileDescriptor pfdInput = mContentResolver diff --git a/src/com/android/camera/gallery/BaseImageList.java b/src/com/android/camera/gallery/BaseImageList.java index 49b43d3..18eef1d 100644 --- a/src/com/android/camera/gallery/BaseImageList.java +++ b/src/com/android/camera/gallery/BaseImageList.java @@ -17,6 +17,9 @@ package com.android.camera.gallery; import com.android.camera.BitmapManager; +import com.android.camera.ExifInterface; +import com.android.camera.ImageManager; +import com.android.camera.Util; import android.content.ContentResolver; import android.content.ContentUris; @@ -34,9 +37,6 @@ import android.provider.MediaStore.Images.Thumbnails; import android.provider.MediaStore.MediaColumns; import android.util.Log; -import com.android.camera.ExifInterface; -import com.android.camera.ImageManager; - import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; @@ -284,7 +284,7 @@ public abstract class BaseImageList implements IImageList { if (BitmapManager.instance().acquireResourceLock() == false) { return -1; } - + try { if (existingImage == null) { // if we don't have an Image object then get the id and magic diff --git a/src/com/android/camera/gallery/IAddImageCancelable.java b/src/com/android/camera/gallery/IAddImageCancelable.java deleted file mode 100644 index 30a6880..0000000 --- a/src/com/android/camera/gallery/IAddImageCancelable.java +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2009 Google Inc. All Rights Reserved. - -package com.android.camera.gallery; - -/** - * Cancelable interface for add image task. - */ -public interface IAddImageCancelable extends ICancelable { - public void get(); -} \ No newline at end of file diff --git a/src/com/android/camera/gallery/ICancelable.java b/src/com/android/camera/gallery/ICancelable.java index ca02e79..9c9e1bf 100644 --- a/src/com/android/camera/gallery/ICancelable.java +++ b/src/com/android/camera/gallery/ICancelable.java @@ -19,7 +19,7 @@ package com.android.camera.gallery; /** * The interface for all the tasks that could be canceled. */ -public interface ICancelable { +public interface ICancelable { /* * call cancel() when the unit of work in progress needs to be * canceled. This should return true if it was possible to @@ -27,4 +27,6 @@ public interface ICancelable { * may still be able to cleanup and simulate cancelation. */ public boolean cancel(); + + public T get(); } \ No newline at end of file diff --git a/src/com/android/camera/gallery/IGetBitmapCancelable.java b/src/com/android/camera/gallery/IGetBitmapCancelable.java deleted file mode 100644 index 32f8b91..0000000 --- a/src/com/android/camera/gallery/IGetBitmapCancelable.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2009 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.gallery; - -import android.graphics.Bitmap; - -/** - * An ICancelable interface which will return a bitmap. - */ -public interface IGetBitmapCancelable extends ICancelable { - // returns the bitmap or null if there was an error or we were canceled - public Bitmap get(); -} \ No newline at end of file diff --git a/src/com/android/camera/gallery/IGetBooleanCancelable.java b/src/com/android/camera/gallery/IGetBooleanCancelable.java deleted file mode 100644 index c85f223..0000000 --- a/src/com/android/camera/gallery/IGetBooleanCancelable.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2009 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.gallery; - -/** - * An ICancelable interface which will return a boolean value. - */ -public interface IGetBooleanCancelable extends ICancelable { - public boolean get(); -} \ No newline at end of file diff --git a/src/com/android/camera/gallery/IImage.java b/src/com/android/camera/gallery/IImage.java index c91fb7f..aee46f0 100644 --- a/src/com/android/camera/gallery/IImage.java +++ b/src/com/android/camera/gallery/IImage.java @@ -38,7 +38,7 @@ public interface IImage { * * @return an object which can be canceled while the bitmap is loading */ - public abstract IGetBitmapCancelable fullSizeBitmapCancelable( + public abstract ICancelable fullSizeBitmapCancelable( int targetWidthOrHeight); /** diff --git a/src/com/android/camera/gallery/Image.java b/src/com/android/camera/gallery/Image.java index c1a0a13..2ec100a 100644 --- a/src/com/android/camera/gallery/Image.java +++ b/src/com/android/camera/gallery/Image.java @@ -17,6 +17,9 @@ package com.android.camera.gallery; import com.android.camera.BitmapManager; +import com.android.camera.ExifInterface; +import com.android.camera.ImageManager; +import com.android.camera.Util; import android.content.ContentResolver; import android.content.ContentUris; @@ -28,9 +31,6 @@ import android.os.ParcelFileDescriptor; import android.provider.MediaStore.Images.Thumbnails; import android.util.Log; -import com.android.camera.ExifInterface; -import com.android.camera.ImageManager; - import java.io.FileNotFoundException; import java.io.IOException; import java.util.HashMap; @@ -165,13 +165,12 @@ public class Image extends BaseImage implements IImage { mExifData.put(tag, value); } - private class SaveImageContentsCancelable extends BaseCancelable - implements IGetBooleanCancelable { + private class SaveImageContentsCancelable extends BaseCancelable { private Bitmap mImage; private byte [] mJpegData; private int mOrientation; private Cursor mCursor; - IGetBooleanCancelable mCurrentCancelable = null; + ICancelable mCurrentCancelable = null; SaveImageContentsCancelable(Bitmap image, byte[] jpegData, int orientation, Cursor cursor) { @@ -189,7 +188,7 @@ public class Image extends BaseImage implements IImage { return true; } - public boolean get() { + public Boolean get() { try { Bitmap thumbnail = null; @@ -198,7 +197,7 @@ public class Image extends BaseImage implements IImage { synchronized (this) { checkCanceled(); mCurrentCancelable = - compressImageToFile(mImage, mJpegData, uri); + compressImageToFile(mImage, mJpegData, uri); } long t2 = System.currentTimeMillis(); @@ -277,7 +276,7 @@ public class Image extends BaseImage implements IImage { } } - public IGetBooleanCancelable saveImageContents(Bitmap image, + public ICancelable saveImageContents(Bitmap image, byte [] jpegData, int orientation, boolean newFile, Cursor cursor) { return new SaveImageContentsCancelable( image, jpegData, orientation, cursor); @@ -385,7 +384,7 @@ public class Image extends BaseImage implements IImage { private Bitmap decodeCurrentImage(Cursor c) { Uri thumbUri = ContentUris.withAppendedId( mContainer.mThumbUri, - c.getLong(((ImageList) mContainer).INDEX_THUMB_ID)); + c.getLong(ImageList.INDEX_THUMB_ID)); ParcelFileDescriptor pfdInput; Bitmap bitmap = null; try { diff --git a/src/com/android/camera/gallery/ImageList.java b/src/com/android/camera/gallery/ImageList.java index 2f638b5..75ed900 100644 --- a/src/com/android/camera/gallery/ImageList.java +++ b/src/com/android/camera/gallery/ImageList.java @@ -18,6 +18,7 @@ package com.android.camera.gallery; import com.android.camera.BitmapManager; import com.android.camera.ImageManager; +import com.android.camera.Util; import android.content.ContentResolver; import android.content.Context; diff --git a/src/com/android/camera/gallery/ImageListUber.java b/src/com/android/camera/gallery/ImageListUber.java index 0f24aef..2f97b9f 100644 --- a/src/com/android/camera/gallery/ImageListUber.java +++ b/src/com/android/camera/gallery/ImageListUber.java @@ -19,7 +19,6 @@ package com.android.camera.gallery; import com.android.camera.ImageManager; import android.net.Uri; -import android.os.Handler; import android.util.Log; import java.util.ArrayList; diff --git a/src/com/android/camera/gallery/MiniThumbFile.java b/src/com/android/camera/gallery/MiniThumbFile.java index e2c825c..692dacf 100644 --- a/src/com/android/camera/gallery/MiniThumbFile.java +++ b/src/com/android/camera/gallery/MiniThumbFile.java @@ -16,8 +16,10 @@ package com.android.camera.gallery; +import com.android.camera.Util; + import android.graphics.Bitmap; -import android.net.Uri; +import android.net.Uri; import android.os.Environment; import android.util.Log; @@ -40,10 +42,9 @@ class MiniThumbFile { private static final int MINI_THUMB_DATA_FILE_VERSION = 3; public static final int BYTES_PER_MINTHUMB = 10000; private static final int HEADER_SIZE = 1 + 8 + 4; - private static final byte [] sMiniThumbData = new byte[BYTES_PER_MINTHUMB]; private Uri mUri; - private RandomAccessFile mMiniThumbFile; - + private RandomAccessFile mMiniThumbFile; + private String randomAccessFilePath(int version) { String directoryName = Environment.getExternalStorageDirectory().toString() diff --git a/src/com/android/camera/gallery/SingleImageList.java b/src/com/android/camera/gallery/SingleImageList.java index 6fe7241..099a01f 100644 --- a/src/com/android/camera/gallery/SingleImageList.java +++ b/src/com/android/camera/gallery/SingleImageList.java @@ -17,6 +17,8 @@ package com.android.camera.gallery; import com.android.camera.BitmapManager; +import com.android.camera.ImageManager; +import com.android.camera.Util; import android.content.ContentResolver; import android.graphics.Bitmap; @@ -26,8 +28,6 @@ import android.net.Uri; import android.os.ParcelFileDescriptor; import android.util.Log; -import com.android.camera.ImageManager; - import java.io.File; import java.io.FileNotFoundException; import java.io.InputStream; @@ -113,8 +113,7 @@ public class SingleImageList extends BaseImageList implements IImageList { } } - final class LoadBitmapCancelable extends BaseCancelable - implements IGetBitmapCancelable { + final class LoadBitmapCancelable extends BaseCancelable { ParcelFileDescriptor mPfdInput; BitmapFactory.Options mOptions = new BitmapFactory.Options(); long mCancelInitiationTime; @@ -157,7 +156,7 @@ public class SingleImageList extends BaseImageList implements IImageList { } } - public IGetBitmapCancelable fullSizeBitmapCancelable( + public ICancelable fullSizeBitmapCancelable( int targetWidthOrHeight) { try { ParcelFileDescriptor pfdInput = getPFD(); diff --git a/src/com/android/camera/gallery/Util.java b/src/com/android/camera/gallery/Util.java deleted file mode 100644 index 04998ef..0000000 --- a/src/com/android/camera/gallery/Util.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2009 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.gallery; - -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Matrix; -import android.media.MediaMetadataRetriever; -import android.os.ParcelFileDescriptor; -import android.util.Log; - -import com.android.camera.ImageLoader; -import com.android.camera.ImageManager; - -import java.io.ByteArrayOutputStream; -import java.io.Closeable; - -/** - * Collection of utility functions used in this package. - */ -public class Util { - private static final boolean VERBOSE = false; - private static final String TAG = "db.Util"; - - private Util() { - } - - // Rotates the bitmap by the specified degree. - // If a new bitmap is created, the original bitmap is recycled. - public static Bitmap rotate(Bitmap b, int degrees) { - if (degrees != 0 && b != null) { - Matrix m = new Matrix(); - m.setRotate(degrees, - (float) b.getWidth() / 2, (float) b.getHeight() / 2); - try { - Bitmap b2 = Bitmap.createBitmap( - b, 0, 0, b.getWidth(), b.getHeight(), m, true); - if (b != b2) { - b.recycle(); - b = b2; - } - } catch (OutOfMemoryError ex) { - // We have no memory to rotate. Return the original bitmap. - } - } - return b; - } - - /* - * Compute the sample size as a function of the image size and the target. - * Scale the image down so that both the width and height are just above the - * target. If this means that one of the dimension goes from above the - * target to below the target (e.g. given a width of 480 and an image width - * of 600 but sample size of 2 -- i.e. new width 300 -- bump the sample size - * down by 1. - */ - public static int computeSampleSize( - BitmapFactory.Options options, int target) { - int w = options.outWidth; - int h = options.outHeight; - - int candidateW = w / target; - int candidateH = h / target; - int candidate = Math.max(candidateW, candidateH); - - if (candidate == 0) return 1; - - if (candidate > 1) { - if ((w > target) && (w / candidate) < target) candidate -= 1; - } - - if (candidate > 1) { - if ((h > target) && (h / candidate) < target) candidate -= 1; - } - - if (VERBOSE) { - Log.v(TAG, "for w/h " + w + "/" + h + " returning " + candidate - + "(" + (w / candidate) + " / " + (h / candidate)); - } - - return candidate; - } - - /** - * Creates a centered bitmap of the desired size. Recycles the input. - * @param source - */ - public static Bitmap extractMiniThumb( - Bitmap source, int width, int height) { - return Util.extractMiniThumb(source, width, height, true); - } - - public static Bitmap extractMiniThumb( - Bitmap source, int width, int height, boolean recycle) { - if (source == null) { - return null; - } - - float scale; - if (source.getWidth() < source.getHeight()) { - scale = width / (float) source.getWidth(); - } else { - scale = height / (float) source.getHeight(); - } - Matrix matrix = new Matrix(); - matrix.setScale(scale, scale); - Bitmap miniThumbnail = ImageLoader.transform(matrix, source, - width, height, false); - - if (recycle && miniThumbnail != source) { - source.recycle(); - } - return miniThumbnail; - } - - /** - * Creates a byte[] for a given bitmap of the desired size. Recycles the - * input bitmap. - */ - public static byte[] miniThumbData(Bitmap source) { - if (source == null) return null; - - Bitmap miniThumbnail = extractMiniThumb( - source, ImageManager.MINI_THUMB_TARGET_SIZE, - ImageManager.MINI_THUMB_TARGET_SIZE); - - ByteArrayOutputStream miniOutStream = new ByteArrayOutputStream(); - miniThumbnail.compress(Bitmap.CompressFormat.JPEG, 75, miniOutStream); - miniThumbnail.recycle(); - - try { - miniOutStream.close(); - byte [] data = miniOutStream.toByteArray(); - return data; - } catch (java.io.IOException ex) { - Log.e(TAG, "got exception ex " + ex); - } - return null; - } - - /** - * @return true if the mimetype is a video mimetype. - */ - public static boolean isVideoMimeType(String mimeType) { - return mimeType.startsWith("video/"); - } - - /** - * Create a video thumbnail for a video. May return null if the video is - * corrupt. - * - * @param filePath - */ - public static Bitmap createVideoThumbnail(String filePath) { - Bitmap bitmap = null; - MediaMetadataRetriever retriever = new MediaMetadataRetriever(); - try { - retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY); - retriever.setDataSource(filePath); - bitmap = retriever.captureFrame(); - } catch (IllegalArgumentException ex) { - // Assume this is a corrupt video file - } catch (RuntimeException ex) { - // Assume this is a corrupt video file. - } finally { - try { - retriever.release(); - } catch (RuntimeException ex) { - // Ignore failures while cleaning up. - } - } - return bitmap; - } - - public static int indexOf(String [] array, String s) { - for (int i = 0; i < array.length; i++) { - if (array[i].equals(s)) { - return i; - } - } - return -1; - } - - public static void closeSiliently(Closeable c) { - if (c == null) return; - try { - c.close(); - } catch (Throwable t) { - // do nothing - } - } - - public static void closeSiliently(ParcelFileDescriptor c) { - if (c == null) return; - try { - c.close(); - } catch (Throwable t) { - // do nothing - } - } - -} diff --git a/src/com/android/camera/gallery/VideoList.java b/src/com/android/camera/gallery/VideoList.java index 3f67113..995fd65 100644 --- a/src/com/android/camera/gallery/VideoList.java +++ b/src/com/android/camera/gallery/VideoList.java @@ -16,7 +16,8 @@ package com.android.camera.gallery; -import static com.android.camera.gallery.BaseImageList.MINITHUMB_IS_NULL; +import com.android.camera.ImageManager; +import com.android.camera.Util; import android.content.ContentResolver; import android.content.Context; @@ -33,8 +34,6 @@ import android.provider.MediaStore.Video.VideoColumns; import android.util.Config; import android.util.Log; -import com.android.camera.ImageManager; - import java.io.IOException; import java.util.HashMap; diff --git a/src/com/android/camera/gallery/VideoObject.java b/src/com/android/camera/gallery/VideoObject.java index cd75e61..d4ce04e 100644 --- a/src/com/android/camera/gallery/VideoObject.java +++ b/src/com/android/camera/gallery/VideoObject.java @@ -16,12 +16,12 @@ package com.android.camera.gallery; +import com.android.camera.ImageManager; + import android.content.ContentResolver; import android.database.Cursor; import android.graphics.Bitmap; -import com.android.camera.ImageManager; - import java.io.IOException; import java.io.InputStream; @@ -78,7 +78,7 @@ public class VideoObject extends BaseImage implements IImage { } @Override - public IGetBitmapCancelable fullSizeBitmapCancelable( + public ICancelable fullSizeBitmapCancelable( int targetWidthHeight) { return null; } -- cgit v1.1