summaryrefslogtreecommitdiffstats
path: root/src/com
diff options
context:
space:
mode:
authorDave Sparks <>2009-03-24 21:28:19 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-24 21:28:19 -0700
commitf5e26bbc592503f28933941740c29070fa6222ae (patch)
tree9895283319741d5ead84c35c4ab2548ea286e9e1 /src/com
parent72e1dfd3b6ddbd87f281c42b6d31f7f0c3e85aac (diff)
downloadLegacyCamera-f5e26bbc592503f28933941740c29070fa6222ae.zip
LegacyCamera-f5e26bbc592503f28933941740c29070fa6222ae.tar.gz
LegacyCamera-f5e26bbc592503f28933941740c29070fa6222ae.tar.bz2
Automated import from //branches/donutburger/...@142121,142121
Diffstat (limited to 'src/com')
-rw-r--r--src/com/android/camera/Camera.java203
1 files changed, 92 insertions, 111 deletions
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java
index 46620f4..9cb30c9 100644
--- a/src/com/android/camera/Camera.java
+++ b/src/com/android/camera/Camera.java
@@ -120,6 +120,8 @@ public class Camera extends Activity implements View.OnClickListener,
private int mOriginalViewFinderWidth, mOriginalViewFinderHeight;
private int mViewFinderWidth, mViewFinderHeight;
private boolean mPreviewing = false;
+ private final Object mCameraLock = new Object();
+ private Thread mStartPreviewThread = null;
private Capturer mCaptureObject;
private ImageCapture mImageCapture = null;
@@ -505,13 +507,8 @@ public class Camera extends Activity implements View.OnClickListener,
* Initiate the capture of an image.
*/
public void initiate(boolean captureOnly) {
- if (mCameraDevice == null) {
- return;
- }
-
mCancel = false;
mCapturing = true;
-
capture(captureOnly);
}
@@ -652,15 +649,6 @@ public class Camera extends Activity implements View.OnClickListener,
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- // To reduce startup time, we open camera device in another thread.
- // We make sure the camera is opened at the end of onCreate.
- Thread openCameraThread = new Thread(new Runnable() {
- public void run() {
- mCameraDevice = android.hardware.Camera.open();
- }
- });
- openCameraThread.start();
-
// To reduce startup time, we run some service creation code in another thread.
// We make sure the services are loaded at the end of onCreate().
Thread loadServiceThread = new Thread(new Runnable() {
@@ -725,7 +713,6 @@ public class Camera extends Activity implements View.OnClickListener,
// Make sure the services are loaded.
try {
- openCameraThread.join();
loadServiceThread.join();
} catch (InterruptedException ex) {
}
@@ -878,7 +865,7 @@ public class Camera extends Activity implements View.OnClickListener,
}
public void onShutterButtonFocus(ShutterButton button, boolean pressed) {
- if (mPausing) {
+ if (!mPreviewing || mPausing) {
return;
}
switch (button.getId()) {
@@ -889,7 +876,7 @@ public class Camera extends Activity implements View.OnClickListener,
}
public void onShutterButtonClick(ShutterButton button) {
- if (mPausing) {
+ if (!mPreviewing || mPausing) {
return;
}
switch (button.getId()) {
@@ -1094,12 +1081,16 @@ public class Camera extends Activity implements View.OnClickListener,
break;
case KeyEvent.KEYCODE_FOCUS:
if (event.getRepeatCount() == 0) {
- doFocus(true);
+ if (mPreviewing) {
+ doFocus(true);
+ }
}
return true;
case KeyEvent.KEYCODE_CAMERA:
if (event.getRepeatCount() == 0) {
- doSnap();
+ if (mPreviewing) {
+ doSnap();
+ }
}
return true;
case KeyEvent.KEYCODE_DPAD_CENTER:
@@ -1108,13 +1099,15 @@ public class Camera extends Activity implements View.OnClickListener,
if (event.getRepeatCount() == 0) {
// Start auto-focus immediately to reduce shutter lag. After the shutter button
// gets the focus, doFocus() will be called again but it is fine.
- doFocus(true);
- if (mShutterButton.isInTouchMode()) {
- mShutterButton.requestFocusFromTouch();
- } else {
- mShutterButton.requestFocus();
+ if (mPreviewing) {
+ doFocus(true);
+ if (mShutterButton.isInTouchMode()) {
+ mShutterButton.requestFocusFromTouch();
+ } else {
+ mShutterButton.requestFocus();
+ }
+ mShutterButton.setPressed(true);
}
- mShutterButton.setPressed(true);
}
return true;
}
@@ -1187,6 +1180,7 @@ public class Camera extends Activity implements View.OnClickListener,
mSurfaceHolder = null;
}
+ // always call stopPreview before calling closeCamera
private void closeCamera() {
if (mCameraDevice != null) {
mCameraDevice.release();
@@ -1195,13 +1189,6 @@ public class Camera extends Activity implements View.OnClickListener,
}
}
- private boolean ensureCameraDevice() {
- if (mCameraDevice == null) {
- mCameraDevice = android.hardware.Camera.open();
- }
- return mCameraDevice != null;
- }
-
private void updateLastImage() {
ImageManager.IImageList list = ImageManager.instance().allImages(
this,
@@ -1255,9 +1242,6 @@ public class Camera extends Activity implements View.OnClickListener,
return;
}
- if (!ensureCameraDevice())
- return;
-
if (mSurfaceHolder == null)
return;
@@ -1279,101 +1263,98 @@ public class Camera extends Activity implements View.OnClickListener,
return;
/*
- * start the preview if we're asked to...
+ * start preview on a separate thread
*/
+ // start camera preview
+ synchronized(mCameraLock) {
+ if (mStartPreviewThread == null) {
+ mStartPreviewThread = new Thread(new Runnable() {
+ public void run() {
+
+ // create camera object
+ synchronized(mCameraLock) {
+ if (mCameraDevice == null) {
+ mCameraDevice = android.hardware.Camera.open();
+ }
+ }
- // we want to start the preview and we're previewing already,
- // stop the preview first (this will blank the screen).
- if (mPreviewing)
- stopPreview();
-
- // this blanks the screen if the surface changed, no-op otherwise
- try {
- mCameraDevice.setPreviewDisplay(mSurfaceHolder);
- } catch (IOException exception) {
- mCameraDevice.release();
- mCameraDevice = null;
- // TODO: add more exception handling logic here
- return;
- }
+ // we want to start the preview and we're previewing already,
+ // stop the preview first (this will blank the screen).
+ if (mPreviewing)
+ stopPreview();
- // request the preview size, the hardware may not honor it,
- // if we depended on it we would have to query the size again
- mParameters = mCameraDevice.getParameters();
- mParameters.setPreviewSize(w, h);
- try {
- mCameraDevice.setParameters(mParameters);
- } catch (IllegalArgumentException e) {
- // Ignore this error, it happens in the simulator.
- }
+ // this blanks the screen if the surface changed, no-op otherwise
+ try {
+ mCameraDevice.setPreviewDisplay(mSurfaceHolder);
+ } catch (IOException exception) {
+ mCameraDevice.release();
+ mCameraDevice = null;
+ // TODO: add more exception handling logic here
+ return;
+ }
+ // request the preview size, the hardware may not honor it,
+ // if we depended on it we would have to query the size again
+ mParameters = mCameraDevice.getParameters();
+ mParameters.setPreviewSize(mViewFinderWidth, mViewFinderHeight);
+ try {
+ mCameraDevice.setParameters(mParameters);
+ } catch (IllegalArgumentException e) {
+ // Ignore this error, it happens in the simulator.
+ }
- final long wallTimeStart = SystemClock.elapsedRealtime();
- final long threadTimeStart = Debug.threadCpuTimeNanos();
+ final long wallTimeStart = SystemClock.elapsedRealtime();
+ final long threadTimeStart = Debug.threadCpuTimeNanos();
- final Object watchDogSync = new Object();
- Thread watchDog = new Thread(new Runnable() {
- public void run() {
- int next_warning = 1;
- while (true) {
- try {
- synchronized (watchDogSync) {
- watchDogSync.wait(1000);
+ if (Config.LOGV) Log.v(TAG, "calling mCameraDevice.startPreview");
+ try {
+ mCameraDevice.startPreview();
+ } catch (Throwable e) {
+ // TODO: change Throwable to IOException once android.hardware.Camera.startPreview
+ // properly declares that it throws IOException.
}
- } catch (InterruptedException ex) {
- //
- }
- if (mPreviewing) break;
-
- int delay = (int) (SystemClock.elapsedRealtime() - wallTimeStart) / 1000;
- if (delay >= next_warning) {
- if (delay < 120) {
- Log.e(TAG, "preview hasn't started yet in " + delay + " seconds");
- } else {
- Log.e(TAG, "preview hasn't started yet in " + (delay / 60) + " minutes");
+ synchronized(mCameraLock) {
+ mPreviewing = true;
+ mStartPreviewThread = null;
}
- if (next_warning < 60) {
- next_warning <<= 1;
- if (next_warning == 16) {
- next_warning = 15;
- }
- } else {
- next_warning += 60;
+
+ long threadTimeEnd = Debug.threadCpuTimeNanos();
+ long wallTimeEnd = SystemClock.elapsedRealtime();
+ if ((wallTimeEnd - wallTimeStart) > 3000) {
+ Log.w(TAG, "startPreview() to " + (wallTimeEnd - wallTimeStart) + " ms. Thread time was"
+ + (threadTimeEnd - threadTimeStart) / 1000000 + " ms.");
}
}
- }
- }
- });
+ });
- watchDog.start();
-
- if (Config.LOGV)
- Log.v(TAG, "calling mCameraDevice.startPreview");
- try {
- mCameraDevice.startPreview();
- } catch (Throwable e) {
- // TODO: change Throwable to IOException once android.hardware.Camera.startPreview
- // properly declares that it throws IOException.
+ mStartPreviewThread.start();
+ }
}
- mPreviewing = true;
+ }
- synchronized (watchDogSync) {
- watchDogSync.notify();
+ // wait for preview thread if it is running
+ private void joinPreviewThread() {
+ Thread startPreviewThread;
+ synchronized(mCameraLock) {
+ startPreviewThread = mStartPreviewThread;
}
-
- long threadTimeEnd = Debug.threadCpuTimeNanos();
- long wallTimeEnd = SystemClock.elapsedRealtime();
- if ((wallTimeEnd - wallTimeStart) > 3000) {
- Log.w(TAG, "startPreview() to " + (wallTimeEnd - wallTimeStart) + " ms. Thread time was"
- + (threadTimeEnd - threadTimeStart) / 1000000 + " ms.");
+ if (startPreviewThread != null) {
+ try {
+ startPreviewThread.join();
+ } catch (InterruptedException ex) {
+ }
}
}
private void stopPreview() {
- if (mCameraDevice != null && mPreviewing) {
- mCameraDevice.stopPreview();
+ joinPreviewThread();
+ synchronized(mCameraLock) {
+ if (mCameraDevice != null && mPreviewing) {
+ mCameraDevice.stopPreview();
+ }
+ mPreviewing = false;
}
- mPreviewing = false;
+
// If auto focus was in progress, it would have been canceled.
clearFocusState();
}