summaryrefslogtreecommitdiffstats
path: root/src/com
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-13 13:04:24 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-13 13:04:24 -0700
commit8d0dd0e2ee9a9f8d729ed96597102777cf14701f (patch)
tree4d422a9bea896fbc60f90c67582828dea9bc21f0 /src/com
parente3f4516c2154539cb5778ef061abf8a0ccf90a5e (diff)
downloadLegacyCamera-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.java25
-rw-r--r--src/com/android/camera/Camera.java6
-rwxr-xr-xsrc/com/android/camera/ImageManager.java42
-rw-r--r--src/com/android/camera/MenuHelper.java17
-rw-r--r--src/com/android/camera/PhotoAppWidgetProvider.java2
-rw-r--r--src/com/android/camera/VideoCamera.java59
-rw-r--r--src/com/android/camera/ViewImage.java34
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