diff options
Diffstat (limited to 'src/com/android/camera/Camera.java')
-rw-r--r-- | src/com/android/camera/Camera.java | 418 |
1 files changed, 272 insertions, 146 deletions
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java index 8b4de05..a0149df 100644 --- a/src/com/android/camera/Camera.java +++ b/src/com/android/camera/Camera.java @@ -16,6 +16,16 @@ package com.android.camera; +import com.android.camera.gallery.IImage; +import com.android.camera.gallery.IImageList; +import com.android.camera.ui.BasicSettingPicker; +import com.android.camera.ui.CameraHeadUpDisplay; +import com.android.camera.ui.GLRootView; +import com.android.camera.ui.HeadUpDisplay; +import com.android.camera.ui.ControlPanel; +import com.android.camera.ui.ZoomControllerListener; +import com.android.camera.ui.ZoomPicker; + import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; @@ -24,10 +34,10 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.content.res.Configuration; import android.content.res.Resources; +import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.hardware.Camera.CameraInfo; @@ -43,18 +53,17 @@ import android.media.ToneGenerator; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import android.os.Debug; import android.os.Environment; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.MessageQueue; -import android.os.SystemClock; import android.provider.MediaStore; import android.provider.Settings; +import android.provider.MediaStore.Images.ImageColumns; +import android.provider.MediaStore.Images.Media; import android.util.AttributeSet; import android.util.Log; -import android.view.Display; import android.view.GestureDetector; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -66,18 +75,16 @@ import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; +import android.view.ViewStub; import android.view.Window; import android.view.WindowManager; import android.view.MenuItem.OnMenuItemClickListener; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.Button; +import android.widget.CursorAdapter; import android.widget.FrameLayout; -import android.widget.ImageView; - -import com.android.camera.gallery.IImage; -import com.android.camera.gallery.IImageList; -import com.android.camera.ui.CameraHeadUpDisplay; -import com.android.camera.ui.GLRootView; -import com.android.camera.ui.HeadUpDisplay; -import com.android.camera.ui.ZoomControllerListener; +import android.widget.ListView; import java.io.File; import java.io.FileNotFoundException; @@ -130,6 +137,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, private int mZoomValue; // The current zoom value. private int mZoomMax; private int mTargetZoomValue; + private ZoomPicker mZoomPicker; private Parameters mParameters; private Parameters mInitialParams; @@ -163,10 +171,15 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, private GLRootView mGLRootView; - // mPostCaptureAlert, mLastPictureButton, mThumbController - // are non-null only if isImageCaptureIntent() is true. - private ImageView mLastPictureButton; - private ThumbnailController mThumbController; + // The layouts of small devices have a thumbnail button, which shows the last + // captured picture. + private RotateImageView mThumbnailButton; + // The layouts of xlarge devices have a list of thumbnails, which show the + // last captured pictures. + private ListView mThumbnailList; + private OnItemClickListener mThumbnailItemClickListener = + new ThumbnailItemClickListener(); + private ThumbnailAdapter mThumbnailAdapter; // mCropValue and mSaveUri are used only if isImageCaptureIntent() is true. private String mCropValue; @@ -174,6 +187,15 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, private ImageCapture mImageCapture = null; + /** + * An unpublished intent flag requesting to return as soon as capturing + * is completed. + * + * TODO: consider publishing by moving into MediaStore. + */ + private final static String EXTRA_QUICK_CAPTURE = + "android.intent.extra.quickCapture"; + private boolean mPreviewing; private boolean mPausing; private boolean mFirstTimeInitialized; @@ -230,12 +252,18 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, private String mSceneMode; private final Handler mHandler = new MainHandler(); + // Small devices use head-up display for camera settings. private CameraHeadUpDisplay mHeadUpDisplay; + // xlarge devices use control panel for camera settings. + private ControlPanel mControlPanel; + private PreferenceGroup mPreferenceGroup; // multiple cameras support private int mNumberOfCameras; private int mCameraId; + private boolean mQuickCapture; + /** * This Handler is used to post message back onto the main thread of the * application @@ -323,14 +351,8 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, mContentResolver = getContentResolver(); if (!mIsImageCaptureIntent) { findViewById(R.id.camera_switch).setOnClickListener(this); - mLastPictureButton = - (ImageView) findViewById(R.id.review_thumbnail); - mLastPictureButton.setOnClickListener(this); - mThumbController = new ThumbnailController( - getResources(), mLastPictureButton, mContentResolver); - mThumbController.loadData(ImageManager.getLastImageThumbPath()); - // Update last image thumbnail. - updateThumbnailButton(); + initThumbnailButton(); + initThumbnailList(); } // Initialize shutter button. @@ -345,8 +367,10 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, installIntentFilter(); initializeFocusTone(); initializeZoom(); - mHeadUpDisplay = new CameraHeadUpDisplay(this); - mHeadUpDisplay.setListener(new MyHeadUpDisplayListener()); + if (mControlPanel == null) { + mHeadUpDisplay = new CameraHeadUpDisplay(this); + mHeadUpDisplay.setListener(new MyHeadUpDisplayListener()); + } initializeHeadUpDisplay(); mFirstTimeInitialized = true; changeHeadUpDisplayState(); @@ -363,12 +387,95 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, }); } + private void initThumbnailButton() { + mThumbnailButton = + (RotateImageView) findViewById(R.id.review_thumbnail); + if (mThumbnailButton != null) { + mThumbnailButton.setOnClickListener(this); + mThumbnailButton.loadData(ImageManager.getLastImageThumbPath()); + updateThumbnailButton(); + } + } + private void updateThumbnailButton() { + if (mThumbnailButton == null) return; // Update last image if URI is invalid and the storage is ready. - if (!mThumbController.isUriValid() && mPicturesRemaining >= 0) { - updateLastImage(); + if (!mThumbnailButton.isUriValid() && mPicturesRemaining >= 0) { + IImageList list = ImageManager.makeImageList( + mContentResolver, + dataLocation(), + ImageManager.INCLUDE_IMAGES, + ImageManager.SORT_ASCENDING, + ImageManager.CAMERA_IMAGE_BUCKET_ID); + int count = list.getCount(); + if (count > 0) { + IImage image = list.getImageAt(count - 1); + Uri uri = image.fullSizeImageUri(); + mThumbnailButton.setData(uri, image.miniThumbBitmap()); + } else { + mThumbnailButton.setData(null, null); + } + list.close(); } - mThumbController.updateDisplayIfNeeded(); + } + + private void setLastPictureThumb(byte[] data, int degree, Uri uri) { + if (mThumbnailButton == null) return; + BitmapFactory.Options options = new BitmapFactory.Options(); + options.inSampleSize = 16; + Bitmap lastPictureThumb = + BitmapFactory.decodeByteArray(data, 0, data.length, options); + lastPictureThumb = Util.rotate(lastPictureThumb, degree); + mThumbnailButton.setData(uri, lastPictureThumb); + } + + private void initThumbnailList() { + mThumbnailList = (ListView) findViewById(R.id.thumbnail_list); + if (mThumbnailList == null) return; + + int width = mThumbnailList.getWidth(); + int height = mThumbnailList.getHeight(); + + // Add gallery button to header view. + if (mThumbnailList.getHeaderViewsCount() == 0) { + LayoutInflater inflater = getLayoutInflater(); + Button b = new Button(this); + ListView.LayoutParams params = new ListView.LayoutParams(width, width); + b.setId(R.id.btn_gallery); + b.setLayoutParams(params); + b.setOnClickListener(this); + b.setBackgroundResource(R.drawable.ic_menu_gallery); + mThumbnailList.addHeaderView(b); + } + + // Set data adapter. + int thumbnailCount = (height + mThumbnailList.getDividerHeight()) + / (width + mThumbnailList.getDividerHeight()) - 1; + Cursor cursor = getThumbnailsCursor(thumbnailCount); + mThumbnailAdapter = new ThumbnailAdapter( + getApplicationContext(), R.layout.thumbnail_item, cursor, true); + mThumbnailList.setAdapter(mThumbnailAdapter); + mThumbnailList.setOnItemClickListener(mThumbnailItemClickListener); + } + + private void updateThumbnailList() { + if (mThumbnailList == null) return; + mThumbnailAdapter.getCursor().requery(); + mThumbnailAdapter.notifyDataSetChanged(); + } + + private Cursor getThumbnailsCursor(int thumbnailCount) { + Log.v(TAG, "thumbnailCount=" + thumbnailCount); + String[] projections = { MediaStore.Images.Thumbnails._ID }; + Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI + .buildUpon() + .appendQueryParameter("limit", String.valueOf(thumbnailCount)) + .build(); + // TODO: managedQuery is deprecated. + return managedQuery(uri, projections, + Media.MIME_TYPE + " = 'image/jpeg' AND " + Media.BUCKET_ID + " = ?", + new String[] {ImageManager.CAMERA_IMAGE_BUCKET_ID}, + ImageColumns._ID + " DESC"); } // If the activity is paused and resumed, this method will be called in @@ -402,6 +509,15 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, mZoomMax = mParameters.getMaxZoom(); mSmoothZoomSupported = mParameters.isSmoothZoomSupported(); mGestureDetector = new GestureDetector(this, new ZoomGestureListener()); + if (mZoomPicker != null) { + mZoomPicker.setZoomRatios(getZoomRatios()); + mZoomPicker.setOnZoomChangeListener( + new ZoomPicker.OnZoomChangedListener() { + public void onZoomChanged(int index) { + onZoomValueChanged(index); + } + }); + } mCameraDevice.setZoomChangeListener(mZoomListener); } @@ -447,6 +563,13 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, return false; } + int x = Math.round(e.getX()); + int y = Math.round(e.getY()); + if (x < mSurfaceView.getLeft() || x > mSurfaceView.getRight() + || y < mSurfaceView.getTop() || y > mSurfaceView.getBottom()) { + return false; + } + if (mZoomValue < mZoomMax) { // Zoom in to the maximum. mZoomValue = mZoomMax; @@ -456,7 +579,11 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, setCameraParametersWhenIdle(UPDATE_PARAM_ZOOM); - mHeadUpDisplay.setZoomIndex(mZoomValue); + if (mZoomPicker != null) { + mZoomPicker.setZoomIndex(mZoomValue); + } else { + mHeadUpDisplay.setZoomIndex(mZoomValue); + } return true; } } @@ -486,6 +613,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, checkStorage(); if (!mIsImageCaptureIntent) { updateThumbnailButton(); + updateThumbnailList(); } } } @@ -608,7 +736,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, } Log.v(TAG, "mPictureDisplayedToJpegCallbackTime = " + mPictureDisplayedToJpegCallbackTime + "ms"); - mHeadUpDisplay.setEnabled(true); + enableCameraControls(true); if (!mIsImageCaptureIntent) { // We want to show the taken picture for a while, so we wait @@ -747,10 +875,14 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, "com.android.camera.NEW_PICTURE", mLastContentUri)); setLastPictureThumb(data, degree, mImageCapture.getLastCaptureUri()); - mThumbController.updateDisplayIfNeeded(); + updateThumbnailList(); } else { mCaptureOnlyData = data; - showPostCaptureAlert(); + if (!mQuickCapture) { + showPostCaptureAlert(); + } else { + doAttach(); + } } } @@ -839,7 +971,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, } mCaptureStartTime = System.currentTimeMillis(); mPostViewPictureCallbackTime = 0; - mHeadUpDisplay.setEnabled(false); + enableCameraControls(false); mStatus = SNAPSHOT_IN_PROGRESS; mImageCapture.initiate(); @@ -863,15 +995,6 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, return true; } - private void setLastPictureThumb(byte[] data, int degree, Uri uri) { - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inSampleSize = 16; - Bitmap lastPictureThumb = - BitmapFactory.decodeByteArray(data, 0, data.length, options); - lastPictureThumb = Util.rotate(lastPictureThumb, degree); - mThumbController.setData(uri, lastPictureThumb); - } - private String createName(long dateTaken) { Date date = new Date(dateTaken); SimpleDateFormat dateFormat = new SimpleDateFormat( @@ -894,6 +1017,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, CameraSettings.upgradeLocalPreferences(mPreferences.getLocal()); mNumberOfCameras = CameraHolder.instance().getNumberOfCameras(); + mQuickCapture = getIntent().getBooleanExtra(EXTRA_QUICK_CAPTURE, false); // we need to reset exposure for the preview resetExposureCompensation(); @@ -946,6 +1070,10 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, mSwitcher.addTouchView(findViewById(R.id.camera_switch_set)); } + // Show zoom picker. + ViewStub zoomStub = (ViewStub) findViewById(R.id.zoom_stub); + if (zoomStub != null) mZoomPicker = (ZoomPicker) zoomStub.inflate(); + // Make sure preview is started. try { startPreviewThread.join(); @@ -956,9 +1084,12 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, } catch (InterruptedException ex) { // ignore } + + initializeControlPanel(); } private void changeHeadUpDisplayState() { + if (mHeadUpDisplay == null) return; // If the camera resumes behind the lock screen, the orientation // will be portrait. That causes OOM when we try to allocation GPU // memory for the GLSurfaceView again when the orientation changes. So, @@ -992,13 +1123,32 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, } } + private void initializeControlPanel() { + String[] keys = new String[]{CameraSettings.KEY_FLASH_MODE, + CameraSettings.KEY_WHITE_BALANCE, + CameraSettings.KEY_COLOR_EFFECT, + CameraSettings.KEY_CAMERA_ID}; + mControlPanel = (ControlPanel) findViewById(R.id.control_panel); + if (mControlPanel != null) { + CameraSettings settings = new CameraSettings(this, mInitialParams, + mCameraId, CameraHolder.instance().getCameraInfo()); + mPreferenceGroup = settings.getPreferenceGroup(R.xml.camera_preferences); + mControlPanel.initialize(this, mPreferenceGroup, keys, true); + mControlPanel.setListener(new MyControlPanelListener()); + } + } + private void initializeHeadUpDisplay() { + if (mHeadUpDisplay == null) return; CameraSettings settings = new CameraSettings(this, mInitialParams, - CameraHolder.instance().getCameraInfo()); + mCameraId, CameraHolder.instance().getCameraInfo()); + // If we have zoom picker, do not show zoom control on head-up display. + float[] zoomRatios = null; + if (mZoomPicker == null) zoomRatios = getZoomRatios(); mHeadUpDisplay.initialize(this, settings.getPreferenceGroup(R.xml.camera_preferences), - getZoomRatios(), mOrientationCompensation); - if (mParameters.isZoomSupported()) { + zoomRatios, mOrientationCompensation); + if (mZoomPicker == null && mParameters.isZoomSupported()) { mHeadUpDisplay.setZoomListener(new ZoomControllerListener() { public void onZoomChanged( int index, float ratio, boolean isMoving) { @@ -1027,6 +1177,21 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, mGLRootView = null; } + private boolean collapseCameraControls() { + if (mHeadUpDisplay != null && mHeadUpDisplay.collapse()) { + return true; + } + if (mControlPanel != null && mControlPanel.hideSettingPicker()) { + return true; + } + return false; + } + + private void enableCameraControls(boolean enable) { + if (mHeadUpDisplay != null) mHeadUpDisplay.setEnabled(enable); + if (mControlPanel != null) mControlPanel.setEnabled(enable); + } + public static int roundOrientation(int orientation) { return ((orientation + 45) / 90 * 90) % 360; } @@ -1043,24 +1208,27 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, // the camera then point the camera to floor or sky, we still have // the correct orientation. if (orientation == ORIENTATION_UNKNOWN) return; - mOrientation = roundOrientation(orientation); - // When the screen is unlocked, display rotation may change. Always - // calculate the up-to-date orientationCompensation. - int orientationCompensation = mOrientation - + Util.getDisplayRotation(Camera.this); - if (mOrientationCompensation != orientationCompensation) { - mOrientationCompensation = orientationCompensation; + orientation = roundOrientation(orientation); + if (orientation != mOrientation) { + mOrientation = orientation; + mOrientationCompensation = orientation + + Util.getDisplayRotation(Camera.this); + if (!mIsImageCaptureIntent) { setOrientationIndicator(mOrientationCompensation); } - mHeadUpDisplay.setOrientation(mOrientationCompensation); + if (mHeadUpDisplay != null) { + mHeadUpDisplay.setOrientation(mOrientationCompensation); + } } } } private void setOrientationIndicator(int degree) { - ((RotateImageView) findViewById( - R.id.review_thumbnail)).setDegree(degree); + RotateImageView thumbnail = (RotateImageView) findViewById( + R.id.review_thumbnail); + if (thumbnail != null) thumbnail.setDegree(degree); + ((RotateImageView) findViewById( R.id.camera_switch_icon)).setDegree(degree); ((RotateImageView) findViewById( @@ -1097,7 +1265,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, break; case R.id.review_thumbnail: if (isCameraIdle()) { - viewLastImage(); + viewImage(mThumbnailButton); } break; case R.id.btn_done: @@ -1105,9 +1273,19 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, break; case R.id.btn_cancel: doCancel(); + break; + case R.id.btn_gallery: + gotoGallery(); + break; } } + private class ThumbnailItemClickListener implements OnItemClickListener { + public void onItemClick(AdapterView<?> p, View v, int pos, long id) { + viewImage((RotateImageView)v); + } + } + private Bitmap createCaptureBitmap(byte[] data) { // This is really stupid...we just want to read the orientation in // the jpeg header. @@ -1337,13 +1515,16 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, // Close the camera now because other activities may need to use it. closeCamera(); resetScreenOn(); + collapseCameraControls(); changeHeadUpDisplayState(); if (mFirstTimeInitialized) { mOrientationListener.disable(); if (!mIsImageCaptureIntent) { - mThumbController.storeData( - ImageManager.getLastImageThumbPath()); + if (mThumbnailButton != null) { + mThumbnailButton.storeData( + ImageManager.getLastImageThumbPath()); + } } hidePostCaptureAlert(); } @@ -1407,7 +1588,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, // Initiate autofocus only when preview is started and snapshot is not // in progress. if (canTakePicture()) { - mHeadUpDisplay.setEnabled(false); + enableCameraControls(false); Log.v(TAG, "Start autofocus."); mFocusStartTime = System.currentTimeMillis(); mFocusState = FOCUSING; @@ -1421,7 +1602,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, if (mStatus != SNAPSHOT_IN_PROGRESS && (mFocusState == FOCUSING || mFocusState == FOCUS_SUCCESS || mFocusState == FOCUS_FAIL)) { Log.v(TAG, "Cancel autofocus."); - mHeadUpDisplay.setEnabled(true); + enableCameraControls(true); mCameraDevice.cancelAutoFocus(); } if (mFocusState != FOCUSING_SNAP_ON_FINISH) { @@ -1453,7 +1634,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, if (!isCameraIdle()) { // ignore backs while we're taking a picture return; - } else if (mHeadUpDisplay == null || !mHeadUpDisplay.collapse()) { + } else if (!collapseCameraControls()) { super.onBackPressed(); } } @@ -1478,7 +1659,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, // Start auto-focus immediately to reduce shutter lag. After // the shutter button gets the focus, doFocus() will be // called again but it is fine. - if (mHeadUpDisplay.collapse()) return true; + if (collapseCameraControls()) return true; doFocus(true); if (mShutterButton.isInTouchMode()) { mShutterButton.requestFocusFromTouch(); @@ -1506,7 +1687,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, } private void doSnap() { - if (mHeadUpDisplay.collapse()) return; + if (collapseCameraControls()) return; Log.v(TAG, "doSnap: mFocusState=" + mFocusState); // If the user has half-pressed the shutter and focus is completed, we @@ -1530,7 +1711,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, private void doFocus(boolean pressed) { // Do the focus if the mode is not infinity. - if (mHeadUpDisplay.collapse()) return; + if (collapseCameraControls()) return; if (!(mFocusMode.equals(Parameters.FOCUS_MODE_INFINITY) || mFocusMode.equals(Parameters.FOCUS_MODE_FIXED) || mFocusMode.equals(Parameters.FOCUS_MODE_EDOF))) { @@ -1610,24 +1791,6 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, } } - private void updateLastImage() { - IImageList list = ImageManager.makeImageList( - mContentResolver, - dataLocation(), - ImageManager.INCLUDE_IMAGES, - ImageManager.SORT_ASCENDING, - ImageManager.CAMERA_IMAGE_BUCKET_ID); - int count = list.getCount(); - if (count > 0) { - IImage image = list.getImageAt(count - 1); - Uri uri = image.fullSizeImageUri(); - mThumbController.setData(uri, image.miniThumbBitmap()); - } else { - mThumbController.setData(null, null); - } - list.close(); - } - private void showCameraErrorAndFinish() { Resources ress = getResources(); Util.showFatalErrorAndFinish(Camera.this, @@ -1691,53 +1854,6 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, clearFocusState(); } - private Size getOptimalPreviewSize(List<Size> sizes, double targetRatio) { - final double ASPECT_TOLERANCE = 0.05; - if (sizes == null) return null; - - Size optimalSize = null; - double minDiff = Double.MAX_VALUE; - - // Because of bugs of overlay and layout, we sometimes will try to - // layout the viewfinder in the portrait orientation and thus get the - // wrong size of mSurfaceView. When we change the preview size, the - // new overlay will be created before the old one closed, which causes - // an exception. For now, just get the screen size - - Display display = getWindowManager().getDefaultDisplay(); - int targetHeight = Math.min(display.getHeight(), display.getWidth()); - - if (targetHeight <= 0) { - // We don't know the size of SurefaceView, use screen height - WindowManager windowManager = (WindowManager) - getSystemService(Context.WINDOW_SERVICE); - targetHeight = windowManager.getDefaultDisplay().getHeight(); - } - - // Try to find an size match aspect ratio and size - for (Size size : sizes) { - double ratio = (double) size.width / size.height; - if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; - if (Math.abs(size.height - targetHeight) < minDiff) { - optimalSize = size; - minDiff = Math.abs(size.height - targetHeight); - } - } - - // Cannot find the one match the aspect ratio, ignore the requirement - if (optimalSize == null) { - Log.v(TAG, "No preview size match the aspect ratio"); - minDiff = Double.MAX_VALUE; - for (Size size : sizes) { - if (Math.abs(size.height - targetHeight) < minDiff) { - optimalSize = size; - minDiff = Math.abs(size.height - targetHeight); - } - } - } - return optimalSize; - } - private static boolean isSupported(String value, List<String> supported) { return supported == null ? false : supported.indexOf(value) >= 0; } @@ -1781,7 +1897,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, // Set a preview size that is closest to the viewfinder height and has // the right aspect ratio. List<Size> sizes = mParameters.getSupportedPreviewSizes(); - Size optimalSize = getOptimalPreviewSize( + Size optimalSize = Util.getOptimalPreviewSize(this, sizes, (double) size.width / size.height); if (optimalSize != null) { Size original = mParameters.getPreviewSize(); @@ -1852,6 +1968,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, } if (mHeadUpDisplay != null) updateSceneModeInHud(); + // TODO: update icons on control panel. if (Parameters.SCENE_MODE_AUTO.equals(mSceneMode)) { // Set flash mode. @@ -1945,21 +2062,22 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, MenuHelper.gotoCameraImageGallery(this); } - private void viewLastImage() { - if (mThumbController.isUriValid()) { - Intent intent = new Intent(Util.REVIEW_ACTION, mThumbController.getUri()); + private void viewImage(RotateImageView view) { + if(!view.isUriValid()) { + Log.e(TAG, "Uri invalid. uri=" + view.getUri()); + return; + } + + try { + startActivity(new Intent( + Util.REVIEW_ACTION, view.getUri())); + } catch (ActivityNotFoundException ex) { try { - startActivity(intent); - } catch (ActivityNotFoundException ex) { - try { - intent = new Intent(Intent.ACTION_VIEW, mThumbController.getUri()); - startActivity(intent); - } catch (ActivityNotFoundException e) { - Log.e(TAG, "review image fail", e); - } + startActivity(new Intent( + Intent.ACTION_VIEW, view.getUri())); + } catch (ActivityNotFoundException e) { + Log.e(TAG, "review image fail. uri=" + view.getUri(), e); } - } else { - Log.e(TAG, "Can't view last image."); } } @@ -2201,7 +2319,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, private class MyHeadUpDisplayListener implements HeadUpDisplay.Listener { - public void onSharedPreferencesChanged() { + public void onSharedPreferenceChanged() { Camera.this.onSharedPreferenceChanged(); } @@ -2217,7 +2335,9 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, if (mPausing) return; Runnable runnable = new Runnable() { public void run() { - mHeadUpDisplay.restorePreferences(mParameters); + if (mHeadUpDisplay != null) { + mHeadUpDisplay.restorePreferences(mParameters); + } } }; MenuHelper.confirmAction(this, @@ -2225,6 +2345,12 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, getString(R.string.confirm_restore_message), runnable); } + + private class MyControlPanelListener implements ControlPanel.Listener { + public void onSharedPreferenceChanged() { + Camera.this.onSharedPreferenceChanged(); + } + } } class FocusRectangle extends View { |