Code drop from //branches/cupcake/...@124589
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
index 1528e6e..9527009 100644
--- a/libs/ui/Camera.cpp
+++ b/libs/ui/Camera.cpp
@@ -1,28 +1,28 @@
 /*
 **
-** Copyright 2008, The Android Open Source Project
+** Copyright (C) 2008, The Android Open Source Project
+** Copyright (C) 2008 HTC Inc.
 **
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
 **
-**     http://www.apache.org/licenses/LICENSE-2.0 
+**     http://www.apache.org/licenses/LICENSE-2.0
 **
-** 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 
+** 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.
 */
 
+//#define LOG_NDEBUG 0
 #define LOG_TAG "Camera"
 #include <utils/Log.h>
-
 #include <utils/IServiceManager.h>
 #include <utils/threads.h>
 #include <utils/IMemory.h>
 #include <ui/Surface.h>
-
 #include <ui/Camera.h>
 #include <ui/ICameraService.h>
 
@@ -60,20 +60,36 @@
 // ---------------------------------------------------------------------------
 
 Camera::Camera()
-      : mStatus(UNKNOWN_ERROR),
-        mShutterCallback(0),
-        mShutterCallbackCookie(0),
-        mRawCallback(0),
-        mRawCallbackCookie(0),
-        mJpegCallback(0),
-        mJpegCallbackCookie(0),
-        mFrameCallback(0),
-        mFrameCallbackCookie(0),
-        mErrorCallback(0),
-        mErrorCallbackCookie(0),
-        mAutoFocusCallback(0),
-        mAutoFocusCallbackCookie(0)
 {
+    init();
+}
+
+Camera::Camera(const sp<ICamera>& camera)
+{
+    init();
+    // connect this client to existing camera remote
+    if (camera->connect(this) == NO_ERROR) {
+        mStatus = NO_ERROR;
+        mCamera = camera;
+        camera->asBinder()->linkToDeath(this);
+    }
+}
+
+void Camera::init()
+{
+    mStatus = UNKNOWN_ERROR;
+    mShutterCallback = 0;
+    mShutterCallbackCookie = 0;
+    mRawCallback = 0;
+    mRawCallbackCookie = 0;
+    mJpegCallback = 0;
+    mJpegCallbackCookie = 0;
+    mFrameCallback = 0;
+    mFrameCallbackCookie = 0;
+    mErrorCallback = 0;
+    mErrorCallbackCookie = 0;
+    mAutoFocusCallback = 0;
+    mAutoFocusCallbackCookie = 0;
 }
 
 Camera::~Camera()
