diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-13 13:04:24 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-13 13:04:24 -0700 |
commit | 8d0dd0e2ee9a9f8d729ed96597102777cf14701f (patch) | |
tree | 4d422a9bea896fbc60f90c67582828dea9bc21f0 /src/com | |
parent | e3f4516c2154539cb5778ef061abf8a0ccf90a5e (diff) | |
download | LegacyCamera-8d0dd0e2ee9a9f8d729ed96597102777cf14701f.zip LegacyCamera-8d0dd0e2ee9a9f8d729ed96597102777cf14701f.tar.gz LegacyCamera-8d0dd0e2ee9a9f8d729ed96597102777cf14701f.tar.bz2 |
auto import from //branches/cupcake_rel/...@138607
Diffstat (limited to 'src/com')
-rw-r--r-- | src/com/android/camera/ActionMenuButton.java | 25 | ||||
-rw-r--r-- | src/com/android/camera/Camera.java | 6 | ||||
-rwxr-xr-x | src/com/android/camera/ImageManager.java | 42 | ||||
-rw-r--r-- | src/com/android/camera/MenuHelper.java | 17 | ||||
-rw-r--r-- | src/com/android/camera/PhotoAppWidgetProvider.java | 2 | ||||
-rw-r--r-- | src/com/android/camera/VideoCamera.java | 59 | ||||
-rw-r--r-- | src/com/android/camera/ViewImage.java | 34 |
7 files changed, 125 insertions, 60 deletions
diff --git a/src/com/android/camera/ActionMenuButton.java b/src/com/android/camera/ActionMenuButton.java index 65e1f0e..d6d355a 100644 --- a/src/com/android/camera/ActionMenuButton.java +++ b/src/com/android/camera/ActionMenuButton.java @@ -34,8 +34,13 @@ public class ActionMenuButton extends TextView { private static final float PADDING_H = 5.0f; private static final float PADDING_V = 1.0f; + private static final int[] RESTRICTED_STATE_SET = { + R.attr.state_restricted + }; + private final RectF mRect = new RectF(); private Paint mPaint; + private boolean mRestricted = false; public ActionMenuButton(Context context) { super(context); @@ -59,6 +64,26 @@ public class ActionMenuButton extends TextView { mPaint.setColor(getContext().getResources().getColor(R.color.bubble_dark_background)); } + public void setRestricted(boolean restricted) { + if (restricted != mRestricted) { + mRestricted = restricted; + refreshDrawableState(); + } + } + + public boolean isRestricted() { + return mRestricted; + } + + @Override + protected int[] onCreateDrawableState(int extraSpace) { + int[] drawableState = super.onCreateDrawableState(extraSpace + 1); + if (isRestricted()) { + mergeDrawableStates(drawableState, RESTRICTED_STATE_SET); + } + return drawableState; + } + @Override protected void drawableStateChanged() { invalidate(); diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java index 71ed339..1111d0d 100644 --- a/src/com/android/camera/Camera.java +++ b/src/com/android/camera/Camera.java @@ -1273,11 +1273,13 @@ public class Camera extends Activity implements View.OnClickListener, } clearFocusState(); updateFocusIndicator(); - } else { + } else if (mFocusState == FOCUSING) { // Half pressing the shutter (i.e. the focus button event) will // already have requested AF for us, so just request capture on // focus here. mFocusState = FOCUSING_SNAP_ON_FINISH; + } else if (mFocusState == FOCUS_NOT_STARTED) { + // Focus key down event is dropped for some reasons. Just ignore. } } @@ -1527,6 +1529,8 @@ public class Camera extends Activity implements View.OnClickListener, mCameraDevice.stopPreview(); } mPreviewing = false; + // If auto focus was in progress, it would have been canceled. + clearFocusState(); } void gotoGallery() { diff --git a/src/com/android/camera/ImageManager.java b/src/com/android/camera/ImageManager.java index b470f95..0b5c850 100755 --- a/src/com/android/camera/ImageManager.java +++ b/src/com/android/camera/ImageManager.java @@ -374,15 +374,7 @@ public class ImageManager { Log.v(TAG, "cancelation of bitmap load success==" + (b == null ? "TRUE" : "FALSE") + " -- took " + (System.currentTimeMillis() - mCancelInitiationTime)); } if (b != null) { - int degrees = getDegreesRotated(); - if (degrees != 0) { - Matrix m = new Matrix(); - m.setRotate(degrees, (float) b.getWidth() / 2, (float) b.getHeight() / 2); - Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true); - if (b != b2) - b.recycle(); - b = b2; - } + b = rotate(b, getDegreesRotated()); } return b; } catch (Exception ex) { @@ -1157,10 +1149,7 @@ public class ImageManager { degrees = c.getInt(column); } if (degrees != 0) { - Bitmap b2 = rotate(bitmap, degrees); - if (b2 != bitmap) - bitmap.recycle(); - bitmap = b2; + bitmap = rotate(bitmap, degrees); } } } @@ -1977,7 +1966,8 @@ public class ImageManager { checkCanceled(); if (VERBOSE) Log.v(TAG, ">>>>>>>>>>>>>>>>>>>>> rotating by " + orientation); try { - saveMiniThumb(rotate(thumbnail, orientation)); + thumbnail = rotate(thumbnail, orientation); + saveMiniThumb(thumbnail); } catch (IOException e) { // Ignore if unable to save thumb. } @@ -2338,6 +2328,15 @@ public class ImageManager { if (pfd == null) return null; + try { + InputStream is = mContentResolver.openInputStream(uri); + Log.v(TAG, "available = " + is.available()); + if (is.available() > 5*1024*1024) return null; + is.close(); + } catch (IOException ex) { + return null; + } + if (options == null) options = new BitmapFactory.Options(); @@ -3720,15 +3719,22 @@ public class ImageManager { return miniThumbnail; } + // Rotates the bitmap by the specified degree. + // If a new bitmap is created, the original bitmap is recycled. 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); - Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, true); - // TODO should recycle here but that needs more testing/verification -// b.recycle(); - b = b2; + 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; } diff --git a/src/com/android/camera/MenuHelper.java b/src/com/android/camera/MenuHelper.java index 568b3a6..29bd279 100644 --- a/src/com/android/camera/MenuHelper.java +++ b/src/com/android/camera/MenuHelper.java @@ -651,19 +651,10 @@ public class MenuHelper { static private void requestOrientation(Activity activity, SharedPreferences prefs, boolean ignoreIntentExtra) { - int req = prefs.getInt("nuorientation", - android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); - // A little trick: use USER instead of UNSPECIFIED, so we ignore the - // orientation set by the activity below. It may have forced a landscape - // orientation, which the user has now cleared here. - if (req == android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) { - req = android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER; - } - if (! ignoreIntentExtra) { - Intent intent = activity.getIntent(); - req = intent.getIntExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, req); - } - activity.setRequestedOrientation(req); + // Disable orientation for now. If it is set to SCREEN_ORIENTATION_SENSOR, + // a duplicated orientation will be observed. + + return; } static void setFlipOrientationEnabled(Activity activity, MenuItem flipItem) { diff --git a/src/com/android/camera/PhotoAppWidgetProvider.java b/src/com/android/camera/PhotoAppWidgetProvider.java index 398528e..e87c1bd 100644 --- a/src/com/android/camera/PhotoAppWidgetProvider.java +++ b/src/com/android/camera/PhotoAppWidgetProvider.java @@ -108,7 +108,7 @@ public class PhotoAppWidgetProvider extends AppWidgetProvider { private static final String DATABASE_NAME = "launcher.db"; - private static final int DATABASE_VERSION = 1; + private static final int DATABASE_VERSION = 2; static final String TABLE_PHOTOS = "photos"; static final String FIELD_APPWIDGET_ID = "appWidgetId"; diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java index 1fb22e1..76e056c 100644 --- a/src/com/android/camera/VideoCamera.java +++ b/src/com/android/camera/VideoCamera.java @@ -67,7 +67,7 @@ import android.widget.TextView; import android.widget.Toast; public class VideoCamera extends Activity implements View.OnClickListener, - ShutterButton.OnShutterButtonListener, SurfaceHolder.Callback, MediaRecorder.OnErrorListener { + ShutterButton.OnShutterButtonListener, SurfaceHolder.Callback, MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener { private static final String TAG = "videocamera"; @@ -107,6 +107,8 @@ public class VideoCamera extends Activity implements View.OnClickListener, ImageView mVideoFrame; Bitmap mVideoFrameBitmap; + private static final int MAX_RECORDING_DURATION_MS = 10 * 60 * 1000; + private int mStorageStatus = STORAGE_STATUS_OK; private MediaRecorder mMediaRecorder; @@ -120,6 +122,7 @@ public class VideoCamera extends Activity implements View.OnClickListener, // The video file that has already been recorded, and that is being // examined by the user. private String mCurrentVideoFilename; + private long mCurrentVideoFileLength = 0L; private Uri mCurrentVideoUri; private ContentValues mCurrentVideoValues; @@ -131,6 +134,7 @@ public class VideoCamera extends Activity implements View.OnClickListener, private ShutterButton mShutterButton; private TextView mRecordingTimeView; + private boolean mRecordingTimeCountsDown = false; ArrayList<MenuItem> mGalleryItems = new ArrayList<MenuItem>(); @@ -154,7 +158,17 @@ public class VideoCamera extends Activity implements View.OnClickListener, if (mMediaRecorderRecording) { long now = SystemClock.uptimeMillis(); long delta = now - mRecordingStartTime; - long seconds = delta / 1000; + + // Starting a minute before reaching the max duration + // limit, we'll countdown the remaining time instead. + boolean countdown_remaining_time = + (delta >= MAX_RECORDING_DURATION_MS - 60000); + + if (countdown_remaining_time) { + delta = Math.max(0, MAX_RECORDING_DURATION_MS - delta); + } + + long seconds = (delta + 500) / 1000; // round to nearest long minutes = seconds / 60; long hours = minutes / 60; long remainderMinutes = minutes - (hours * 60); @@ -177,6 +191,20 @@ public class VideoCamera extends Activity implements View.OnClickListener, text = hoursString + ":" + text; } mRecordingTimeView.setText(text); + + if (mRecordingTimeCountsDown != countdown_remaining_time) { + // Avoid setting the color on every update, do it only + // when it needs changing. + + mRecordingTimeCountsDown = countdown_remaining_time; + + int color = getResources().getColor( + countdown_remaining_time ? R.color.recording_time_remaining_text + : R.color.recording_time_elapsed_text); + + mRecordingTimeView.setTextColor(color); + } + // Work around a limitation of the T-Mobile G1: The T-Mobile // hardware blitter can't pixel-accurately scale and clip at the same time, // and the SurfaceFlinger doesn't attempt to work around this limitation. @@ -266,8 +294,7 @@ public class VideoCamera extends Activity implements View.OnClickListener, } private void startShareVideoActivity() { - long fileLength = new File(mCurrentVideoFilename).length(); - if (fileLength > SHARE_FILE_LENGTH_LIMIT) { + if (mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT) { Toast.makeText(VideoCamera.this, R.string.too_large_to_attach, Toast.LENGTH_LONG).show(); return; @@ -323,6 +350,7 @@ public class VideoCamera extends Activity implements View.OnClickListener, stopVideoRecordingAndDisplayDialog(); } else if (mVideoFrame.getVisibility() == View.VISIBLE) { doStartCaptureMode(); + startVideoRecording(); } else { startVideoRecording(); } @@ -683,6 +711,8 @@ public class VideoCamera extends Activity implements View.OnClickListener, mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); + mMediaRecorder.setMaxDuration(MAX_RECORDING_DURATION_MS); + if (mStorageStatus != STORAGE_STATUS_OK) { mMediaRecorder.setOutputFile("/dev/null"); } else { @@ -866,6 +896,13 @@ public class VideoCamera extends Activity implements View.OnClickListener, } } + // from MediaRecorder.OnInfoListener + public void onInfo(MediaRecorder mr, int what, int extra) { + if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) { + stopVideoRecordingAndDisplayDialog(); + } + } + /* * Make sure we're not recording music playing in the background, ask * the MediaPlaybackService to pause playback. @@ -898,6 +935,7 @@ public class VideoCamera extends Activity implements View.OnClickListener, try { mMediaRecorder.setOnErrorListener(this); + mMediaRecorder.setOnInfoListener(this); mMediaRecorder.start(); // Recording is now started } catch (RuntimeException e) { Log.e(TAG, "Could not start media recorder. ", e); @@ -942,7 +980,10 @@ public class VideoCamera extends Activity implements View.OnClickListener, for(int id : hideIds) { mPostPictureAlert.findViewById(id).setVisibility(View.GONE); } - + ActionMenuButton shareButton = + (ActionMenuButton) mPostPictureAlert.findViewById(R.id.share); + shareButton.setRestricted( + mCurrentVideoFileLength > SHARE_FILE_LENGTH_LIMIT); connectAndFadeIn(connectIds); connectAndFadeIn(alwaysOnIds); mPostPictureAlert.setVisibility(View.VISIBLE); @@ -973,11 +1014,19 @@ public class VideoCamera extends Activity implements View.OnClickListener, if (mMediaRecorderRecording && mMediaRecorder != null) { try { mMediaRecorder.setOnErrorListener(null); + mMediaRecorder.setOnInfoListener(null); mMediaRecorder.stop(); } catch (RuntimeException e) { Log.e(TAG, "stop fail: " + e.getMessage()); } + mCurrentVideoFilename = mCameraVideoFilename; + try { + mCurrentVideoFileLength = new File(mCurrentVideoFilename).length(); + } catch (RuntimeException e) { + Log.e(TAG, "get file length fail: " + e.getMessage()); + mCurrentVideoFileLength = 0; + } Log.v(TAG, "Setting current video filename: " + mCurrentVideoFilename); needToRegisterRecording = true; mMediaRecorderRecording = false; diff --git a/src/com/android/camera/ViewImage.java b/src/com/android/camera/ViewImage.java index 7963e66..7aacbbb 100644 --- a/src/com/android/camera/ViewImage.java +++ b/src/com/android/camera/ViewImage.java @@ -247,9 +247,8 @@ public class ViewImage extends Activity implements View.OnClickListener private void setup(Context context) { mViewImage = (ViewImage) context; mGestureDetector = new GestureDetector(getContext(), new MyGestureListener()); - mGestureDetector.setOnDoubleTapListener(new MyDoubleTapListener()); - mZoomButtonsController = new ZoomButtonsController(context, this); - mZoomButtonsController.setCallback(new ZoomButtonsController.OnZoomListener() { + mZoomButtonsController = new ZoomButtonsController(this); + mZoomButtonsController.setOnZoomListener(new ZoomButtonsController.OnZoomListener() { public void onCenter(int x, int y) { } @@ -300,20 +299,25 @@ public class ViewImage extends Activity implements View.OnClickListener } private class MyGestureListener extends GestureDetector.SimpleOnGestureListener { + @Override + public boolean onDown(MotionEvent e) { + mZoomButtonsController.setVisible(true); + return true; + } + + @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if (getScale() > 1F) { postTranslate(-distanceX, -distanceY, sUseBounce); ImageViewTouch.this.center(true, true, false); } + mZoomButtonsController.setVisible(true); return true; } - } - private class MyDoubleTapListener implements GestureDetector.OnDoubleTapListener { - // On single tap, we show the arrows. We also change to the - // prev/next image if the user taps on the left/right region. - public boolean onSingleTapConfirmed(MotionEvent e) { + @Override + public boolean onSingleTapUp(MotionEvent e) { ViewImage viewImage = mViewImage; int viewWidth = getWidth(); @@ -330,20 +334,6 @@ public class ViewImage extends Activity implements View.OnClickListener return true; } - - // On double tap, we show the zoom controls. - public boolean onDoubleTapEvent(MotionEvent e) { - mViewImage.setMode(MODE_NORMAL); - if (mZoomButtonsController.handleDoubleTapEvent(e)) { - ZoomButtonsController.finishZoomTutorial(mViewImage, true); - } - return true; - } - - public boolean onDoubleTap(MotionEvent e) { - return false; - } - } @Override |