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 |