1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/api/webcam_private/webcam_private_api.h"
8 #include <linux/videodev2.h>
10 #include <sys/ioctl.h>
13 #include "base/files/scoped_file.h"
14 #include "base/posix/eintr_wrapper.h"
15 #include "chrome/common/extensions/api/webcam_private.h"
16 #include "content/public/browser/browser_context.h"
17 #include "content/public/browser/media_device_id.h"
18 #include "content/public/browser/resource_context.h"
19 #include "content/public/common/media_stream_request.h"
23 } // namespace content
27 base::ScopedFD OpenWebcam(const std::string& extension_id,
28 content::BrowserContext* browser_context,
29 const std::string& webcam_id) {
30 GURL security_origin =
31 extensions::Extension::GetBaseURLFromExtensionId(extension_id);
33 std::string device_id;
34 bool success = content::GetMediaDeviceIDForHMAC(
35 content::MEDIA_DEVICE_VIDEO_CAPTURE,
36 browser_context->GetResourceContext()->GetMediaDeviceIDSalt(),
42 return base::ScopedFD();
44 return base::ScopedFD(HANDLE_EINTR(open(device_id.c_str(), 0)));
47 void SetWebcamParameter(int fd, uint32_t control_id, int value) {
48 struct v4l2_control v4l2_ctrl = {control_id, value};
49 HANDLE_EINTR(ioctl(fd, VIDIOC_S_CTRL, &v4l2_ctrl));
52 bool GetWebcamParameter(int fd, uint32_t control_id, int* value) {
53 struct v4l2_control v4l2_ctrl = {control_id};
55 if (HANDLE_EINTR(ioctl(fd, VIDIOC_G_CTRL, &v4l2_ctrl)))
58 *value = v4l2_ctrl.value;
62 const char kUnknownWebcam[] = "Unknown webcam id";
65 namespace extensions {
67 WebcamPrivateSetFunction::WebcamPrivateSetFunction() {
70 WebcamPrivateSetFunction::~WebcamPrivateSetFunction() {
73 bool WebcamPrivateSetFunction::RunSync() {
75 scoped_ptr<api::webcam_private::Set::Params> params(
76 api::webcam_private::Set::Params::Create(*args_));
77 EXTENSION_FUNCTION_VALIDATE(params.get());
80 OpenWebcam(extension_id(), browser_context(), params->webcam_id);
82 SetError(kUnknownWebcam);
86 if (params->config.pan) {
87 SetWebcamParameter(fd.get(), V4L2_CID_PAN_ABSOLUTE,
88 *(params->config.pan));
91 if (params->config.tilt) {
92 SetWebcamParameter(fd.get(), V4L2_CID_TILT_ABSOLUTE,
93 *(params->config.tilt));
96 if (params->config.zoom) {
97 SetWebcamParameter(fd.get(), V4L2_CID_ZOOM_ABSOLUTE,
98 *(params->config.zoom));
104 WebcamPrivateGetFunction::WebcamPrivateGetFunction() {
107 WebcamPrivateGetFunction::~WebcamPrivateGetFunction() {
110 bool WebcamPrivateGetFunction::RunSync() {
112 scoped_ptr<api::webcam_private::Get::Params> params(
113 api::webcam_private::Get::Params::Create(*args_));
114 EXTENSION_FUNCTION_VALIDATE(params.get());
117 OpenWebcam(extension_id(), browser_context(), params->webcam_id);
118 if (!fd.is_valid()) {
119 SetError(kUnknownWebcam);
123 api::webcam_private::WebcamConfiguration result;
126 if (GetWebcamParameter(fd.get(), V4L2_CID_PAN_ABSOLUTE, &pan))
127 result.pan.reset(new double(pan));
130 if (GetWebcamParameter(fd.get(), V4L2_CID_TILT_ABSOLUTE, &tilt))
131 result.tilt.reset(new double(tilt));
134 if (GetWebcamParameter(fd.get(), V4L2_CID_ZOOM_ABSOLUTE, &zoom))
135 result.zoom.reset(new double(zoom));
137 SetResult(result.ToValue().release());
142 WebcamPrivateResetFunction::WebcamPrivateResetFunction() {
145 WebcamPrivateResetFunction::~WebcamPrivateResetFunction() {
148 bool WebcamPrivateResetFunction::RunSync() {
150 scoped_ptr<api::webcam_private::Reset::Params> params(
151 api::webcam_private::Reset::Params::Create(*args_));
152 EXTENSION_FUNCTION_VALIDATE(params.get());
155 OpenWebcam(extension_id(), browser_context(), params->webcam_id);
156 if (!fd.is_valid()) {
157 SetError(kUnknownWebcam);
161 if (params->config.pan) {
162 struct v4l2_control v4l2_ctrl = {V4L2_CID_PAN_RESET};
163 HANDLE_EINTR(ioctl(fd.get(), VIDIOC_S_CTRL, &v4l2_ctrl));
166 if (params->config.tilt) {
167 struct v4l2_control v4l2_ctrl = {V4L2_CID_TILT_RESET};
168 HANDLE_EINTR(ioctl(fd.get(), VIDIOC_S_CTRL, &v4l2_ctrl));
171 if (params->config.zoom) {
172 const int kDefaultZoom = 100;
173 SetWebcamParameter(fd.get(), V4L2_CID_ZOOM_ABSOLUTE, kDefaultZoom);
179 } // namespace extensions