Bug 803471 - Part 5c - Cange GonkCamera to use android::Camera. r=mhabicher
authorSotaro Ikeda <sikeda@mozilla.com>
Fri, 08 Mar 2013 14:43:33 -0500
changeset 124265 c7f37db7d7384244236b439f57dddcb8cdc9c60b
parent 124264 6fb64985500c3f1a4da1538d65e830328de9598f
child 124266 7f0a8b55cd6829d18d85aaf962e73543991d6fd9
push id24412
push userryanvm@gmail.com
push dateSun, 10 Mar 2013 00:01:53 +0000
treeherdermozilla-central@9e6232e86000 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmhabicher
bugs803471
milestone22.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 803471 - Part 5c - Cange GonkCamera to use android::Camera. r=mhabicher
dom/camera/GonkCameraControl.cpp
dom/camera/GonkCameraControl.h
dom/camera/GonkCameraHwMgr.cpp
dom/camera/GonkCameraHwMgr.h
dom/camera/GonkCameraListener.h
dom/camera/GonkCameraManager.cpp
dom/camera/GonkCameraSource.cpp
dom/camera/GonkCameraSource.h
--- a/dom/camera/GonkCameraControl.cpp
+++ b/dom/camera/GonkCameraControl.cpp
@@ -16,17 +16,16 @@
 
 #include <time.h>
 #include <string.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <libgen.h>
 #include "base/basictypes.h"
-#include "libcameraservice/CameraHardwareInterface.h"
 #include "camera/CameraParameters.h"
 #include "nsCOMPtr.h"
 #include "nsDOMClassInfo.h"
 #include "nsMemory.h"
 #include "jsapi.h"
 #include "nsThread.h"
 #include <media/MediaProfiles.h>
 #include "mozilla/FileUtils.h"
@@ -189,17 +188,16 @@ public:
   nsCOMPtr<nsICameraGetCameraCallback> mOnSuccessCb;
   nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
   uint64_t mWindowId;
 };
 
 // Construct nsGonkCameraControl on the main thread.
 nsGonkCameraControl::nsGonkCameraControl(uint32_t aCameraId, nsIThread* aCameraThread, nsDOMCameraControl* aDOMCameraControl, nsICameraGetCameraCallback* onSuccess, nsICameraErrorCallback* onError, uint64_t aWindowId)
   : CameraControlImpl(aCameraId, aCameraThread, aWindowId)
-  , mHwHandle(0)
   , mExposureCompensationMin(0.0)
   , mExposureCompensationStep(0.0)
   , mDeferConfigUpdate(false)
   , mWidth(0)
   , mHeight(0)
   , mLastPictureWidth(0)
   , mLastPictureHeight(0)
 #if !FORCE_PREVIEW_FORMAT_YUV420SP
