void CameraControlImpl::OnHardwareStateChange(CameraControlListener::HardwareState aNewState, nsresult aReason) { // This callback can run on threads other than the Main Thread and // the Camera Thread. On Gonk, it may be called from the camera's // local binder thread, should the mediaserver process die. MutexAutoLock lock(mListenerLock); if (aNewState == mHardwareState) { DOM_CAMERA_LOGI("OnHardwareStateChange: state did not change from %d\n", mHardwareState); return; } const char* state[] = { "uninitialized", "closed", "open", "failed" }; MOZ_ASSERT(aNewState >= 0); if (static_cast<unsigned int>(aNewState) < sizeof(state) / sizeof(state[0])) { DOM_CAMERA_LOGI("New hardware state is '%s' (reason=0x%x)\n", state[aNewState], aReason); } else { DOM_CAMERA_LOGE("OnHardwareStateChange: got invalid HardwareState value %d\n", aNewState); } mHardwareState = aNewState; mHardwareStateChangeReason = aReason; for (uint32_t i = 0; i < mListeners.Length(); ++i) { CameraControlListener* l = mListeners[i]; l->OnHardwareStateChange(mHardwareState, mHardwareStateChangeReason); } }
void CameraControlImpl::OnPreviewStateChange(CameraControlListener::PreviewState aNewState) { // This callback runs on the Main Thread and the Camera Thread, and // may run on the local binder thread, should the mediaserver // process die. MutexAutoLock lock(mListenerLock); if (aNewState == mPreviewState) { DOM_CAMERA_LOGI("OnPreviewStateChange: state did not change from %d\n", mPreviewState); return; } const char* state[] = { "stopped", "paused", "started" }; MOZ_ASSERT(aNewState >= 0); if (static_cast<unsigned int>(aNewState) < sizeof(state) / sizeof(state[0])) { DOM_CAMERA_LOGI("New preview state is '%s'\n", state[aNewState]); } else { DOM_CAMERA_LOGE("OnPreviewStateChange: got unknown PreviewState value %d\n", aNewState); } mPreviewState = aNewState; for (uint32_t i = 0; i < mListeners.Length(); ++i) { CameraControlListener* l = mListeners[i]; l->OnPreviewStateChange(mPreviewState); } }
void CameraControlImpl::OnSystemError(CameraControlListener::SystemContext aContext, nsresult aError) { // This callback can run on threads other than the Main Thread and // the Camera Thread. RwLockAutoEnterRead lock(mListenerLock); #ifdef PR_LOGGING const char* context[] = { "Camera Service" }; if (static_cast<size_t>(aContext) < sizeof(context) / sizeof(context[0])) { DOM_CAMERA_LOGW("CameraControlImpl::OnSystemError : aContext='%s' (%d), aError=0x%x\n", context[aContext], aContext, aError); } else { DOM_CAMERA_LOGE("CameraControlImpl::OnSystemError : aContext=%d, aError=0x%x\n", aContext, aError); } #endif for (uint32_t i = 0; i < mListeners.Length(); ++i) { CameraControlListener* l = mListeners[i]; l->OnSystemError(aContext, aError); } }
void CameraControlImpl::OnAutoFocusMoving(bool aIsMoving) { MutexAutoLock lock(mListenerLock); for (uint32_t i = 0; i < mListeners.Length(); ++i) { CameraControlListener* l = mListeners[i]; l->OnAutoFocusMoving(aIsMoving); } }
void CameraControlImpl::OnClosed() { // This callback can run on threads other than the Main Thread and // the Camera Thread. RwLockAutoEnterRead lock(mListenerLock); for (uint32_t i = 0; i < mListeners.Length(); ++i) { CameraControlListener* l = mListeners[i]; l->OnHardwareStateChange(CameraControlListener::kHardwareClosed); } }
void CameraControlImpl::OnPoster(dom::BlobImpl* aBlobImpl) { // This callback can run on threads other than the Main Thread and // the Camera Thread. MutexAutoLock lock(mListenerLock); for (uint32_t i = 0; i < mListeners.Length(); ++i) { CameraControlListener* l = mListeners[i]; l->OnPoster(aBlobImpl); } }
void CameraControlImpl::OnTakePictureComplete(const uint8_t* aData, uint32_t aLength, const nsAString& aMimeType) { // This callback can run on threads other than the Main Thread and // the Camera Thread. On Gonk, it is called from the camera // library's snapshot thread. MutexAutoLock lock(mListenerLock); for (uint32_t i = 0; i < mListeners.Length(); ++i) { CameraControlListener* l = mListeners[i]; l->OnTakePictureComplete(aData, aLength, aMimeType); } }
void CameraControlImpl::OnFacesDetected(const nsTArray<Face>& aFaces) { // This callback can run on threads other than the Main Thread and // the Camera Thread. On Gonk, it is called from the camera // library's face detection thread. MutexAutoLock lock(mListenerLock); for (uint32_t i = 0; i < mListeners.Length(); ++i) { CameraControlListener* l = mListeners[i]; l->OnFacesDetected(aFaces); } }
void CameraControlImpl::OnAutoFocusComplete(bool aAutoFocusSucceeded) { // This callback can run on threads other than the Main Thread and // the Camera Thread. On Gonk, it is called from the camera // library's auto focus thread. MutexAutoLock lock(mListenerLock); for (uint32_t i = 0; i < mListeners.Length(); ++i) { CameraControlListener* l = mListeners[i]; l->OnAutoFocusComplete(aAutoFocusSucceeded); } }
void CameraControlImpl::OnConfigurationChange() { MOZ_ASSERT(NS_GetCurrentThread() == mCameraThread); MutexAutoLock lock(mListenerLock); DOM_CAMERA_LOGI("OnConfigurationChange : %zu listeners\n", mListeners.Length()); for (uint32_t i = 0; i < mListeners.Length(); ++i) { CameraControlListener* l = mListeners[i]; l->OnConfigurationChange(mCurrentConfiguration); } }
void CameraControlImpl::AddListenerImpl(already_AddRefed<CameraControlListener> aListener) { MutexAutoLock lock(mListenerLock); CameraControlListener* l = *mListeners.AppendElement() = aListener; DOM_CAMERA_LOGI("Added camera control listener %p\n", l); // Update the newly-added listener's state l->OnConfigurationChange(mCurrentConfiguration); l->OnHardwareStateChange(mHardwareState, mHardwareStateChangeReason); l->OnPreviewStateChange(mPreviewState); }
void CameraControlImpl::OnShutter() { // This callback can run on threads other than the Main Thread and // the Camera Thread. On Gonk, it is called from the camera driver's // preview thread. MutexAutoLock lock(mListenerLock); for (uint32_t i = 0; i < mListeners.Length(); ++i) { CameraControlListener* l = mListeners[i]; l->OnShutter(); } }
void CameraControlImpl::OnRateLimitPreview(bool aLimit) { // This function runs on neither the Main Thread nor the Camera Thread. MutexAutoLock lock(mListenerLock); DOM_CAMERA_LOGI("OnRateLimitPreview: %d\n", aLimit); for (uint32_t i = 0; i < mListeners.Length(); ++i) { CameraControlListener* l = mListeners[i]; l->OnRateLimitPreview(aLimit); } }
void CameraControlImpl::OnRecorderStateChange(CameraControlListener::RecorderState aState, int32_t aStatus, int32_t aTrackNumber) { // This callback can run on threads other than the Main Thread and // the Camera Thread. On Gonk, it is called from the media encoder // thread. MutexAutoLock lock(mListenerLock); for (uint32_t i = 0; i < mListeners.Length(); ++i) { CameraControlListener* l = mListeners[i]; l->OnRecorderStateChange(aState, aStatus, aTrackNumber); } }
void CameraControlImpl::OnError(CameraControlListener::CameraErrorContext aContext, CameraControlListener::CameraError aError) { // This callback can run on threads other than the Main Thread and // the Camera Thread. RwLockAutoEnterRead lock(mListenerLock); #ifdef PR_LOGGING const char* error[] = { "api-failed", "init-failed", "invalid-configuration", "service-failed", "set-picture-size-failred", "set-thumbnail-size-failed", "unknown" }; const char* context[] = { "StartCamera", "StopCamera", "AutoFocus", "TakePicture", "StartRecording", "StopRecording", "SetConfiguration", "StartPreview", "StopPreview", "Unspecified" }; if (static_cast<unsigned int>(aError) < sizeof(error) / sizeof(error[0]) && static_cast<unsigned int>(aContext) < sizeof(context) / sizeof(context[0])) { DOM_CAMERA_LOGW("CameraControlImpl::OnError : aContext='%s' (%u), aError='%s' (%u)\n", context[aContext], aContext, error[aError], aError); } else { DOM_CAMERA_LOGE("CameraControlImpl::OnError : aContext=%u, aError=%d\n", aContext, aError); } #endif for (uint32_t i = 0; i < mListeners.Length(); ++i) { CameraControlListener* l = mListeners[i]; l->OnError(aContext, aError); } }
bool CameraControlImpl::OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight) { // This function runs on neither the Main Thread nor the Camera Thread. // On Gonk, it is called from the camera driver's preview thread. MutexAutoLock lock(mListenerLock); DOM_CAMERA_LOGI("OnNewPreviewFrame: we have %zu preview frame listener(s)\n", mListeners.Length()); bool consumed = false; for (uint32_t i = 0; i < mListeners.Length(); ++i) { CameraControlListener* l = mListeners[i]; consumed = l->OnNewPreviewFrame(aImage, aWidth, aHeight) || consumed; } return consumed; }
void CameraControlImpl::OnUserError(CameraControlListener::UserContext aContext, nsresult aError) { // This callback can run on threads other than the Main Thread and // the Camera Thread. MutexAutoLock lock(mListenerLock); const char* context[] = { "StartCamera", "StopCamera", "AutoFocus", "StartFaceDetection", "StopFaceDetection", "TakePicture", "StartRecording", "StopRecording", "PauseRecording", "ResumeRecording", "SetConfiguration", "StartPreview", "StopPreview", "SetPictureSize", "SetThumbnailSize", "ResumeContinuousFocus", "Unspecified" }; if (static_cast<size_t>(aContext) < sizeof(context) / sizeof(context[0])) { DOM_CAMERA_LOGW("CameraControlImpl::OnUserError : aContext='%s' (%d), aError=0x%x\n", context[aContext], aContext, aError); } else { DOM_CAMERA_LOGE("CameraControlImpl::OnUserError : aContext=%d, aError=0x%x\n", aContext, aError); } for (uint32_t i = 0; i < mListeners.Length(); ++i) { CameraControlListener* l = mListeners[i]; l->OnUserError(aContext, aError); } }