@@ -83,6 +99,7 @@
 
 sp<Camera> Camera::connect()
 {
+    LOGV("connect");
     sp<Camera> c = new Camera();
     const sp<ICameraService>& cs = getCameraService();
     if (cs != 0) {
@@ -97,6 +114,7 @@
 
 void Camera::disconnect()
 {
+    LOGV("disconnect");
     if (mCamera != 0) {
         mErrorCallback = 0;
         mCamera->disconnect();
@@ -104,9 +122,24 @@
     }
 }
 
+status_t Camera::reconnect()
+{
+    LOGV("reconnect");
+    if (mCamera != 0) {
+        return mCamera->connect(this);
+    }
+    return NO_INIT;
+}
+
+sp<ICamera> Camera::remote()
+{
+    return mCamera;
+}
+
 // pass the buffered ISurface to the camera service
 status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
 {
+    LOGV("setPreviewDisplay");
     if (surface == 0) {
         LOGE("app passed NULL surface");
         return NO_INIT;
@@ -114,81 +147,105 @@
     return mCamera->setPreviewDisplay(surface->getISurface());
 }
 
+status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
+{
+    LOGV("setPreviewDisplay");
+    if (surface == 0) {
+        LOGE("app passed NULL surface");
+        return NO_INIT;
+    }
+    return mCamera->setPreviewDisplay(surface);
+}
+
+
 // start preview mode, must call setPreviewDisplay first
 status_t Camera::startPreview()
 {
+    LOGV("startPreview");
     return mCamera->startPreview();
 }
 
 // stop preview mode
 void Camera::stopPreview()
 {
+    LOGV("stopPreview");
     mCamera->stopPreview();
 }
 
 status_t Camera::autoFocus()
 {
+    LOGV("autoFocus");
     return mCamera->autoFocus();
 }
 
 // take a picture
 status_t Camera::takePicture()
 {
+    LOGV("takePicture");
     return mCamera->takePicture();
 }
 
 // set preview/capture parameters - key/value pairs
 status_t Camera::setParameters(const String8& params)
 {
+    LOGV("setParameters");
     return mCamera->setParameters(params);
 }
 
 // get preview/capture parameters - key/value pairs
 String8 Camera::getParameters() const
 {
+    LOGV("getParameters");
     String8 params = mCamera->getParameters();
     return params;
 }
 
 void Camera::setAutoFocusCallback(autofocus_callback cb, void *cookie)
 {
+    LOGV("setAutoFocusCallback");
     mAutoFocusCallback = cb;
     mAutoFocusCallbackCookie = cookie;
 }
 
 void Camera::setShutterCallback(shutter_callback cb, void *cookie)
 {
+    LOGV("setShutterCallback");
     mShutterCallback = cb;
     mShutterCallbackCookie = cookie;
 }
 
 void Camera::setRawCallback(frame_callback cb, void *cookie)
 {
+    LOGV("setRawCallback");
     mRawCallback = cb;
     mRawCallbackCookie = cookie;
 }
 
 void Camera::setJpegCallback(frame_callback cb, void *cookie)
 {
+    LOGV("setJpegCallback");
     mJpegCallback = cb;
     mJpegCallbackCookie = cookie;
 }
 
-void Camera::setFrameCallback(frame_callback cb, void *cookie)
+void Camera::setFrameCallback(frame_callback cb, void *cookie, int frame_callback_flag)
 {
+    LOGV("setFrameCallback");
     mFrameCallback = cb;
     mFrameCallbackCookie = cookie;
-    mCamera->setHasFrameCallback(cb != NULL);
+    mCamera->setFrameCallbackFlag(frame_callback_flag);
 }
 
 void Camera::setErrorCallback(error_callback cb, void *cookie)
 {
+    LOGV("setErrorCallback");
     mErrorCallback = cb;
     mErrorCallbackCookie = cookie;
 }
 
 void Camera::autoFocusCallback(bool focused)
 {
+    LOGV("autoFocusCallback");
     if (mAutoFocusCallback) {
         mAutoFocusCallback(focused, mAutoFocusCallbackCookie);
     }
@@ -196,6 +253,7 @@
 
 void Camera::shutterCallback()
 {
+    LOGV("shutterCallback");
     if (mShutterCallback) {
         mShutterCallback(mShutterCallbackCookie);
     }
@@ -203,6 +261,7 @@
 
 void Camera::rawCallback(const sp<IMemory>& picture)
 {
+    LOGV("rawCallback");
     if (mRawCallback) {
         mRawCallback(picture, mRawCallbackCookie);
     }
@@ -211,6 +270,7 @@
 // callback from camera service when image is ready
 void Camera::jpegCallback(const sp<IMemory>& picture)
 {
+    LOGV("jpegCallback");
     if (mJpegCallback) {
         mJpegCallback(picture, mJpegCallbackCookie);
     }
@@ -219,6 +279,7 @@
 // callback from camera service when video frame is ready
 void Camera::frameCallback(const sp<IMemory>& frame)
 {
+    LOGV("frameCallback");
     if (mFrameCallback) {
         mFrameCallback(frame, mFrameCallbackCookie);
     }
@@ -227,19 +288,21 @@
 // callback from camera service when an error occurs in preview or takePicture
 void Camera::errorCallback(status_t error)
 {
+    LOGV("errorCallback");
     if (mErrorCallback) {
         mErrorCallback(error, mErrorCallbackCookie);
     }
 }
 
-void Camera::binderDied(const wp<IBinder>& who) {    
+void Camera::binderDied(const wp<IBinder>& who) {
     LOGW("ICamera died");
     if (mErrorCallback) {
         mErrorCallback(DEAD_OBJECT, mErrorCallbackCookie);
     }
 }
 
-void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {    
+void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
+    LOGV("binderDied");
     Mutex::Autolock _l(Camera::mLock);
     Camera::mCameraService.clear();
     LOGW("Camera server died!");