Chromium Code Reviews| Index: extensions/browser/api/webcam_private/webcam_private_api_chromeos.cc |
| 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 765c778d048e6f1772916d0b1cb101471b105499..d0af59165776ba2a7ca8f780421b3e0c65c1d763 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,16 @@ |
| #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/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 +21,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 +103,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 +176,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 +186,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 +214,25 @@ 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); |
| - } |
| - } |
| - |
| - if (params->config.pan) { |
| - struct v4l2_control v4l2_ctrl = {V4L2_CID_PAN_RESET}; |
| - HANDLE_EINTR(ioctl(fd.get(), VIDIOC_S_CTRL, &v4l2_ctrl)); |
| - } |
| + webcam->Reset(params->config.pan, params->config.tilt, params->config.zoom); |
| - if (params->config.tilt) { |
| - struct v4l2_control v4l2_ctrl = {V4L2_CID_TILT_RESET}; |
| - HANDLE_EINTR(ioctl(fd.get(), VIDIOC_S_CTRL, &v4l2_ctrl)); |
| - } |
| + return true; |
| +} |
| - if (params->config.zoom) { |
| - const int kDefaultZoom = 100; |
| - SetWebcamParameter(fd.get(), V4L2_CID_ZOOM_ABSOLUTE, kDefaultZoom); |
| - } |
| +static base::LazyInstance<BrowserContextKeyedAPIFactory<WebcamPrivateAPI>> |
| + g_factory = LAZY_INSTANCE_INITIALIZER; |
| - return true; |
| +// static |
| +BrowserContextKeyedAPIFactory<WebcamPrivateAPI>* |
| +WebcamPrivateAPI::GetFactoryInstance() { |
| + return g_factory.Pointer(); |
| } |
|
Ken Rockot(use gerrit already)
2015/05/14 00:07:02
You also need to declare your dependency on Proces
Zachary Kuznia
2015/05/14 17:25:11
Done.
|
| } // namespace extensions |