diff options
author | Chih-Chung Chang <chihchung@google.com> | 2010-06-15 16:41:33 +0800 |
---|---|---|
committer | Chih-Chung Chang <chihchung@google.com> | 2010-06-23 12:44:35 +0800 |
commit | ac9d0a1ce538eb4bd50cba3b257737a05b9ac4e5 (patch) | |
tree | 3afe1d6a8399087d1fc5c30065464828225a23da /src | |
parent | 186ff08e71d106e329171055accd4395760495ea (diff) | |
download | LegacyCamera-ac9d0a1ce538eb4bd50cba3b257737a05b9ac4e5.zip LegacyCamera-ac9d0a1ce538eb4bd50cba3b257737a05b9ac4e5.tar.gz LegacyCamera-ac9d0a1ce538eb4bd50cba3b257737a05b9ac4e5.tar.bz2 |
Support switching between multiple cameras.
Change-Id: Id444ebcd780c67f4990bd6f6b96c74379b6859ab
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/camera/Camera.java | 57 | ||||
-rw-r--r-- | src/com/android/camera/CameraButtonIntentReceiver.java | 3 | ||||
-rw-r--r-- | src/com/android/camera/CameraHolder.java | 25 | ||||
-rw-r--r-- | src/com/android/camera/CameraSettings.java | 14 | ||||
-rw-r--r-- | src/com/android/camera/MenuHelper.java | 15 | ||||
-rw-r--r-- | src/com/android/camera/Util.java | 20 | ||||
-rw-r--r-- | src/com/android/camera/VideoCamera.java | 64 |
7 files changed, 174 insertions, 24 deletions
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java index c67f093..5c12abe 100644 --- a/src/com/android/camera/Camera.java +++ b/src/com/android/camera/Camera.java @@ -173,6 +173,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, private boolean mPreviewing; private boolean mPausing; + private boolean mSwitching; private boolean mFirstTimeInitialized; private boolean mIsImageCaptureIntent; private boolean mRecordLocation; @@ -230,6 +231,10 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, private boolean mQuickCapture; private CameraHeadUpDisplay mHeadUpDisplay; + // multiple cameras support + private int mNumberOfCameras; + private int mCameraId; + /** * This Handler is used to post message back onto the main thread of the * application @@ -892,7 +897,8 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, mPreferences = PreferenceManager.getDefaultSharedPreferences(this); CameraSettings.upgradePreferences(mPreferences); - mQuickCapture = getQuickCaptureSettings(); + mNumberOfCameras = CameraHolder.instance().getNumberOfCameras(); + mCameraId = CameraSettings.readPreferredCameraId(this); // comment out -- unused now. //mQuickCapture = getQuickCaptureSettings(); @@ -968,7 +974,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, // becomes landscape. Configuration config = getResources().getConfiguration(); if (config.orientation == Configuration.ORIENTATION_LANDSCAPE - && !mPausing && mFirstTimeInitialized) { + && !mPausing && !mSwitching && mFirstTimeInitialized) { if (mGLRootView == null) attachHeadUpDisplay(); } else if (mGLRootView != null) { detachHeadUpDisplay(); @@ -1577,7 +1583,8 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, private void ensureCameraDevice() throws CameraHardwareException { if (mCameraDevice == null) { - mCameraDevice = CameraHolder.instance().open(); + mCameraDevice = CameraHolder.instance().open(mCameraId); + Util.setCameraDisplayOrientation(this, mCameraId, mCameraDevice); mInitialParams = mCameraDevice.getParameters(); } } @@ -2072,6 +2079,50 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, }); gallery.setIcon(android.R.drawable.ic_menu_gallery); mGalleryItems.add(gallery); + + if (mNumberOfCameras > 1) { + menu.add(Menu.NONE, Menu.NONE, + MenuHelper.POSITION_SWITCH_CAMERA_ID, + R.string.switch_camera_id) + .setOnMenuItemClickListener(new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + switchCameraId(); + return true; + } + }).setIcon(android.R.drawable.ic_menu_camera); + } + } + + private void switchCameraId() { + mSwitching = true; + + mCameraId = (mCameraId + 1) % mNumberOfCameras; + CameraSettings.writePreferredCameraId(this, mCameraId); + + stopPreview(); + closeCamera(); + changeHeadUpDisplayState(); + + // Remove the messages in the event queue. + mHandler.removeMessages(RESTART_PREVIEW); + + // Reset variables + mJpegPictureCallbackTime = 0; + mZoomValue = 0; + + // Restart the preview. + resetExposureCompensation(); + try { + startPreview(); + } catch (CameraHardwareException e) { + showCameraErrorAndFinish(); + return; + } + + initializeZoom(); + + mSwitching = false; + changeHeadUpDisplayState(); } private boolean switchToVideoMode() { diff --git a/src/com/android/camera/CameraButtonIntentReceiver.java b/src/com/android/camera/CameraButtonIntentReceiver.java index 38f9241..148542d 100644 --- a/src/com/android/camera/CameraButtonIntentReceiver.java +++ b/src/com/android/camera/CameraButtonIntentReceiver.java @@ -36,7 +36,8 @@ public class CameraButtonIntentReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { // Try to get the camera hardware CameraHolder holder = CameraHolder.instance(); - if (holder.tryOpen() == null) return; + int cameraId = CameraSettings.readPreferredCameraId(context); + if (holder.tryOpen(cameraId) == null) return; // We are going to launch the camera, so hold the camera for later use holder.keep(); diff --git a/src/com/android/camera/CameraHolder.java b/src/com/android/camera/CameraHolder.java index a4c1537..fc6e687 100644 --- a/src/com/android/camera/CameraHolder.java +++ b/src/com/android/camera/CameraHolder.java @@ -47,6 +47,7 @@ public class CameraHolder { private long mKeepBeforeTime = 0; // Keep the Camera before this time. private final Handler mHandler; private int mUsers = 0; // number of open() - number of release() + private int mNumberOfCameras; // We store the camera parameters when we actually open the device, // so we can restore them in the subsequent open() requests by the user. @@ -90,14 +91,30 @@ public class CameraHolder { HandlerThread ht = new HandlerThread("CameraHolder"); ht.start(); mHandler = new MyHandler(ht.getLooper()); + mNumberOfCameras = android.hardware.Camera.getNumberOfCameras(); + + android.hardware.Camera.CameraInfo info = + new android.hardware.Camera.CameraInfo(); + Log.v(TAG, "# of cameras:" + mNumberOfCameras); + for (int i = 0; i < mNumberOfCameras; i++) { + Log.v(TAG, "camera info #" + i); + android.hardware.Camera.getCameraInfo(i, info); + Log.v(TAG, "facing: " + info.mFacing); + Log.v(TAG, "orientation: " + info.mOrientation); + } + } + + public int getNumberOfCameras() { + return mNumberOfCameras; } - public synchronized android.hardware.Camera open() + public synchronized android.hardware.Camera open(int cameraId) throws CameraHardwareException { Assert(mUsers == 0); if (mCameraDevice == null) { try { - mCameraDevice = android.hardware.Camera.open(); + Log.v(TAG, "open camera " + cameraId); + mCameraDevice = android.hardware.Camera.open(cameraId); } catch (RuntimeException e) { Log.e(TAG, "fail to connect Camera", e); throw new CameraHardwareException(e); @@ -122,9 +139,9 @@ public class CameraHolder { * Tries to open the hardware camera. If the camera is being used or * unavailable then return {@code null}. */ - public synchronized android.hardware.Camera tryOpen() { + public synchronized android.hardware.Camera tryOpen(int cameraId) { try { - return mUsers == 0 ? open() : null; + return mUsers == 0 ? open(cameraId) : null; } catch (CameraHardwareException e) { // In eng build, we throw the exception so that test tool // can detect it and report it diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java index b32f077..6ac2e71 100644 --- a/src/com/android/camera/CameraSettings.java +++ b/src/com/android/camera/CameraSettings.java @@ -48,6 +48,7 @@ public class CameraSettings { public static final String KEY_QUICK_CAPTURE = "pref_camera_quickcapture_key"; public static final String KEY_EXPOSURE = "pref_camera_exposure_key"; public static final String KEY_METERING_MODE = "pref_camera_meteringmode_key"; + public static final String KEY_CAMERA_ID = "pref_camera_id"; public static final String QUICK_CAPTURE_ON = "on"; public static final String QUICK_CAPTURE_OFF = "off"; @@ -328,4 +329,17 @@ public class CameraSettings { } return DEFAULT_VIDEO_DURATION * 1000; } + + public static int readPreferredCameraId(Context context) { + SharedPreferences pref = + PreferenceManager.getDefaultSharedPreferences(context); + return pref.getInt(KEY_CAMERA_ID, 0); + } + + public static void writePreferredCameraId(Context context, int cameraId) { + SharedPreferences.Editor editor = PreferenceManager + .getDefaultSharedPreferences(context).edit(); + editor.putInt(KEY_CAMERA_ID, cameraId); + editor.commit(); + } } diff --git a/src/com/android/camera/MenuHelper.java b/src/com/android/camera/MenuHelper.java index e07f4f0..17755f9 100644 --- a/src/com/android/camera/MenuHelper.java +++ b/src/com/android/camera/MenuHelper.java @@ -58,20 +58,7 @@ public class MenuHelper { public static final int POSITION_SWITCH_CAMERA_MODE = 1; public static final int POSITION_GOTO_GALLERY = 2; - public static final int POSITION_VIEWPLAY = 3; - public static final int POSITION_CAPTURE_PICTURE = 4; - public static final int POSITION_CAPTURE_VIDEO = 5; - public static final int POSITION_IMAGE_SHARE = 6; - public static final int POSITION_IMAGE_ROTATE = 7; - public static final int POSITION_IMAGE_TOSS = 8; - public static final int POSITION_IMAGE_CROP = 9; - public static final int POSITION_IMAGE_SET = 10; - public static final int POSITION_DETAILS = 11; - public static final int POSITION_SHOWMAP = 12; - public static final int POSITION_SLIDESHOW = 13; - public static final int POSITION_MULTISELECT = 14; - public static final int POSITION_CAMERA_SETTING = 15; - public static final int POSITION_GALLERY_SETTING = 16; + public static final int POSITION_SWITCH_CAMERA_ID = 3; public static final int NO_STORAGE_ERROR = -1; public static final int CANNOT_STAT_ERROR = -2; diff --git a/src/com/android/camera/Util.java b/src/com/android/camera/Util.java index 44d5681..de99562 100644 --- a/src/com/android/camera/Util.java +++ b/src/com/android/camera/Util.java @@ -23,6 +23,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.util.Log; +import android.view.Surface; import android.view.View; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; @@ -278,4 +279,23 @@ public class Util { if (x < min) return min; return x; } + + public static void setCameraDisplayOrientation(Activity activity, + int cameraId, android.hardware.Camera camera) { + android.hardware.Camera.CameraInfo info = + new android.hardware.Camera.CameraInfo(); + android.hardware.Camera.getCameraInfo(cameraId, info); + int rotation = activity.getWindowManager().getDefaultDisplay() + .getRotation(); + int degrees = 0; + switch (rotation) { + case Surface.ROTATION_0: degrees = 0; break; + case Surface.ROTATION_90: degrees = 90; break; + case Surface.ROTATION_180: degrees = 180; break; + case Surface.ROTATION_270: degrees = 270; break; + } + + int result = (info.mOrientation - degrees + 360) % 360; + camera.setDisplayOrientation(result); + } } diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java index 0fac843..0fc4c43 100644 --- a/src/com/android/camera/VideoCamera.java +++ b/src/com/android/camera/VideoCamera.java @@ -162,6 +162,7 @@ public class VideoCamera extends NoSearchActivity private int mMaxVideoDurationInMs; boolean mPausing = false; + boolean mSwitching; boolean mPreviewing = false; // True if preview is started. private ContentResolver mContentResolver; @@ -176,6 +177,10 @@ public class VideoCamera extends NoSearchActivity private final Handler mHandler = new MainHandler(); private Parameters mParameters; + // multiple cameras support + private int mNumberOfCameras; + private int mCameraId; + // This Handler is used to post message back onto the main thread of the // application private class MainHandler extends Handler { @@ -269,6 +274,9 @@ public class VideoCamera extends NoSearchActivity mPreferences = PreferenceManager.getDefaultSharedPreferences(this); CameraSettings.upgradePreferences(mPreferences); + mNumberOfCameras = CameraHolder.instance().getNumberOfCameras(); + mCameraId = CameraSettings.readPreferredCameraId(this); + readVideoPreferences(); /* @@ -371,7 +379,7 @@ public class VideoCamera extends NoSearchActivity // becomes landscape. Configuration config = getResources().getConfiguration(); if (config.orientation == Configuration.ORIENTATION_LANDSCAPE - && !mPausing && mGLRootView == null) { + && !mPausing && !mSwitching && mGLRootView == null) { attachHeadUpDisplay(); } else if (mGLRootView != null) { detachHeadUpDisplay(); @@ -626,7 +634,8 @@ public class VideoCamera extends NoSearchActivity if (mCameraDevice == null) { // If the activity is paused and resumed, camera device has been // released and we need to open the camera. - mCameraDevice = CameraHolder.instance().open(); + mCameraDevice = CameraHolder.instance().open(mCameraId); + Util.setCameraDisplayOrientation(this, mCameraId, mCameraDevice); } mCameraDevice.lock(); @@ -1053,6 +1062,57 @@ public class VideoCamera extends NoSearchActivity }); gallery.setIcon(android.R.drawable.ic_menu_gallery); mGalleryItems.add(gallery); + + if (mNumberOfCameras > 1) { + menu.add(Menu.NONE, Menu.NONE, + MenuHelper.POSITION_SWITCH_CAMERA_ID, + R.string.switch_camera_id) + .setOnMenuItemClickListener(new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + switchCameraId(); + return true; + } + }).setIcon(android.R.drawable.ic_menu_camera); + } + } + + private void switchCameraId() { + mSwitching = true; + + int nextId = (mCameraId + 1) % mNumberOfCameras; + CameraSettings.writePreferredCameraId(this, nextId); + + changeHeadUpDisplayState(); + + // This is similar to what mShutterButton.performClick() does, + // but not quite the same. + if (mMediaRecorderRecording) { + if (mIsVideoCaptureIntent) { + stopVideoRecording(); + showAlert(); + } else { + stopVideoRecordingAndGetThumbnail(); + } + } else { + stopVideoRecording(); + } + closeCamera(); + mHandler.removeMessages(INIT_RECORDER); + + // Restart preview + try { + startPreview(); + } catch (CameraHardwareException e) { + showCameraBusyAndFinish(); + return; + } + + if (mSurfaceHolder != null) { + mHandler.sendEmptyMessage(INIT_RECORDER); + } + + mSwitching = false; + changeHeadUpDisplayState(); } private PreferenceGroup filterPreferenceScreenByIntent( |