diff options
author | Dave Sparks <> | 2009-03-24 21:28:19 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-24 21:28:19 -0700 |
commit | f5e26bbc592503f28933941740c29070fa6222ae (patch) | |
tree | 9895283319741d5ead84c35c4ab2548ea286e9e1 /src/com | |
parent | 72e1dfd3b6ddbd87f281c42b6d31f7f0c3e85aac (diff) | |
download | LegacyCamera-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.java | 203 |
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(); } |