@@ -225,18 +223,18 @@ void nsGonkCameraControl::DispatchInit(n
   // ...but initialization is carried out on the camera thread.
   nsCOMPtr<nsIRunnable> init = new InitGonkCameraControl(this, aDOMCameraControl, onSuccess, onError, aWindowId);
   mCameraThread->Dispatch(init, NS_DISPATCH_NORMAL);
 }
 
 nsresult
 nsGonkCameraControl::Init()
 {
-  mHwHandle = GonkCameraHardware::GetHandle(this, mCameraId);
-  DOM_CAMERA_LOGI("Initializing camera %d (this=%p, mHwHandle=%d)\n", mCameraId, this, mHwHandle);
+  mCameraHw = GonkCameraHardware::Connect(this, mCameraId);
+  DOM_CAMERA_LOGI("Initializing camera %d (this=%p, mCameraHw=%p)\n", mCameraId, this, mCameraHw.get());
 
   // Initialize our camera configuration database.
   PullParametersImpl();
 
   // Try to set preferred image format and frame rate
 #if !FORCE_PREVIEW_FORMAT_YUV420SP
   DOM_CAMERA_LOGI("Camera preview formats: %s\n", mParams.get(mParams.KEY_SUPPORTED_PREVIEW_FORMATS));
   const char* const PREVIEW_FORMAT = "yuv420p";
@@ -277,22 +275,22 @@ nsGonkCameraControl::Init()
   mMaxMeteringAreas = mParams.getInt(mParams.KEY_MAX_NUM_METERING_AREAS);
   mMaxFocusAreas = mParams.getInt(mParams.KEY_MAX_NUM_FOCUS_AREAS);
 
   DOM_CAMERA_LOGI(" - minimum exposure compensation: %f\n", mExposureCompensationMin);
   DOM_CAMERA_LOGI(" - exposure compensation step:    %f\n", mExposureCompensationStep);
   DOM_CAMERA_LOGI(" - maximum metering areas:        %d\n", mMaxMeteringAreas);
   DOM_CAMERA_LOGI(" - maximum focus areas:           %d\n", mMaxFocusAreas);
 
-  return mHwHandle != 0 ? NS_OK : NS_ERROR_FAILURE;
+  return mCameraHw.get() != nullptr ? NS_OK : NS_ERROR_FAILURE;
 }
 
 nsGonkCameraControl::~nsGonkCameraControl()
 {
-  DOM_CAMERA_LOGT("%s:%d : this=%p, mHwHandle = %d\n", __func__, __LINE__, this, mHwHandle);
+  DOM_CAMERA_LOGT("%s:%d : this=%p, mCameraHw = %p\n", __func__, __LINE__, this, mCameraHw.get());
 
   ReleaseHardwareImpl(nullptr);
   if (mRwLock) {
     PRRWLock* lock = mRwLock;
     mRwLock = nullptr;
     PR_DestroyRWLock(lock);
   }
 
@@ -648,17 +646,17 @@ nsGonkCameraControl::StartPreviewImpl(St
   if (aStartPreview->mDOMPreview) {
     StopPreviewInternal(true /* forced */);
     mDOMPreview = aStartPreview->mDOMPreview;
   } else if (!mDOMPreview) {
     return NS_ERROR_INVALID_ARG;
   }
 
   DOM_CAMERA_LOGI("%s: starting preview (mDOMPreview=%p)\n", __func__, mDOMPreview);
-  if (GonkCameraHardware::StartPreview(mHwHandle) != OK) {
+  if (mCameraHw->StartPreview() != OK) {
     DOM_CAMERA_LOGE("%s: failed to start preview\n", __func__);
     return NS_ERROR_FAILURE;
   }
 
   if (aStartPreview->mDOMPreview) {
     mDOMPreview->Started();
   }
   return NS_OK;
@@ -667,17 +665,17 @@ nsGonkCameraControl::StartPreviewImpl(St
 nsresult
 nsGonkCameraControl::StopPreviewInternal(bool aForced)
 {
   DOM_CAMERA_LOGI("%s: stopping preview (mDOMPreview=%p)\n", __func__, mDOMPreview);
 
   // StopPreview() is a synchronous call--it doesn't return
   // until the camera preview thread exits.
   if (mDOMPreview) {
-    GonkCameraHardware::StopPreview(mHwHandle);
+    mCameraHw->StopPreview();
     mDOMPreview->Stopped(aForced);
     mDOMPreview = nullptr;
   }
 
   return NS_OK;
 }
 
 nsresult
@@ -685,23 +683,23 @@ nsGonkCameraControl::StopPreviewImpl(Sto
 {
   return StopPreviewInternal();
 }
 
 nsresult
 nsGonkCameraControl::AutoFocusImpl(AutoFocusTask* aAutoFocus)
 {
   if (aAutoFocus->mCancel) {
-    GonkCameraHardware::CancelAutoFocus(mHwHandle);
+    mCameraHw->CancelAutoFocus();
   }
 
   mAutoFocusOnSuccessCb = aAutoFocus->mOnSuccessCb;
   mAutoFocusOnErrorCb = aAutoFocus->mOnErrorCb;
 
-  if (GonkCameraHardware::AutoFocus(mHwHandle) != OK) {
+  if (mCameraHw->AutoFocus() != OK) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 void
 nsGonkCameraControl::SetupThumbnail(uint32_t aPictureWidth, uint32_t aPictureHeight, uint32_t aPercentQuality)
 {
@@ -740,17 +738,17 @@ nsGonkCameraControl::SetupThumbnail(uint
     SetParameter(CAMERA_PARAM_THUMBNAILHEIGHT, static_cast<int>(h));
   }
 }
 
 nsresult
 nsGonkCameraControl::TakePictureImpl(TakePictureTask* aTakePicture)
 {
   if (aTakePicture->mCancel) {
-    GonkCameraHardware::CancelTakePicture(mHwHandle);
+    mCameraHw->CancelTakePicture();
   }
 
   mTakePictureOnSuccessCb = aTakePicture->mOnSuccessCb;
   mTakePictureOnErrorCb = aTakePicture->mOnErrorCb;
 
   // batch-update camera configuration
   mDeferConfigUpdate = true;
 
@@ -775,17 +773,17 @@ nsGonkCameraControl::TakePictureImpl(Tak
   }
 
   // Picture format -- need to keep it for the callback.
   mFileFormat = aTakePicture->mFileFormat;
   SetParameter(CameraParameters::KEY_PICTURE_FORMAT, NS_ConvertUTF16toUTF8(mFileFormat).get());
 
   // Convert 'rotation' to a positive value from 0..270 degrees, in steps of 90.
   uint32_t r = static_cast<uint32_t>(aTakePicture->mRotation);
-  r += GonkCameraHardware::GetSensorOrientation(mHwHandle);
+  r += mCameraHw->GetSensorOrientation();
   r %= 360;
   r += 45;
   r /= 90;
   r *= 90;
   DOM_CAMERA_LOGI("setting picture rotation to %d degrees (mapped from %d)\n", r, aTakePicture->mRotation);
   SetParameter(CameraParameters::KEY_ROTATION, nsPrintfCString("%u", r).get());
 
   // Add any specified positional information -- don't care if these fail.
@@ -831,40 +829,40 @@ nsGonkCameraControl::TakePictureImpl(Tak
     } else {
       DOM_CAMERA_LOGE("picture date/time couldn't be converted to local time: (%d) %s\n", errno, strerror(errno));
     }
   }
 
   mDeferConfigUpdate = false;
   PushParameters();
 
-  if (GonkCameraHardware::TakePicture(mHwHandle) != OK) {
+  if (mCameraHw->TakePicture() != OK) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 nsresult
 nsGonkCameraControl::PushParametersImpl()
 {
   DOM_CAMERA_LOGI("Pushing camera parameters\n");
   RwAutoLockRead lock(mRwLock);
-  if (GonkCameraHardware::PushParameters(mHwHandle, mParams) != OK) {
+  if (mCameraHw->PushParameters(mParams) != OK) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
 nsresult
 nsGonkCameraControl::PullParametersImpl()
 {
   DOM_CAMERA_LOGI("Pulling camera parameters\n");
   RwAutoLockWrite lock(mRwLock);
-  GonkCameraHardware::PullParameters(mHwHandle, mParams);
+  mCameraHw->PullParameters(mParams);
   return NS_OK;
 }
 
 nsresult
 nsGonkCameraControl::StartRecordingImpl(StartRecordingTask* aStartRecording)
 {
   NS_ENSURE_TRUE(mRecorderProfile, NS_ERROR_NOT_INITIALIZED);
   NS_ENSURE_FALSE(mRecorder, NS_ERROR_FAILURE);
@@ -1251,17 +1249,17 @@ nsGonkCameraControl::SetupRecording(int 
   char buffer[SIZE];
 
   mRecorder = new GonkRecorder();
   CHECK_SETARG(mRecorder->init());
 
   nsresult rv = mRecorderProfile->ConfigureRecorder(mRecorder);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  CHECK_SETARG(mRecorder->setCameraHandle((int32_t)mHwHandle));
+  CHECK_SETARG(mRecorder->setCamera(mCameraHw));
 
   DOM_CAMERA_LOGI("maxVideoLengthMs=%lld\n", aMaxVideoLengthMs);
   if (aMaxVideoLengthMs == 0) {
     aMaxVideoLengthMs = -1;
   }
   snprintf(buffer, SIZE, "max-duration=%lld", aMaxVideoLengthMs);
   CHECK_SETARG(mRecorder->setParameters(String8(buffer)));
 
@@ -1269,17 +1267,17 @@ nsGonkCameraControl::SetupRecording(int 
   if (aMaxFileSizeBytes == 0) {
     aMaxFileSizeBytes = -1;
   }
   snprintf(buffer, SIZE, "max-filesize=%lld", aMaxFileSizeBytes);
   CHECK_SETARG(mRecorder->setParameters(String8(buffer)));
 
   // adjust rotation by camera sensor offset
   int r = aRotation;
-  r += GonkCameraHardware::GetSensorOrientation(mHwHandle, GonkCameraHardware::RAW_SENSOR_ORIENTATION);
+  r += mCameraHw->GetSensorOrientation(GonkCameraHardware::RAW_SENSOR_ORIENTATION);
   r %= 360;
   r += 45;
   r /= 90;
   r *= 90;
   if (r < 0) {
     // the video recorder only supports positive rotations
     r += 360;
   }
@@ -1333,17 +1331,20 @@ nsGonkCameraControl::ReleaseHardwareImpl
     mRecorder->stop();
     mRecorder = nullptr;
   }
 
   // stop the preview
   StopPreviewInternal(true /* forced */);
 
   // release the hardware handle
-  GonkCameraHardware::ReleaseHandle(mHwHandle, true /* unregister */);
+  if (mCameraHw.get()){
+     mCameraHw->Close();
+     mCameraHw.clear();
+  }
 
   if (aReleaseHardware) {
     nsCOMPtr<nsIRunnable> releaseHardwareResult = new ReleaseHardwareResult(aReleaseHardware->mOnSuccessCb, mWindowId);
     return NS_DispatchToMainThread(releaseHardwareResult);
   }
 
   return NS_OK;
 }
--- a/dom/camera/GonkCameraControl.h
+++ b/dom/camera/GonkCameraControl.h
@@ -21,16 +21,23 @@
 #include "prrwlock.h"
 #include <media/MediaProfiles.h>
 #include "DeviceStorage.h"
 #include "nsIDOMCameraManager.h"
 #include "DOMCameraControl.h"
 #include "CameraControlImpl.h"
 #include "CameraCommon.h"
 #include "GonkRecorder.h"
+#include "GonkCameraHwMgr.h"
+
+namespace android {
+class GonkCameraHardware;
+class MediaProfiles;
+class GonkRecorder;
+}
 
 namespace mozilla {
 
 namespace layers {
 class GraphicBufferLocked;
 }
 
 class GonkRecorderProfile;
@@ -78,17 +85,17 @@ protected:
   already_AddRefed<RecorderProfileManager> GetRecorderProfileManagerImpl();
   already_AddRefed<GonkRecorderProfileManager> GetGonkRecorderProfileManager();
 
   nsresult SetupRecording(int aFd, int aRotation, int64_t aMaxFileSizeBytes, int64_t aMaxVideoLengthMs);
   nsresult SetupVideoMode(const nsAString& aProfile);
   void SetPreviewSize(uint32_t aWidth, uint32_t aHeight);
   void SetupThumbnail(uint32_t aPictureWidth, uint32_t aPictureHeight, uint32_t aPercentQuality);
 
-  uint32_t                  mHwHandle;
+  android::sp<android::GonkCameraHardware> mCameraHw;
   double                    mExposureCompensationMin;
   double                    mExposureCompensationStep;
   bool                      mDeferConfigUpdate;
   PRRWLock*                 mRwLock;
   android::CameraParameters mParams;
   uint32_t                  mWidth;
   uint32_t                  mHeight;
   uint32_t                  mLastPictureWidth;
--- a/dom/camera/GonkCameraHwMgr.cpp
+++ b/dom/camera/GonkCameraHwMgr.cpp
@@ -9,22 +9,25 @@
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
+#include <binder/IPCThreadState.h>
+#include <sys/system_properties.h>
+
 #include "base/basictypes.h"
 #include "nsDebug.h"
+#include "GonkCameraControl.h"
 #include "GonkCameraHwMgr.h"
 #include "GonkNativeWindow.h"
 #include "CameraCommon.h"
-#include <sys/system_properties.h>
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace android;
 
 #if GIHM_TIMING_RECEIVEFRAME
 #define INCLUDE_TIME_H                  1
 #endif
@@ -42,438 +45,293 @@ static __inline void timespecSubtract(st
     b->tv_nsec += 1000000000;
     b->tv_sec -= 1;
   }
   a->tv_nsec = b->tv_nsec - a->tv_nsec;
   a->tv_sec = b->tv_sec - a->tv_sec;
 }
 #endif
 
-GonkCameraHardware::GonkCameraHardware(GonkCamera* aTarget, uint32_t aCamera)
-  : mCamera(aCamera)
+GonkCameraHardware::GonkCameraHardware(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId, const sp<Camera>& aCamera)
+  : mCameraId(aCameraId)
   , mClosing(false)
   , mMonitor("GonkCameraHardware.Monitor")
   , mNumFrames(0)
+  , mCamera(aCamera)
   , mTarget(aTarget)
   , mInitialized(false)
+  , mSensorOrientation(0)
 {
   DOM_CAMERA_LOGT( "%s:%d : this=%p (aTarget=%p)\n", __func__, __LINE__, (void*)this, (void*)aTarget );
   Init();
 }
 
 void
 GonkCameraHardware::OnNewFrame()
 {
   if (mClosing) {
     return;
   }
-  GonkNativeWindow* window = static_cast<GonkNativeWindow*>(mWindow.get());
-  nsRefPtr<GraphicBufferLocked> buffer = window->getCurrentBuffer();
+  nsRefPtr<GraphicBufferLocked> buffer = mNativeWindow->getCurrentBuffer();
   ReceiveFrame(mTarget, buffer);
 }
 
 // Android data callback
 void
-GonkCameraHardware::DataCallback(int32_t aMsgType, const sp<IMemory> &aDataPtr, camera_frame_metadata_t* aMetadata, void* aUser)
+GonkCameraHardware::postData(int32_t aMsgType, const sp<IMemory>& aDataPtr, camera_frame_metadata_t* metadata)
 {
-  GonkCameraHardware* hw = GetHardware((uint32_t)aUser);
-  if (!hw) {
-    DOM_CAMERA_LOGW("%s:aUser = %d resolved to no camera hw\n", __func__, (uint32_t)aUser);
-    return;
-  }
-  if (hw->mClosing) {
+  if (mClosing) {
     return;
   }
 
-  GonkCamera* camera = hw->mTarget;
-  if (camera) {
-    switch (aMsgType) {
-      case CAMERA_MSG_PREVIEW_FRAME:
-        // Do nothing
-        break;
+  switch (aMsgType) {
+    case CAMERA_MSG_PREVIEW_FRAME:
+      // Do nothing
+      break;
 
-      case CAMERA_MSG_COMPRESSED_IMAGE:
-        ReceiveImage(camera, (uint8_t*)aDataPtr->pointer(), aDataPtr->size());
-        break;
+    case CAMERA_MSG_COMPRESSED_IMAGE:
+      ReceiveImage(mTarget, (uint8_t*)aDataPtr->pointer(), aDataPtr->size());
+      break;
 
-      default:
-        DOM_CAMERA_LOGE("Unhandled data callback event %d\n", aMsgType);
-        break;
-    }
-  } else {
-    DOM_CAMERA_LOGW("%s: hw = %p (camera = NULL)\n", __func__, hw);
+    default:
+      DOM_CAMERA_LOGE("Unhandled data callback event %d\n", aMsgType);
+      break;
   }
 }
 
 // Android notify callback
 void
-GonkCameraHardware::NotifyCallback(int32_t aMsgType, int32_t ext1, int32_t ext2, void* aUser)
+GonkCameraHardware::notify(int32_t aMsgType, int32_t ext1, int32_t ext2)
 {
   bool bSuccess;
-  GonkCameraHardware* hw = GetHardware((uint32_t)aUser);
-  if (!hw) {
-    DOM_CAMERA_LOGW("%s:aUser = %d resolved to no camera hw\n", __func__, (uint32_t)aUser);
-    return;
-  }
-  if (hw->mClosing) {
-    return;
-  }
-
-  GonkCamera* camera = hw->mTarget;
-  if (!camera) {
+  if (mClosing) {
     return;
   }
 
   switch (aMsgType) {
     case CAMERA_MSG_FOCUS:
       if (ext1) {
         DOM_CAMERA_LOGI("Autofocus complete");
         bSuccess = true;
       } else {
         DOM_CAMERA_LOGW("Autofocus failed");
         bSuccess = false;
       }
-      AutoFocusComplete(camera, bSuccess);
+      AutoFocusComplete(mTarget, bSuccess);
       break;
 
     case CAMERA_MSG_SHUTTER:
-      OnShutter(camera);
+      OnShutter(mTarget);
       break;
 
     default:
       DOM_CAMERA_LOGE("Unhandled notify callback event %d\n", aMsgType);
       break;
   }
 }
 
 void
-GonkCameraHardware::DataCallbackTimestamp(nsecs_t aTimestamp, int32_t aMsgType, const sp<IMemory> &aDataPtr, void* aUser)
+GonkCameraHardware::postDataTimestamp(nsecs_t aTimestamp, int32_t aMsgType, const sp<IMemory>& aDataPtr)
 {
   DOM_CAMERA_LOGI("%s",__func__);
-  GonkCameraHardware* hw = GetHardware((uint32_t)aUser);
-  if (!hw) {
-    DOM_CAMERA_LOGE("%s:aUser = %d resolved to no camera hw\n", __func__, (uint32_t)aUser);
-    return;
-  }
-  if (hw->mClosing) {
+  if (mClosing) {
     return;
   }
 
-  sp<GonkCameraListener> listener;
-  {
-    //TODO
-    //Mutex::Autolock _l(hw->mLock);
-    listener = hw->mListener;
-  }
-  if (listener.get()) {
+  if (mListener.get()) {
     DOM_CAMERA_LOGI("Listener registered, posting recording frame!");
-    listener->postDataTimestamp(aTimestamp, aMsgType, aDataPtr);
+    mListener->postDataTimestamp(aTimestamp, aMsgType, aDataPtr);
   } else {
     DOM_CAMERA_LOGW("No listener was set. Drop a recording frame.");
-    hw->mHardware->releaseRecordingFrame(aDataPtr);
+    mCamera->releaseRecordingFrame(aDataPtr);
   }
 }
 
 void
 GonkCameraHardware::Init()
 {
   DOM_CAMERA_LOGT("%s: this=%p\n", __func__, (void* )this);
 
-  if (hw_get_module(CAMERA_HARDWARE_MODULE_ID, (const hw_module_t**)&mModule) < 0) {
+  CameraInfo info;
+  int rv = Camera::getCameraInfo(mCameraId, &info);
+  if (rv != 0) {
+    DOM_CAMERA_LOGE("%s: failed to get CameraInfo mCameraId %d\n", __func__, mCameraId);
     return;
-  }
-  char cameraDeviceName[4];
-  snprintf(cameraDeviceName, sizeof(cameraDeviceName), "%d", mCamera);
-  mHardware = new CameraHardwareInterface(cameraDeviceName);
-  if (mHardware->initialize(&mModule->common) != OK) {
-    mHardware.clear();
-    return;
-  }
+   }
 
-  struct camera_info info;
-  int rv = mModule->get_camera_info(mCamera, &info);
-  if (rv != 0) {
-    return;
-  }
   mRawSensorOrientation = info.orientation;
   mSensorOrientation = mRawSensorOrientation;
 
   // Some kernels report the wrong sensor orientation through
   // get_camera_info()...
   char propname[PROP_NAME_MAX];
   char prop[PROP_VALUE_MAX];
   int offset = 0;
-  snprintf(propname, sizeof(propname), "ro.moz.cam.%d.sensor_offset", mCamera);
+  snprintf(propname, sizeof(propname), "ro.moz.cam.%d.sensor_offset", mCameraId);
   if (__system_property_get(propname, prop) > 0) {
     offset = clamped(atoi(prop), 0, 270);
     mSensorOrientation += offset;
     mSensorOrientation %= 360;
   }
   DOM_CAMERA_LOGI("Sensor orientation: base=%d, offset=%d, final=%d\n", info.orientation, offset, mSensorOrientation);
 
-  if (sHwHandle == 0) {
-    sHwHandle = 1;  // don't use 0
+  mNativeWindow = new GonkNativeWindow();
+  mNativeWindow->setNewFrameCallback(this);
+  mCamera->setListener(this);
+  mCamera->setPreviewTexture(mNativeWindow);
+  mInitialized = true;
+}
+
+sp<GonkCameraHardware>
+GonkCameraHardware::Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId)
+{
+  sp<Camera> camera = Camera::connect(aCameraId);
+  if (camera.get() == nullptr) {
+    return nullptr;
   }
-  mHardware->setCallbacks(GonkCameraHardware::NotifyCallback, GonkCameraHardware::DataCallback, GonkCameraHardware::DataCallbackTimestamp, (void*)sHwHandle);
-  mInitialized = true;
+  sp<GonkCameraHardware> cameraHardware = new GonkCameraHardware(aTarget, aCameraId, camera);
+  return cameraHardware;
+ }
+
+void
+GonkCameraHardware::Close()
+{
+  DOM_CAMERA_LOGT( "%s:%d : this=%p\n", __func__, __LINE__, (void*)this );
+
+  mClosing = true;
+  mCamera->stopPreview();
+  mCamera->disconnect();
+  if (mNativeWindow.get()) {
+    mNativeWindow->abandon();
+  }
+  mCamera.clear();
+  mNativeWindow.clear();
+
+  // Ensure that ICamera's destructor is actually executed
+  IPCThreadState::self()->flushCommands();
 }
 
 GonkCameraHardware::~GonkCameraHardware()
 {
   DOM_CAMERA_LOGT( "%s:%d : this=%p\n", __func__, __LINE__, (void*)this );
-  sHw = nullptr;
+  mCamera.clear();
+  mNativeWindow.clear();
 
   /**
    * Trigger the OnClosed event; the upper layers can't do anything
    * with the hardware layer once they receive this event.
    */
   if (mTarget) {
     OnClosed(mTarget);
   }
 }
 
-GonkCameraHardware* GonkCameraHardware::sHw         = nullptr;
-uint32_t            GonkCameraHardware::sHwHandle   = 0;
-
-void
-GonkCameraHardware::ReleaseHandle(uint32_t aHwHandle,
-                                  bool aUnregisterTarget = false)
+int
+GonkCameraHardware::GetSensorOrientation(uint32_t aType)
 {
-  GonkCameraHardware* hw = GetHardware(aHwHandle);
-  DOM_CAMERA_LOGI("%s: aHwHandle = %d, hw = %p (sHwHandle = %d)\n", __func__, aHwHandle, (void*)hw, sHwHandle);
-  if (!hw) {
-    return;
-  }
+  DOM_CAMERA_LOGI("%s\n", __func__);
 
-  DOM_CAMERA_LOGT("%s: before: sHwHandle = %d\n", __func__, sHwHandle);
-  sHwHandle += 1; // invalidate old handles before deleting
-  hw->mClosing = true;
-  hw->mHardware->disableMsgType(CAMERA_MSG_ALL_MSGS);
-  hw->mHardware->stopPreview();
-  hw->mHardware->release();
-  GonkNativeWindow* window = static_cast<GonkNativeWindow*>(hw->mWindow.get());
-  if (window) {
-    window->abandon();
-  }
-  DOM_CAMERA_LOGT("%s: after: sHwHandle = %d\n", __func__, sHwHandle);
-  if (aUnregisterTarget) {
-    hw->mTarget = nullptr;
-  }
-  delete hw;     // destroy the camera hardware instance
-}
-
-uint32_t
-GonkCameraHardware::GetHandle(GonkCamera* aTarget, uint32_t aCamera)
-{
-  ReleaseHandle(sHwHandle);
-
-  sHw = new GonkCameraHardware(aTarget, aCamera);
-
-  if (sHw->IsInitialized()) {
-    return sHwHandle;
-  }
-
-  DOM_CAMERA_LOGE("failed to initialize camera hardware\n");
-  delete sHw;
-  sHw = nullptr;
-  return 0;
-}
-
-int
-GonkCameraHardware::GetSensorOrientation(uint32_t aHwHandle, uint32_t aType)
-{
-  DOM_CAMERA_LOGI("%s: aHwHandle = %d\n", __func__, aHwHandle);
-  GonkCameraHardware* hw = GetHardware(aHwHandle);
-  if (!hw) {
-    return 0;
-  }
   switch (aType) {
     case OFFSET_SENSOR_ORIENTATION:
-      return hw->mSensorOrientation;
+      return mSensorOrientation;
 
     case RAW_SENSOR_ORIENTATION:
-      return hw->mRawSensorOrientation;
+      return mRawSensorOrientation;
 
     default:
       DOM_CAMERA_LOGE("%s:%d : unknown aType=%d\n", __func__, __LINE__, aType);
       return 0;
   }
 }
 
 int
-GonkCameraHardware::AutoFocus(uint32_t aHwHandle)
+GonkCameraHardware::AutoFocus()
 {
-  DOM_CAMERA_LOGI("%s: aHwHandle = %d\n", __func__, aHwHandle);
-  GonkCameraHardware* hw = GetHardware(aHwHandle);
-  if (!hw) {
-    return DEAD_OBJECT;
-  }
-
-  hw->mHardware->enableMsgType(CAMERA_MSG_FOCUS);
-  return hw->mHardware->autoFocus();
+  DOM_CAMERA_LOGI("%s\n", __func__);
+  return mCamera->autoFocus();
 }
 
 void
-GonkCameraHardware::CancelAutoFocus(uint32_t aHwHandle)
+GonkCameraHardware::CancelAutoFocus()
 {
-  DOM_CAMERA_LOGI("%s: aHwHandle = %d\n", __func__, aHwHandle);
-  GonkCameraHardware* hw = GetHardware(aHwHandle);
-  if (hw) {
-    hw->mHardware->cancelAutoFocus();
-  }
+  DOM_CAMERA_LOGI("%s\n", __func__);
+  mCamera->cancelAutoFocus();
 }
 
 int
-GonkCameraHardware::TakePicture(uint32_t aHwHandle)
+GonkCameraHardware::TakePicture()
 {
-  GonkCameraHardware* hw = GetHardware(aHwHandle);
-  if (!hw) {
-    return DEAD_OBJECT;
-  }
-
-  hw->mHardware->enableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
-  return hw->mHardware->takePicture();
+  return mCamera->takePicture(CAMERA_MSG_SHUTTER | CAMERA_MSG_COMPRESSED_IMAGE);
 }
 
 void
-GonkCameraHardware::CancelTakePicture(uint32_t aHwHandle)
+GonkCameraHardware::CancelTakePicture()
 {
-  GonkCameraHardware* hw = GetHardware(aHwHandle);
-  if (hw) {
-    hw->mHardware->cancelPicture();
-  }
+  DOM_CAMERA_LOGW("%s: android::Camera do not provide this capability\n", __func__);
 }
 
 int
-GonkCameraHardware::PushParameters(uint32_t aHwHandle, const CameraParameters& aParams)
+GonkCameraHardware::PushParameters(const CameraParameters& aParams)
 {
-  GonkCameraHardware* hw = GetHardware(aHwHandle);
-  if (!hw) {
-    return DEAD_OBJECT;
-  }
-
-  return hw->mHardware->setParameters(aParams);
+  String8 s = aParams.flatten();
+  return mCamera->setParameters(s);
 }
 
 void
-GonkCameraHardware::PullParameters(uint32_t aHwHandle, CameraParameters& aParams)
+GonkCameraHardware::PullParameters(CameraParameters& aParams)
 {
-  GonkCameraHardware* hw = GetHardware(aHwHandle);
-  if (hw) {
-    aParams = hw->mHardware->getParameters();
-  }
+  const String8 s = mCamera->getParameters();
+  aParams.unflatten(s);
 }
 
 int
 GonkCameraHardware::StartPreview()
 {
-  if (!mWindow.get()) {
-    mWindow = new GonkNativeWindow(this);
-    mHardware->setPreviewWindow(mWindow);
-  }
-
-  mHardware->enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
-  return mHardware->startPreview();
-}
-
-int
-GonkCameraHardware::StartPreview(uint32_t aHwHandle)
-{
-  GonkCameraHardware* hw = GetHardware(aHwHandle);
-  DOM_CAMERA_LOGI("%s : aHwHandle = %d, hw = %p\n", __func__, aHwHandle, hw);
-  if (!hw) {
-    return DEAD_OBJECT;
-  }
-
-  return hw->StartPreview();
+  DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
+  return mCamera->startPreview();
 }
 
 void
-GonkCameraHardware::StopPreview(uint32_t aHwHandle)
+GonkCameraHardware::StopPreview()
 {
-  GonkCameraHardware* hw = GetHardware(aHwHandle);
-  DOM_CAMERA_LOGI("%s : aHwHandle = %d, hw = %p\n", __func__, aHwHandle, hw);
-  if (hw) {
-    // Must disable messages first; else some drivers will silently discard
-    //  the stopPreview() request, which can lead to crashes and other
-    //  Very Bad Things that are Hard To Diagnose.
-    hw->mHardware->disableMsgType(CAMERA_MSG_ALL_MSGS);
-    hw->mHardware->stopPreview();
-  }
+  DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
+  return mCamera->stopPreview();
 }
 
 int
-GonkCameraHardware::StartRecording(uint32_t aHwHandle)
+GonkCameraHardware::StartRecording()
 {
-  DOM_CAMERA_LOGI("%s: aHwHandle = %d\n", __func__, aHwHandle);
+  DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
   int rv = OK;
-  GonkCameraHardware* hw = GetHardware(aHwHandle);
-  if (!hw) {
-    return DEAD_OBJECT;
-  }
-
-  if (hw->mHardware->recordingEnabled()) {
-    return OK;
-  }
 
-  if (!hw->mHardware->previewEnabled()) {
-    DOM_CAMERA_LOGW("Preview was not enabled, enabling now!\n");
-    rv = StartPreview(aHwHandle);
-    if (rv != OK) {
-      return rv;
-    }
-  }
-
-  // start recording mode
-  hw->mHardware->enableMsgType(CAMERA_MSG_VIDEO_FRAME);
-  DOM_CAMERA_LOGI("Calling hw->startRecording\n");
-  rv = hw->mHardware->startRecording();
+  rv = mCamera->startRecording();
   if (rv != OK) {
     DOM_CAMERA_LOGE("mHardware->startRecording() failed with status %d", rv);
   }
   return rv;
 }
 
 int
-GonkCameraHardware::StopRecording(uint32_t aHwHandle)
+GonkCameraHardware::StopRecording()
 {
-  DOM_CAMERA_LOGI("%s: aHwHandle = %d\n", __func__, aHwHandle);
-  GonkCameraHardware* hw = GetHardware(aHwHandle);
-  if (!hw) {
-    return DEAD_OBJECT;
-  }
-
-  hw->mHardware->disableMsgType(CAMERA_MSG_VIDEO_FRAME);
-  hw->mHardware->stopRecording();
+  DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
+  mCamera->stopRecording();
   return OK;
 }
 
 int
-GonkCameraHardware::SetListener(uint32_t aHwHandle, const sp<GonkCameraListener>& aListener)
+GonkCameraHardware::SetListener(const sp<GonkCameraListener>& aListener)
 {
-  GonkCameraHardware* hw = GetHardware(aHwHandle);
-  if (!hw) {
-    return DEAD_OBJECT;
-  }
-
-  hw->mListener = aListener;
+  mListener = aListener;
   return OK;
 }
 
 void
-GonkCameraHardware::ReleaseRecordingFrame(uint32_t aHwHandle, const sp<IMemory>& aFrame)
+GonkCameraHardware::ReleaseRecordingFrame(const sp<IMemory>& aFrame)
 {
-  GonkCameraHardware* hw = GetHardware(aHwHandle);
-  if (hw) {
-    hw->mHardware->releaseRecordingFrame(aFrame);
-  }
+  mCamera->releaseRecordingFrame(aFrame);
 }
 
 int
-GonkCameraHardware::StoreMetaDataInBuffers(uint32_t aHwHandle, bool aEnabled)
+GonkCameraHardware::StoreMetaDataInBuffers(bool aEnabled)
 {
-  GonkCameraHardware* hw = GetHardware(aHwHandle);
-  if (!hw) {
-    return DEAD_OBJECT;
-  }
-
-  return hw->mHardware->storeMetaDataInBuffers(aEnabled);
+  return mCamera->storeMetaDataInBuffers(aEnabled);
 }
--- a/dom/camera/GonkCameraHwMgr.h
+++ b/dom/camera/GonkCameraHwMgr.h
@@ -12,52 +12,58 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 #ifndef DOM_CAMERA_GONKCAMERAHWMGR_H
 #define DOM_CAMERA_GONKCAMERAHWMGR_H
 
-#include "libcameraservice/CameraHardwareInterface.h"
-#include "binder/IMemory.h"
-#include "mozilla/ReentrantMonitor.h"
-#include "GonkCameraListener.h"
+#include <binder/IMemory.h>
+#include <camera/Camera.h>
+#include <camera/CameraParameters.h>
 #include <utils/threads.h>
 
 #include "GonkCameraControl.h"
 #include "CameraCommon.h"
 
+#include "GonkCameraListener.h"
 #include "GonkNativeWindow.h"
+#include "mozilla/ReentrantMonitor.h"
 
 // config
 #define GIHM_TIMING_RECEIVEFRAME    0
 #define GIHM_TIMING_OVERALL         1
 
 
 namespace mozilla {
+  class nsGonkCameraControl;
+}
 
-typedef class nsGonkCameraControl GonkCamera;
+namespace android {
 
-class GonkCameraHardware : android::GonkNativeWindowNewFrameCallback
+class GonkCameraHardware : public GonkNativeWindowNewFrameCallback
+                         , public CameraListener
 {
 protected:
-  GonkCameraHardware(GonkCamera* aTarget, uint32_t aCamera);
-  ~GonkCameraHardware();
+  GonkCameraHardware(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId, const sp<Camera>& aCamera);
+  virtual ~GonkCameraHardware();
   void Init();
 
-  static void     DataCallback(int32_t aMsgType, const android::sp<android::IMemory> &aDataPtr, camera_frame_metadata_t* aMetadata, void* aUser);
-  static void     NotifyCallback(int32_t aMsgType, int32_t ext1, int32_t ext2, void* aUser);
-  static void     DataCallbackTimestamp(nsecs_t aTimestamp, int32_t aMsgType, const android::sp<android::IMemory>& aDataPtr, void* aUser);
+public:
+  static  sp<GonkCameraHardware>  Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId);
+  void    Close();
 
-public:
+  // derived from GonkNativeWindowNewFrameCallback
   virtual void    OnNewFrame() MOZ_OVERRIDE;
 
-  static void     ReleaseHandle(uint32_t aHwHandle, bool aUnregisterTarget);
-  static uint32_t GetHandle(GonkCamera* aTarget, uint32_t aCamera);
+  // derived from CameraListener
+  virtual void notify(int32_t aMsgType, int32_t ext1, int32_t ext2);
+  virtual void postData(int32_t aMsgType, const sp<IMemory>& aDataPtr, camera_frame_metadata_t* metadata);
+  virtual void postDataTimestamp(nsecs_t aTimestamp, int32_t aMsgType, const sp<IMemory>& aDataPtr);
 
   /**
    * The physical orientation of the camera sensor: 0, 90, 180, or 270.
    *
    * For example, suppose a device has a naturally tall screen. The
    * back-facing camera sensor is mounted in landscape. You are looking at
    * the screen. If the top side of the camera sensor is aligned with the
    * right edge of the screen in natural orientation, the value should be
@@ -67,74 +73,55 @@ public:
    * RAW_SENSOR_ORIENTATION is the uncorrected orientation returned directly
    * by get_camera_info(); OFFSET_SENSOR_ORIENTATION is the offset adjusted
    * orientation.
    */
   enum {
     RAW_SENSOR_ORIENTATION,
     OFFSET_SENSOR_ORIENTATION
   };
-  static int      GetSensorOrientation(uint32_t aHwHandle, uint32_t aType = OFFSET_SENSOR_ORIENTATION);
+  int      GetSensorOrientation(uint32_t aType = OFFSET_SENSOR_ORIENTATION);
 
-  static int      AutoFocus(uint32_t aHwHandle);
-  static void     CancelAutoFocus(uint32_t aHwHandle);
-  static int      TakePicture(uint32_t aHwHandle);
-  static void     CancelTakePicture(uint32_t aHwHandle);
-  static int      StartPreview(uint32_t aHwHandle);
-  static void     StopPreview(uint32_t aHwHandle);
-  static int      PushParameters(uint32_t aHwHandle, const android::CameraParameters& aParams);
-  static void     PullParameters(uint32_t aHwHandle, android::CameraParameters& aParams);
-  static int      StartRecording(uint32_t aHwHandle);
-  static int      StopRecording(uint32_t aHwHandle);
-  static int      SetListener(uint32_t aHwHandle, const android::sp<android::GonkCameraListener>& aListener);
-  static void     ReleaseRecordingFrame(uint32_t aHwHandle, const android::sp<android::IMemory>& aFrame);
-  static int      StoreMetaDataInBuffers(uint32_t aHwHandle, bool aEnabled);
+  int      AutoFocus();
+  void     CancelAutoFocus();
+  int      TakePicture();
+  void     CancelTakePicture();
+  int      StartPreview();
+  void     StopPreview();
+  int      PushParameters(const CameraParameters& aParams);
+  void     PullParameters(CameraParameters& aParams);
+  int      StartRecording();
+  int      StopRecording();
+  int      SetListener(const sp<GonkCameraListener>& aListener);
+  void     ReleaseRecordingFrame(const sp<IMemory>& aFrame);
+  int      StoreMetaDataInBuffers(bool aEnabled);
 
 protected:
-  static GonkCameraHardware*    sHw;
-  static uint32_t               sHwHandle;
 
-  static GonkCameraHardware*    GetHardware(uint32_t aHwHandle)
-  {
-    if (aHwHandle == sHwHandle) {
-      /**
-       * In the initial case, sHw will be null and sHwHandle will be 0,
-       * so even if this function is called with aHwHandle = 0, the
-       * result will still be null.
-       */
-      return sHw;
-    }
-    return nullptr;
-  }
-
-  // Instance wrapper to make member function access easier.
-  int StartPreview();
-
-  uint32_t                      mCamera;
+  uint32_t                      mCameraId;
   bool                          mClosing;
   mozilla::ReentrantMonitor     mMonitor;
   uint32_t                      mNumFrames;
-  android::sp<android::CameraHardwareInterface>   mHardware;
-  GonkCamera*                   mTarget;
-  camera_module_t*              mModule;
-  android::sp<ANativeWindow>             mWindow;
+  sp<Camera>                    mCamera;
+  mozilla::nsGonkCameraControl* mTarget;
+  sp<GonkNativeWindow>          mNativeWindow;
 #if GIHM_TIMING_OVERALL
   struct timespec               mStart;
   struct timespec               mAutoFocusStart;
 #endif
-  android::sp<android::GonkCameraListener>        mListener;
+  sp<GonkCameraListener>        mListener;
   bool                          mInitialized;
   int                           mRawSensorOrientation;
   int                           mSensorOrientation;
 
   bool IsInitialized()
   {
     return mInitialized;
   }
 
 private:
   GonkCameraHardware(const GonkCameraHardware&) MOZ_DELETE;
   GonkCameraHardware& operator=(const GonkCameraHardware&) MOZ_DELETE;
 };
 
-} // namespace mozilla
+} // namespace android
 
 #endif // GONK_IMPL_HW_MGR_H
--- a/dom/camera/GonkCameraListener.h
+++ b/dom/camera/GonkCameraListener.h
@@ -13,17 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 #ifndef GONK_CAMERA_LISTENER_H
 #define GONK_CAMERA_LISTENER_H
 
 #include <utils/Timers.h>
-#include "libcameraservice/CameraHardwareInterface.h"
+#include <camera/Camera.h>
 
 namespace android {
 
 // ref-counted object for callbacks
 class GonkCameraListener: virtual public RefBase
 {
 public:
     virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
--- a/dom/camera/GonkCameraManager.cpp
+++ b/dom/camera/GonkCameraManager.cpp
@@ -9,47 +9,46 @@
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
+#include <camera/Camera.h>
+
 #include "jsapi.h"
-#include "libcameraservice/CameraHardwareInterface.h"
 #include "GonkCameraControl.h"
 #include "DOMCameraManager.h"
 #include "CameraCommon.h"
 
 // From nsDOMCameraManager, but gonk-specific!
 
 /* [implicit_jscontext] jsval getListOfCameras (); */
 NS_IMETHODIMP
 nsDOMCameraManager::GetListOfCameras(JSContext* cx, JS::Value* _retval)
 {
   JSObject* a = JS_NewArrayObject(cx, 0, nullptr);
-  camera_module_t* module;
   uint32_t index = 0;
-  uint32_t count;
+  int32_t count;
 
   if (!a) {
     DOM_CAMERA_LOGE("getListOfCameras : Could not create array object");
     return NS_ERROR_OUT_OF_MEMORY;
   }
-  if (hw_get_module(CAMERA_HARDWARE_MODULE_ID, (const hw_module_t**)&module) < 0) {
-    DOM_CAMERA_LOGE("getListOfCameras : Could not load camera HAL module");
+  count = android::Camera::getNumberOfCameras();
+  if (count <= 0) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
-  count = module->get_number_of_cameras();
   DOM_CAMERA_LOGI("getListOfCameras : get_number_of_cameras() returned %d\n", count);
   while (count--) {
-    struct camera_info info;
-    int rv = module->get_camera_info(count, &info);
+    android::CameraInfo info;
+    int rv = android::Camera::getCameraInfo(count, &info);
     if (rv != 0) {
       DOM_CAMERA_LOGE("getListOfCameras : get_camera_info(%d) failed: %d\n", count, rv);
       continue;
     }
 
     JSString* v;
     jsval jv;
 
--- a/dom/camera/GonkCameraSource.cpp
+++ b/dom/camera/GonkCameraSource.cpp
@@ -120,49 +120,48 @@ static int32_t getColorFormat(const char
 
     LOGE("Uknown color format (%s), please add it to "
          "GonkCameraSource::getColorFormat", colorFormat);
 
     CHECK_EQ(0, "Unknown color format");
 }
 
 GonkCameraSource *GonkCameraSource::Create(
-    int32_t cameraHandle,
+    const sp<GonkCameraHardware>& aCameraHw,
     Size videoSize,
     int32_t frameRate,
     bool storeMetaDataInVideoBuffers) {
 
-    GonkCameraSource *source = new GonkCameraSource(cameraHandle,
+    GonkCameraSource *source = new GonkCameraSource(aCameraHw,
                     videoSize, frameRate,
                     storeMetaDataInVideoBuffers);
     return source;
 }
 
 GonkCameraSource::GonkCameraSource(
-    int32_t cameraHandle,
+    const sp<GonkCameraHardware>& aCameraHw,
     Size videoSize,
     int32_t frameRate,
     bool storeMetaDataInVideoBuffers)
-    : mCameraFlags(0),
+    : mCameraHw(aCameraHw),
+      mCameraFlags(0),
       mVideoFrameRate(-1),
       mNumFramesReceived(0),
       mLastFrameTimestampUs(0),
       mStarted(false),
       mNumFramesEncoded(0),
       mTimeBetweenFrameCaptureUs(0),
       mFirstFrameTimeUs(0),
       mNumFramesDropped(0),
       mNumGlitches(0),
       mGlitchDurationThresholdUs(200000),
       mCollectStats(false) {
     mVideoSize.width  = -1;
     mVideoSize.height = -1;
 
-    mCameraHandle = cameraHandle;
-
     mInitCheck = init(
                     videoSize, frameRate,
                     storeMetaDataInVideoBuffers);
     if (mInitCheck != OK) releaseCamera();
 }
 
 status_t GonkCameraSource::initCheck() const {
     return mInitCheck;
@@ -305,17 +304,17 @@ status_t GonkCameraSource::configureCame
         isCameraParamChanged = true;
     } else {  // frameRate == -1
         // Do not configure the camera.
         // Use the current frame rate value setting from the camera
     }
 
     if (isCameraParamChanged) {
         // Either frame rate or frame size needs to be changed.
-        if (OK != GonkCameraHardware::PushParameters(mCameraHandle,*params)) {
+        if (OK != mCameraHw->PushParameters(*params)) {
             LOGE("Could not change settings."
                  " Someone else is using camera ?");
             return -EBUSY;
         }
     }
     return OK;
 }
 
@@ -429,45 +428,45 @@ status_t GonkCameraSource::init(
         int32_t frameRate,
         bool storeMetaDataInVideoBuffers) {
 
     LOGV("init");
     status_t err = OK;
     //TODO: need to do something here to check the sanity of camera
 
     CameraParameters params;
-    GonkCameraHardware::PullParameters(mCameraHandle, params);
+    mCameraHw->PullParameters(params);
     if ((err = isCameraColorFormatSupported(params)) != OK) {
         return err;
     }
 
     // Set the camera to use the requested video frame size
     // and/or frame rate.
     if ((err = configureCamera(&params,
                     videoSize.width, videoSize.height,
                     frameRate))) {
         return err;
     }
 
     // Check on video frame size and frame rate.
     CameraParameters newCameraParams;
-    GonkCameraHardware::PullParameters(mCameraHandle, newCameraParams);
+    mCameraHw->PullParameters(newCameraParams);
     if ((err = checkVideoSize(newCameraParams,
                 videoSize.width, videoSize.height)) != OK) {
         return err;
     }
     if ((err = checkFrameRate(newCameraParams, frameRate)) != OK) {
         return err;
     }
 
     // By default, do not store metadata in video buffers
     mIsMetaDataStoredInVideoBuffers = false;
-    GonkCameraHardware::StoreMetaDataInBuffers(mCameraHandle, false);
+    mCameraHw->StoreMetaDataInBuffers(false);
     if (storeMetaDataInVideoBuffers) {
-        if (OK == GonkCameraHardware::StoreMetaDataInBuffers(mCameraHandle, true)) {
+        if (OK == mCameraHw->StoreMetaDataInBuffers(true)) {
             mIsMetaDataStoredInVideoBuffers = true;
         }
     }
 
     const char *hfr_str = params.get("video-hfr");
     int32_t hfr = -1;
     if ( hfr_str != NULL ) {
       hfr = atoi(hfr_str);
@@ -510,17 +509,17 @@ GonkCameraSource::~GonkCameraSource() {
         // Camera's lock is released in this case.
         // TODO: Don't think I need to do this
         releaseCamera();
     }
 }
 
 int GonkCameraSource::startCameraRecording() {
     LOGV("startCameraRecording");
-    return GonkCameraHardware::StartRecording(mCameraHandle);
+    return mCameraHw->StartRecording();
 }
 
 status_t GonkCameraSource::start(MetaData *meta) {
     int rv;
 
     LOGV("start");
     CHECK(!mStarted);
     if (mInitCheck != OK) {
@@ -537,27 +536,27 @@ status_t GonkCameraSource::start(MetaDat
     mStartTimeUs = 0;
     int64_t startTimeUs;
     if (meta && meta->findInt64(kKeyTime, &startTimeUs)) {
         LOGV("Metadata enabled, startime: %lld us", startTimeUs);
         mStartTimeUs = startTimeUs;
     }
 
     // Register a listener with GonkCameraHardware so that we can get callbacks
-    GonkCameraHardware::SetListener(mCameraHandle, new GonkCameraSourceListener(this));
+    mCameraHw->SetListener(new GonkCameraSourceListener(this));
 
     rv = startCameraRecording();
 
     mStarted = (rv == OK);
     return rv;
 }
 
 void GonkCameraSource::stopCameraRecording() {
     LOGV("stopCameraRecording");
-    GonkCameraHardware::StopRecording(mCameraHandle);
+    mCameraHw->StopRecording();
 }
 
 void GonkCameraSource::releaseCamera() {
     LOGV("releaseCamera");
 }
 
 status_t GonkCameraSource::stop() {
     LOGV("stop: E");
@@ -590,17 +589,17 @@ status_t GonkCameraSource::stop() {
 
     CHECK_EQ(mNumFramesReceived, mNumFramesEncoded + mNumFramesDropped);
     LOGV("stop: X");
     return OK;
 }
 
 void GonkCameraSource::releaseRecordingFrame(const sp<IMemory>& frame) {
     LOGV("releaseRecordingFrame");
-    GonkCameraHardware::ReleaseRecordingFrame(mCameraHandle, frame);
+    mCameraHw->ReleaseRecordingFrame(frame);
 }
 
 void GonkCameraSource::releaseQueuedFrames() {
     List<sp<IMemory> >::iterator it;
     while (!mFramesReceived.empty()) {
         it = mFramesReceived.begin();
         releaseRecordingFrame(*it);
         mFramesReceived.erase(it);
--- a/dom/camera/GonkCameraSource.h
+++ b/dom/camera/GonkCameraSource.h
@@ -20,25 +20,27 @@
 
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaSource.h>
 #include <camera/CameraParameters.h>
 #include <utils/List.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
 
+#include "GonkCameraHwMgr.h"
+
 namespace android {
 
 class IMemory;
 class GonkCameraSourceListener;
 
 class GonkCameraSource : public MediaSource, public MediaBufferObserver {
 public:
 
-    static GonkCameraSource *Create(int32_t cameraHandle,
+    static GonkCameraSource *Create(const sp<GonkCameraHardware>& aCameraHw,
                                     Size videoSize,
                                     int32_t frameRate,
                                     bool storeMetaDataInVideoBuffers = false);
 
     virtual ~GonkCameraSource();
 
     virtual status_t start(MetaData *params = NULL);
     virtual status_t stop();
@@ -93,17 +95,17 @@ protected:
     int32_t mNumFramesReceived;
     int64_t mLastFrameTimestampUs;
     bool mStarted;
     int32_t mNumFramesEncoded;
 
     // Time between capture of two frames.
     int64_t mTimeBetweenFrameCaptureUs;
 
-    GonkCameraSource(int32_t cameraHandle,
+    GonkCameraSource(const sp<GonkCameraHardware>& aCameraHw,
                  Size videoSize, int32_t frameRate,
                  bool storeMetaDataInVideoBuffers = false);
 
     virtual int startCameraRecording();
     virtual void stopCameraRecording();
     virtual void releaseRecordingFrame(const sp<IMemory>& frame);
 
     // Returns true if need to skip the current frame.
@@ -127,17 +129,17 @@ private:
     List<int64_t> mFrameTimes;
 
     int64_t mFirstFrameTimeUs;
     int32_t mNumFramesDropped;
     int32_t mNumGlitches;
     int64_t mGlitchDurationThresholdUs;
     bool mCollectStats;
     bool mIsMetaDataStoredInVideoBuffers;
-    int32_t mCameraHandle;
+    sp<GonkCameraHardware> mCameraHw;
 
     void releaseQueuedFrames();
     void releaseOneRecordingFrame(const sp<IMemory>& frame);
 
     status_t init(Size videoSize, int32_t frameRate,
                   bool storeMetaDataInVideoBuffers);
     status_t isCameraColorFormatSupported(const CameraParameters& params);
     status_t configureCamera(CameraParameters* params,