diff options
author | zork <zork@chromium.org> | 2015-05-14 13:39:29 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-05-14 20:39:31 +0000 |
commit | 6c3c6032ca10259fcc749cc7da3ea20629dcb85b (patch) | |
tree | 3fa6ab15e35a739f5fe28e0a00aeb6762721dc82 /extensions/browser/api/webcam_private | |
parent | d540b4c265392b42bbf4f713c08775eb3f397159 (diff) | |
download | chromium_src-6c3c6032ca10259fcc749cc7da3ea20629dcb85b.zip chromium_src-6c3c6032ca10259fcc749cc7da3ea20629dcb85b.tar.gz chromium_src-6c3c6032ca10259fcc749cc7da3ea20629dcb85b.tar.bz2 |
Move V4L2 code into a webcam helper class.
This will make it simpler to add new webcam interface types.
BUG=None
Review URL: https://codereview.chromium.org/1136883004
Cr-Commit-Position: refs/heads/master@{#329922}
Diffstat (limited to 'extensions/browser/api/webcam_private')
6 files changed, 447 insertions, 120 deletions
diff --git a/extensions/browser/api/webcam_private/v4l2_webcam.cc b/extensions/browser/api/webcam_private/v4l2_webcam.cc new file mode 100644 index 0000000..f6d53c5 --- /dev/null +++ b/extensions/browser/api/webcam_private/v4l2_webcam.cc @@ -0,0 +1,172 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/api/webcam_private/v4l2_webcam.h" + +#include <fcntl.h> +#include <linux/uvcvideo.h> +#include <linux/videodev2.h> +#include <stdio.h> +#include <sys/ioctl.h> +#include <unistd.h> + +#include "base/posix/eintr_wrapper.h" + +#define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE+32) +#define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE+33) +#define V4L2_CID_PANTILT_CMD (V4L2_CID_CAMERA_CLASS_BASE+34) + +// GUID of the Extension Unit for Logitech CC3300e motor control: +// {212de5ff-3080-2c4e-82d9-f587d00540bd} +#define UVC_GUID_LOGITECH_CC3000E_MOTORS \ + {0x21, 0x2d, 0xe5, 0xff, 0x30, 0x80, 0x2c, 0x4e, \ + 0x82, 0xd9, 0xf5, 0x87, 0xd0, 0x05, 0x40, 0xbd} + +#define LOGITECH_MOTORCONTROL_PANTILT_CMD 2 + +namespace { +const int kLogitechMenuIndexGoHome = 2; + +const uvc_menu_info kLogitechCmdMenu[] = { + {1, "Set Preset"}, {2, "Get Preset"}, {3, "Go Home"} +}; + +const uvc_xu_control_mapping kLogitechCmdMapping = { + V4L2_CID_PANTILT_CMD, + "Pan/Tilt Go", + UVC_GUID_LOGITECH_CC3000E_MOTORS, + LOGITECH_MOTORCONTROL_PANTILT_CMD, + 8, + 0, + V4L2_CTRL_TYPE_MENU, + UVC_CTRL_DATA_TYPE_ENUM, + const_cast<uvc_menu_info*>(&kLogitechCmdMenu[0]), + arraysize(kLogitechCmdMenu), +}; +} // namespace + +namespace extensions { + +V4L2Webcam::V4L2Webcam(const std::string& device_id) : device_id_(device_id) { +} + +V4L2Webcam::~V4L2Webcam() { +} + +bool V4L2Webcam::Open() { + fd_.reset(HANDLE_EINTR(open(device_id_.c_str(), 0))); + return fd_.is_valid(); +} + +bool V4L2Webcam::EnsureLogitechCommandsMapped() { + int res = + HANDLE_EINTR(ioctl(fd_.get(), UVCIOC_CTRL_MAP, &kLogitechCmdMapping)); + // If mapping is successful or it's already mapped, this is a Logitech + // camera. + // NOTE: On success, occasionally EFAULT is returned. On a real error, + // ENOMEM, EPERM, EINVAL, or EOVERFLOW should be returned. + return res >= 0 || errno == EEXIST || errno == EFAULT; +} + +bool V4L2Webcam::SetWebcamParameter(int fd, uint32_t control_id, int value) { + struct v4l2_control v4l2_ctrl = {control_id, value}; + int res = HANDLE_EINTR(ioctl(fd, VIDIOC_S_CTRL, &v4l2_ctrl)) >= 0; + return res >= 0; +} + +bool V4L2Webcam::GetWebcamParameter(int fd, uint32_t control_id, int* value) { + struct v4l2_control v4l2_ctrl = {control_id}; + + if (HANDLE_EINTR(ioctl(fd, VIDIOC_G_CTRL, &v4l2_ctrl))) + return false; + + *value = v4l2_ctrl.value; + return true; +} + +void V4L2Webcam::Reset(bool pan, bool tilt, bool zoom) { + if (pan || tilt) { + if (EnsureLogitechCommandsMapped()) { + SetWebcamParameter(fd_.get(), V4L2_CID_PANTILT_CMD, + kLogitechMenuIndexGoHome); + } else { + if (pan) { + struct v4l2_control v4l2_ctrl = {V4L2_CID_PAN_RESET}; + HANDLE_EINTR(ioctl(fd_.get(), VIDIOC_S_CTRL, &v4l2_ctrl)); + } + + if (tilt) { + struct v4l2_control v4l2_ctrl = {V4L2_CID_TILT_RESET}; + HANDLE_EINTR(ioctl(fd_.get(), VIDIOC_S_CTRL, &v4l2_ctrl)); + } + } + } + + if (zoom) { + const int kDefaultZoom = 100; + SetWebcamParameter(fd_.get(), V4L2_CID_ZOOM_ABSOLUTE, kDefaultZoom); + } +} + +bool V4L2Webcam::GetPan(int* value) { + return GetWebcamParameter(fd_.get(), V4L2_CID_PAN_ABSOLUTE, value); +} + +bool V4L2Webcam::GetTilt(int* value) { + return GetWebcamParameter(fd_.get(), V4L2_CID_TILT_ABSOLUTE, value); +} + +bool V4L2Webcam::GetZoom(int* value) { + return GetWebcamParameter(fd_.get(), V4L2_CID_ZOOM_ABSOLUTE, value); +} + +bool V4L2Webcam::SetPan(int value) { + return SetWebcamParameter(fd_.get(), V4L2_CID_PAN_ABSOLUTE, value); +} + +bool V4L2Webcam::SetTilt(int value) { + return SetWebcamParameter(fd_.get(), V4L2_CID_TILT_ABSOLUTE, value); +} + +bool V4L2Webcam::SetZoom(int value) { + return SetWebcamParameter(fd_.get(), V4L2_CID_ZOOM_ABSOLUTE, value); +} + +bool V4L2Webcam::SetPanDirection(PanDirection direction) { + int direction_value = 0; + switch (direction) { + case PAN_STOP: + direction_value = 0; + break; + + case PAN_RIGHT: + direction_value = 1; + break; + + case PAN_LEFT: + direction_value = -1; + break; + } + return SetWebcamParameter(fd_.get(), V4L2_CID_PAN_SPEED, direction_value); +} + +bool V4L2Webcam::SetTiltDirection(TiltDirection direction) { + int direction_value = 0; + switch (direction) { + case TILT_STOP: + direction_value = 0; + break; + + case TILT_UP: + direction_value = 1; + break; + + case TILT_DOWN: + direction_value = -1; + break; + } + return SetWebcamParameter(fd_.get(), V4L2_CID_TILT_SPEED, direction_value); +} + +} // namespace extensions diff --git a/extensions/browser/api/webcam_private/v4l2_webcam.h b/extensions/browser/api/webcam_private/v4l2_webcam.h new file mode 100644 index 0000000..53efcfc --- /dev/null +++ b/extensions/browser/api/webcam_private/v4l2_webcam.h @@ -0,0 +1,46 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_BROWSER_API_WEBCAM_PRIVATE_V4L2_WEBCAM_H_ +#define EXTENSIONS_BROWSER_API_WEBCAM_PRIVATE_V4L2_WEBCAM_H_ + +#include "extensions/browser/api/webcam_private/webcam.h" + +#include "base/files/scoped_file.h" + +namespace extensions { + +class V4L2Webcam : public Webcam { + public: + V4L2Webcam(const std::string& device_id); + ~V4L2Webcam() override; + + bool Open(); + + private: + bool EnsureLogitechCommandsMapped(); + bool SetWebcamParameter(int fd, uint32_t control_id, int value); + bool GetWebcamParameter(int fd, uint32_t control_id, int* value); + + // Webcam: + void Reset(bool pan, bool tilt, bool zoom) override; + bool GetPan(int* value) override; + bool GetTilt(int* value) override; + bool GetZoom(int* value) override; + bool SetPan(int value) override; + bool SetTilt(int value) override; + bool SetZoom(int value) override; + bool SetPanDirection(PanDirection direction) override; + bool SetTiltDirection(TiltDirection direction) override; + + const std::string device_id_; + base::ScopedFD fd_; + + DISALLOW_COPY_AND_ASSIGN(V4L2Webcam); +}; + + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_API_WEBCAM_PRIVATE_V4L2_WEBCAM_H_ diff --git a/extensions/browser/api/webcam_private/webcam.cc b/extensions/browser/api/webcam_private/webcam.cc new file mode 100644 index 0000000..79b6510 --- /dev/null +++ b/extensions/browser/api/webcam_private/webcam.cc @@ -0,0 +1,12 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/api/webcam_private/webcam.h" + +namespace extensions { + +Webcam::Webcam() {} +Webcam::~Webcam() {} + +} // namespace extensions diff --git a/extensions/browser/api/webcam_private/webcam.h b/extensions/browser/api/webcam_private/webcam.h new file mode 100644 index 0000000..c85e75f --- /dev/null +++ b/extensions/browser/api/webcam_private/webcam.h @@ -0,0 +1,62 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_BROWSER_API_WEBCAM_PRIVATE_WEBCAM_H_ +#define EXTENSIONS_BROWSER_API_WEBCAM_PRIVATE_WEBCAM_H_ + +#include <set> +#include <string> + +#include "base/macros.h" + +namespace extensions { + +class Webcam { + public: + enum PanDirection { + PAN_LEFT, + PAN_RIGHT, + PAN_STOP, + }; + + enum TiltDirection { + TILT_UP, + TILT_DOWN, + TILT_STOP, + }; + + Webcam(); + virtual ~Webcam(); + + virtual void Reset(bool pan, bool tilt, bool zoom) = 0; + virtual bool GetPan(int* value) = 0; + virtual bool GetTilt(int* value) = 0; + virtual bool GetZoom(int* value) = 0; + virtual bool SetPan(int value) = 0; + virtual bool SetTilt(int value) = 0; + virtual bool SetZoom(int value) = 0; + virtual bool SetPanDirection(PanDirection direction) = 0; + virtual bool SetTiltDirection(TiltDirection direction) = 0; + + void AddExtensionRef(const std::string& extension_id) { + extension_refs_.insert(extension_id); + } + + void RemoveExtensionRef(const std::string& extension_id) { + extension_refs_.erase(extension_id); + } + + bool ShouldDelete() { + return extension_refs_.empty(); + } + + private: + std::set<std::string> extension_refs_; + + DISALLOW_COPY_AND_ASSIGN(Webcam); +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_API_WEBCAM_PRIVATE_WEBCAM_H_ diff --git a/extensions/browser/api/webcam_private/webcam_private_api.h b/extensions/browser/api/webcam_private/webcam_private_api.h index c4cef37..3c64e6c8 100644 --- a/extensions/browser/api/webcam_private/webcam_private_api.h +++ b/extensions/browser/api/webcam_private/webcam_private_api.h @@ -5,12 +5,65 @@ #ifndef EXTENSIONS_BROWSER_API_WEBCAM_PRIVATE_WEBCAM_PRIVATE_API_H_ #define EXTENSIONS_BROWSER_API_WEBCAM_PRIVATE_WEBCAM_PRIVATE_API_H_ +#include <map> + +#include "base/memory/scoped_ptr.h" +#include "base/scoped_observer.h" +#include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/extension_function.h" +#include "extensions/browser/process_manager_observer.h" class Profile; namespace extensions { +class ProcessManager; +class Webcam; + +class WebcamPrivateAPI : public BrowserContextKeyedAPI, + public ProcessManagerObserver { + public: + static BrowserContextKeyedAPIFactory<WebcamPrivateAPI>* GetFactoryInstance(); + + // Convenience method to get the WebcamPrivateAPI for a BrowserContext. + static WebcamPrivateAPI* Get(content::BrowserContext* context); + + explicit WebcamPrivateAPI(content::BrowserContext* context); + ~WebcamPrivateAPI() override; + + Webcam* GetWebcam(const std::string& extension_id, + const std::string& webcam_id); + + private: + friend class BrowserContextKeyedAPIFactory<WebcamPrivateAPI>; + + bool GetDeviceId(const std::string& extension_id, + const std::string& webcam_id, + std::string* device_id); + + // ProcessManagerObserver: + void OnBackgroundHostClose(const std::string& extension_id) override; + + // BrowserContextKeyedAPI: + static const char* service_name() { + return "WebcamPrivateAPI"; + } + static const bool kServiceIsNULLWhileTesting = true; + static const bool kServiceRedirectedInIncognito = true; + + content::BrowserContext* const browser_context_; + ScopedObserver<ProcessManager, ProcessManagerObserver> + process_manager_observer_; + + std::map<std::string, linked_ptr<Webcam>> webcams_; + + base::WeakPtrFactory<WebcamPrivateAPI> weak_ptr_factory_; +}; + +template <> +void BrowserContextKeyedAPIFactory<WebcamPrivateAPI> + ::DeclareFactoryDependencies(); + class WebcamPrivateSetFunction : public SyncExtensionFunction { public: WebcamPrivateSetFunction(); diff --git a/extensions/browser/api/webcam_private/webcam_private_api_chromeos.cc b/extensions/browser/api/webcam_private/webcam_private_api_chromeos.cc index 765c778..4b0f0d3 100644 --- a/extensions/browser/api/webcam_private/webcam_private_api_chromeos.cc +++ b/extensions/browser/api/webcam_private/webcam_private_api_chromeos.cc @@ -4,33 +4,17 @@ #include "extensions/browser/api/webcam_private/webcam_private_api.h" -#include <fcntl.h> -#include <linux/uvcvideo.h> -#include <linux/videodev2.h> -#include <stdio.h> -#include <sys/ioctl.h> -#include <unistd.h> - -#include "base/files/scoped_file.h" -#include "base/posix/eintr_wrapper.h" +#include "base/lazy_instance.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/media_device_id.h" #include "content/public/browser/resource_context.h" #include "content/public/common/media_stream_request.h" +#include "extensions/browser/api/webcam_private/v4l2_webcam.h" +#include "extensions/browser/api/webcam_private/webcam.h" +#include "extensions/browser/process_manager.h" +#include "extensions/browser/process_manager_factory.h" #include "extensions/common/api/webcam_private.h" -#define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE+32) -#define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE+33) -#define V4L2_CID_PANTILT_CMD (V4L2_CID_CAMERA_CLASS_BASE+34) - -// GUID of the Extension Unit for Logitech CC3300e motor control: -// {212de5ff-3080-2c4e-82d9-f587d00540bd} -#define UVC_GUID_LOGITECH_CC3000E_MOTORS \ - {0x21, 0x2d, 0xe5, 0xff, 0x30, 0x80, 0x2c, 0x4e, \ - 0x82, 0xd9, 0xf5, 0x87, 0xd0, 0x05, 0x40, 0xbd} - -#define LOGITECH_MOTORCONTROL_PANTILT_CMD 2 - namespace webcam_private = extensions::core_api::webcam_private; namespace content { @@ -38,70 +22,75 @@ class BrowserContext; } // namespace content namespace { -const int kLogitechMenuIndexGoHome = 2; - -const uvc_menu_info kLogitechCmdMenu[] = { - {1, "Set Preset"}, {2, "Get Preset"}, {3, "Go Home"} -}; - -const uvc_xu_control_mapping kLogitechCmdMapping = { - V4L2_CID_PANTILT_CMD, - "Pan/Tilt Go", - UVC_GUID_LOGITECH_CC3000E_MOTORS, - LOGITECH_MOTORCONTROL_PANTILT_CMD, - 8, - 0, - V4L2_CTRL_TYPE_MENU, - UVC_CTRL_DATA_TYPE_ENUM, - const_cast<uvc_menu_info*>(&kLogitechCmdMenu[0]), - arraysize(kLogitechCmdMenu), -}; - -base::ScopedFD OpenWebcam(const std::string& extension_id, - content::BrowserContext* browser_context, - const std::string& webcam_id) { - GURL security_origin = - extensions::Extension::GetBaseURLFromExtensionId(extension_id); - - std::string device_id; - bool success = content::GetMediaDeviceIDForHMAC( - content::MEDIA_DEVICE_VIDEO_CAPTURE, - browser_context->GetResourceContext()->GetMediaDeviceIDSalt(), - security_origin, - webcam_id, - &device_id); +const char kUnknownWebcam[] = "Unknown webcam id"; +} // namespace - if (!success) - return base::ScopedFD(); +namespace extensions { - return base::ScopedFD(HANDLE_EINTR(open(device_id.c_str(), 0))); +// static +WebcamPrivateAPI* WebcamPrivateAPI::Get(content::BrowserContext* context) { + return GetFactoryInstance()->Get(context); } -void SetWebcamParameter(int fd, uint32_t control_id, int value) { - struct v4l2_control v4l2_ctrl = {control_id, value}; - HANDLE_EINTR(ioctl(fd, VIDIOC_S_CTRL, &v4l2_ctrl)); +WebcamPrivateAPI::WebcamPrivateAPI(content::BrowserContext* context) + : browser_context_(context), + process_manager_observer_(this), + weak_ptr_factory_(this) { + process_manager_observer_.Add(ProcessManager::Get(browser_context_)); } -bool GetWebcamParameter(int fd, uint32_t control_id, int* value) { - struct v4l2_control v4l2_ctrl = {control_id}; +WebcamPrivateAPI::~WebcamPrivateAPI() {} - if (HANDLE_EINTR(ioctl(fd, VIDIOC_G_CTRL, &v4l2_ctrl))) - return false; +Webcam* WebcamPrivateAPI::GetWebcam(const std::string& extension_id, + const std::string& webcam_id) { + std::string device_id; + if (!GetDeviceId(extension_id, webcam_id, &device_id)) { + return nullptr; + } - *value = v4l2_ctrl.value; - return true; -} + auto ix = webcams_.find(device_id); + if (ix != webcams_.end()) { + ix->second->AddExtensionRef(extension_id); + return ix->second.get(); + } + + scoped_ptr<V4L2Webcam> v4l2_webcam(new V4L2Webcam(device_id)); + if (!v4l2_webcam->Open()) { + return nullptr; + } -bool EnsureLogitechCommandsMapped(int fd) { - int res = ioctl(fd, UVCIOC_CTRL_MAP, &kLogitechCmdMapping); - // If mapping is successful or it's already mapped, this is a Logitech camera. - return res >= 0 || errno == EEXIST; + linked_ptr<Webcam> webcam(v4l2_webcam.release()); + + webcams_[device_id] = webcam; + webcam->AddExtensionRef(extension_id); + + return webcam.get(); } -const char kUnknownWebcam[] = "Unknown webcam id"; -} // namespace +bool WebcamPrivateAPI::GetDeviceId(const std::string& extension_id, + const std::string& webcam_id, + std::string* device_id) { + GURL security_origin = + extensions::Extension::GetBaseURLFromExtensionId(extension_id); -namespace extensions { + return content::GetMediaDeviceIDForHMAC( + content::MEDIA_DEVICE_VIDEO_CAPTURE, + browser_context_->GetResourceContext()->GetMediaDeviceIDSalt(), + security_origin, + webcam_id, + device_id); +} + +void WebcamPrivateAPI::OnBackgroundHostClose(const std::string& extension_id) { + for (auto webcam = webcams_.begin(); + webcam != webcams_.end(); /* No increment */ ) { + auto next = std::next(webcam); + webcam->second->RemoveExtensionRef(extension_id); + if (webcam->second->ShouldDelete()) + webcams_.erase(webcam); + webcam = next; + } +} WebcamPrivateSetFunction::WebcamPrivateSetFunction() { } @@ -115,64 +104,61 @@ bool WebcamPrivateSetFunction::RunSync() { webcam_private::Set::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); - base::ScopedFD fd = - OpenWebcam(extension_id(), browser_context(), params->webcam_id); - if (!fd.is_valid()) { + Webcam* webcam = WebcamPrivateAPI::Get(browser_context())-> + GetWebcam(extension_id(), params->webcam_id); + if (!webcam) { SetError(kUnknownWebcam); return false; } if (params->config.pan) { - SetWebcamParameter(fd.get(), V4L2_CID_PAN_ABSOLUTE, - *(params->config.pan)); + webcam->SetPan(*(params->config.pan)); } if (params->config.pan_direction) { - int direction = 0; + Webcam::PanDirection direction = Webcam::PAN_STOP; switch (params->config.pan_direction) { case webcam_private::PAN_DIRECTION_NONE: case webcam_private::PAN_DIRECTION_STOP: - direction = 0; + direction = Webcam::PAN_STOP; break; case webcam_private::PAN_DIRECTION_RIGHT: - direction = 1; + direction = Webcam::PAN_RIGHT; break; case webcam_private::PAN_DIRECTION_LEFT: - direction = -1; + direction = Webcam::PAN_LEFT; break; } - SetWebcamParameter(fd.get(), V4L2_CID_PAN_SPEED, direction); + webcam->SetPanDirection(direction); } if (params->config.tilt) { - SetWebcamParameter(fd.get(), V4L2_CID_TILT_ABSOLUTE, - *(params->config.tilt)); + webcam->SetTilt(*(params->config.tilt)); } if (params->config.tilt_direction) { - int direction = 0; + Webcam::TiltDirection direction = Webcam::TILT_STOP; switch (params->config.tilt_direction) { case webcam_private::TILT_DIRECTION_NONE: case webcam_private::TILT_DIRECTION_STOP: - direction = 0; + direction = Webcam::TILT_STOP; break; case webcam_private::TILT_DIRECTION_UP: - direction = 1; + direction = Webcam::TILT_UP; break; case webcam_private::TILT_DIRECTION_DOWN: - direction = -1; + direction = Webcam::TILT_DOWN; break; } - SetWebcamParameter(fd.get(), V4L2_CID_TILT_SPEED, direction); + webcam->SetTiltDirection(direction); } if (params->config.zoom) { - SetWebcamParameter(fd.get(), V4L2_CID_ZOOM_ABSOLUTE, - *(params->config.zoom)); + webcam->SetZoom(*(params->config.zoom)); } @@ -191,9 +177,9 @@ bool WebcamPrivateGetFunction::RunSync() { webcam_private::Get::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); - base::ScopedFD fd = - OpenWebcam(extension_id(), browser_context(), params->webcam_id); - if (!fd.is_valid()) { + Webcam* webcam = WebcamPrivateAPI::Get(browser_context())-> + GetWebcam(extension_id(), params->webcam_id); + if (!webcam) { SetError(kUnknownWebcam); return false; } @@ -201,15 +187,15 @@ bool WebcamPrivateGetFunction::RunSync() { webcam_private::WebcamConfiguration result; int pan; - if (GetWebcamParameter(fd.get(), V4L2_CID_PAN_ABSOLUTE, &pan)) + if (webcam->GetPan(&pan)) result.pan.reset(new double(pan)); int tilt; - if (GetWebcamParameter(fd.get(), V4L2_CID_TILT_ABSOLUTE, &tilt)) + if (webcam->GetTilt(&tilt)) result.tilt.reset(new double(tilt)); int zoom; - if (GetWebcamParameter(fd.get(), V4L2_CID_ZOOM_ABSOLUTE, &zoom)) + if (webcam->GetZoom(&zoom)) result.zoom.reset(new double(zoom)); SetResult(result.ToValue().release()); @@ -229,36 +215,32 @@ bool WebcamPrivateResetFunction::RunSync() { webcam_private::Reset::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); - base::ScopedFD fd = - OpenWebcam(extension_id(), browser_context(), params->webcam_id); - if (!fd.is_valid()) { + Webcam* webcam = WebcamPrivateAPI::Get(browser_context())-> + GetWebcam(extension_id(), params->webcam_id); + if (!webcam) { SetError(kUnknownWebcam); return false; } - if (params->config.pan || params->config.tilt) { - if (EnsureLogitechCommandsMapped(fd.get())) { - SetWebcamParameter(fd.get(), V4L2_CID_PANTILT_CMD, - kLogitechMenuIndexGoHome); - } - } + webcam->Reset(params->config.pan, params->config.tilt, params->config.zoom); - if (params->config.pan) { - struct v4l2_control v4l2_ctrl = {V4L2_CID_PAN_RESET}; - HANDLE_EINTR(ioctl(fd.get(), VIDIOC_S_CTRL, &v4l2_ctrl)); - } + return true; +} - if (params->config.tilt) { - struct v4l2_control v4l2_ctrl = {V4L2_CID_TILT_RESET}; - HANDLE_EINTR(ioctl(fd.get(), VIDIOC_S_CTRL, &v4l2_ctrl)); - } +static base::LazyInstance<BrowserContextKeyedAPIFactory<WebcamPrivateAPI>> + g_factory = LAZY_INSTANCE_INITIALIZER; - if (params->config.zoom) { - const int kDefaultZoom = 100; - SetWebcamParameter(fd.get(), V4L2_CID_ZOOM_ABSOLUTE, kDefaultZoom); - } +// static +BrowserContextKeyedAPIFactory<WebcamPrivateAPI>* +WebcamPrivateAPI::GetFactoryInstance() { + return g_factory.Pointer(); +} - return true; +template <> +void BrowserContextKeyedAPIFactory<WebcamPrivateAPI> + ::DeclareFactoryDependencies() { + DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); + DependsOn(ProcessManagerFactory::GetInstance()); } } // namespace extensions |