summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorJamie Gennis <jgennis@google.com>2011-07-13 15:13:14 -0700
committerJamie Gennis <jgennis@google.com>2011-07-14 17:48:33 -0700
commit0ed3ec00d0242c9dc77532fe0cf0082645b6662c (patch)
tree26598624682ba4fa9b14e853d286517cba87fd0e /services
parent61c7ef5bde2c7ed94a078396aa65da67b47e5402 (diff)
downloadframeworks_av-0ed3ec00d0242c9dc77532fe0cf0082645b6662c.zip
frameworks_av-0ed3ec00d0242c9dc77532fe0cf0082645b6662c.tar.gz
frameworks_av-0ed3ec00d0242c9dc77532fe0cf0082645b6662c.tar.bz2
CameraService: (dis)connect from preview windows
This change makes CameraService connect and disconnect from preview windows (Surfaces and SurfaceTextures) that get set. Change-Id: I726971688367d5ce0d9aa90c44168037bce33deb
Diffstat (limited to 'services')
-rw-r--r--services/camera/libcameraservice/CameraService.cpp97
-rw-r--r--services/camera/libcameraservice/CameraService.h4
2 files changed, 55 insertions, 46 deletions
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 9b09983..0eff776 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -502,77 +502,82 @@ void CameraService::Client::disconnect() {
// ----------------------------------------------------------------------------
-// set the Surface that the preview will use
-status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) {
- LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());
+static void disconnectWindow(const sp<ANativeWindow>& window) {
+ if (window != 0) {
+ status_t result = native_window_disconnect(window.get(),
+ NATIVE_WINDOW_API_CAMERA);
+ if (result != NO_ERROR) {
+ LOGW("native_window_disconnect failed: %s (%d)", strerror(-result),
+ result);
+ }
+ }
+}
+
+status_t CameraService::Client::setPreviewWindow(const sp<IBinder>& binder,
+ const sp<ANativeWindow>& window) {
Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
- result = NO_ERROR;
-
// return if no change in surface.
- sp<IBinder> binder(surface != 0 ? surface->asBinder() : 0);
if (binder == mSurface) {
- return result;
+ return NO_ERROR;
}
- if (mSurface != 0) {
- LOG1("clearing old preview surface %p", mSurface.get());
+ if (window != 0) {
+ result = native_window_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
+ if (result != NO_ERROR) {
+ LOGE("native_window_connect failed: %s (%d)", strerror(-result),
+ result);
+ return result;
+ }
}
- mSurface = binder;
- mPreviewWindow = surface;
- // If preview has been already started, register preview
- // buffers now.
+ // If preview has been already started, register preview buffers now.
if (mHardware->previewEnabled()) {
- if (mPreviewWindow != 0) {
- native_window_set_buffers_transform(mPreviewWindow.get(),
- mOrientation);
- result = mHardware->setPreviewWindow(mPreviewWindow);
+ if (window != 0) {
+ native_window_set_buffers_transform(window.get(), mOrientation);
+ result = mHardware->setPreviewWindow(window);
}
}
+ if (result == NO_ERROR) {
+ // Everything has succeeded. Disconnect the old window and remember the
+ // new window.
+ disconnectWindow(mPreviewWindow);
+ mSurface = binder;
+ mPreviewWindow = window;
+ } else {
+ // Something went wrong after we connected to the new window, so
+ // disconnect here.
+ disconnectWindow(window);
+ }
+
return result;
}
+// set the Surface that the preview will use
+status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) {
+ LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());
+
+ sp<IBinder> binder(surface != 0 ? surface->asBinder() : 0);
+ sp<ANativeWindow> window(surface);
+ return setPreviewWindow(binder, window);
+}
+
// set the SurfaceTexture that the preview will use
status_t CameraService::Client::setPreviewTexture(
const sp<ISurfaceTexture>& surfaceTexture) {
LOG1("setPreviewTexture(%p) (pid %d)", surfaceTexture.get(),
getCallingPid());
- Mutex::Autolock lock(mLock);
- status_t result = checkPidAndHardware();
- if (result != NO_ERROR) return result;
-
- // return if no change in surface.
- // asBinder() is safe on NULL (returns NULL)
- if (surfaceTexture->asBinder() == mSurface) {
- return result;
- }
- if (mSurface != 0) {
- LOG1("clearing old preview surface %p", mSurface.get());
- }
- mSurface = surfaceTexture->asBinder();
+ sp<IBinder> binder;
+ sp<ANativeWindow> window;
if (surfaceTexture != 0) {
- mPreviewWindow = new SurfaceTextureClient(surfaceTexture);
- } else {
- mPreviewWindow = 0;
- }
-
- // If preview has been already started, set overlay or register preview
- // buffers now.
- if (mHardware->previewEnabled()) {
- // XXX: What if the new preview window is 0?
- if (mPreviewWindow != 0) {
- native_window_set_buffers_transform(mPreviewWindow.get(),
- mOrientation);
- result = mHardware->setPreviewWindow(mPreviewWindow);
- }
+ binder = surfaceTexture->asBinder();
+ window = new SurfaceTextureClient(surfaceTexture);
}
-
- return result;
+ return setPreviewWindow(binder, window);
}
// set the preview callback flag to affect how the received frames from
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 5e2d571..c5fefb8 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -161,6 +161,10 @@ private:
int getOrientation(int orientation, bool mirror);
+ status_t setPreviewWindow(
+ const sp<IBinder>& binder,
+ const sp<ANativeWindow>& window);
+
// these are initialized in the constructor.
sp<CameraService> mCameraService; // immutable after constructor
sp<ICameraClient> mCameraClient;