status_t CameraClient::setPreviewWindow(const sp<IBinder>& binder, const sp<ANativeWindow>& window) { Mutex::Autolock lock(mLock); status_t result = checkPidAndHardware(); if (result != NO_ERROR) return result; // return if no change in surface. if (binder == mSurface) { return NO_ERROR; } if (window != 0) { result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA); if (result != NO_ERROR) { ALOGE("native_window_api_connect failed: %s (%d)", strerror(-result), result); return result; } } // If preview has been already started, register preview buffers now. if (mHardware->previewEnabled()) { if (window != 0) { native_window_set_scaling_mode(window.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); native_window_set_buffers_transform(window.get(), mOrientation); result = mHardware->setPreviewWindow(window); } #ifdef QCOM_HARDWARE #ifndef NO_UPDATE_PREVIEW } else { if (window != 0) { native_window_set_buffers_transform(window.get(), mOrientation); } result = mHardware->setPreviewWindow(window); #endif #endif } 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; }
void CameraClient::disconnect() { int callingPid = getCallingPid(); LOG1("disconnect E (pid %d)", callingPid); Mutex::Autolock lock(mLock); // Allow both client and the media server to disconnect at all times if (callingPid != mClientPid && callingPid != mServicePid) { ALOGW("different client - don't disconnect"); return; } if (mClientPid <= 0) { LOG1("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid); return; } // Make sure disconnect() is done once and once only, whether it is called // from the user directly, or called by the destructor. if (mHardware == 0) return; LOG1("hardware teardown"); // Before destroying mHardware, we must make sure it's in the // idle state. // Turn off all messages. disableMsgType(CAMERA_MSG_ALL_MSGS); mHardware->stopPreview(); mHardware->cancelPicture(); // Release the hardware resources. mHardware->release(); // Release the held ANativeWindow resources. if (mPreviewWindow != 0) { #ifdef QCOM_HARDWARE #ifndef NO_UPDATE_PREVIEW mHardware->setPreviewWindow(0); #endif #endif disconnectWindow(mPreviewWindow); mPreviewWindow = 0; #ifndef QCOM_HARDWARE mHardware->setPreviewWindow(mPreviewWindow); #endif } mHardware.clear(); CameraService::Client::disconnect(); LOG1("disconnect X (pid %d)", callingPid); }
void CameraService::Client::disconnect() { int callingPid = getCallingPid(); LOG1("disconnect E (pid %d)", callingPid); Mutex::Autolock lock(mLock); if (checkPid() != NO_ERROR) { LOGW("different client - don't disconnect"); return; } if (mClientPid <= 0) { LOG1("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid); return; } // Make sure disconnect() is done once and once only, whether it is called // from the user directly, or called by the destructor. if (mHardware == 0) return; LOG1("hardware teardown"); // Before destroying mHardware, we must make sure it's in the // idle state. // Turn off all messages. disableMsgType(CAMERA_MSG_ALL_MSGS); mHardware->stopPreview(); mHardware->cancelPicture(); // Release the hardware resources. mHardware->release(); // Release the held ANativeWindow resources. if (mPreviewWindow != 0) { disconnectWindow(mPreviewWindow); mPreviewWindow = 0; mHardware->setPreviewWindow(mPreviewWindow); } mHardware.clear(); mCameraService->removeClient(mCameraClient); mCameraService->setCameraFree(mCameraId); LOG1("disconnect X (pid %d)", callingPid); }