Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / api / webcam_private / webcam_private_api_chromeos.cc
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.
4
5 #include "extensions/browser/api/webcam_private/webcam_private_api.h"
6
7 #include <fcntl.h>
8 #include <linux/videodev2.h>
9 #include <stdio.h>
10 #include <sys/ioctl.h>
11 #include <unistd.h>
12
13 #include "base/files/scoped_file.h"
14 #include "base/posix/eintr_wrapper.h"
15 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/media_device_id.h"
17 #include "content/public/browser/resource_context.h"
18 #include "content/public/common/media_stream_request.h"
19 #include "extensions/common/api/webcam_private.h"
20
21 #define V4L2_CID_PAN_SPEED (V4L2_CID_CAMERA_CLASS_BASE+32)
22 #define V4L2_CID_TILT_SPEED (V4L2_CID_CAMERA_CLASS_BASE+33)
23
24 namespace webcam_private = extensions::core_api::webcam_private;
25
26 namespace content {
27 class BrowserContext;
28 }  // namespace content
29
30 namespace {
31
32 base::ScopedFD OpenWebcam(const std::string& extension_id,
33                           content::BrowserContext* browser_context,
34                           const std::string& webcam_id) {
35   GURL security_origin =
36       extensions::Extension::GetBaseURLFromExtensionId(extension_id);
37
38   std::string device_id;
39   bool success = content::GetMediaDeviceIDForHMAC(
40       content::MEDIA_DEVICE_VIDEO_CAPTURE,
41       browser_context->GetResourceContext()->GetMediaDeviceIDSalt(),
42       security_origin,
43       webcam_id,
44       &device_id);
45
46   if (!success)
47     return base::ScopedFD();
48
49   return base::ScopedFD(HANDLE_EINTR(open(device_id.c_str(), 0)));
50 }
51
52 void SetWebcamParameter(int fd, uint32_t control_id, int value) {
53   struct v4l2_control v4l2_ctrl = {control_id, value};
54   HANDLE_EINTR(ioctl(fd, VIDIOC_S_CTRL, &v4l2_ctrl));
55 }
56
57 bool GetWebcamParameter(int fd, uint32_t control_id, int* value) {
58   struct v4l2_control v4l2_ctrl = {control_id};
59
60   if (HANDLE_EINTR(ioctl(fd, VIDIOC_G_CTRL, &v4l2_ctrl)))
61     return false;
62
63   *value = v4l2_ctrl.value;
64   return true;
65 }
66
67 const char kUnknownWebcam[] = "Unknown webcam id";
68 }  // namespace
69
70 namespace extensions {
71
72 WebcamPrivateSetFunction::WebcamPrivateSetFunction() {
73 }
74
75 WebcamPrivateSetFunction::~WebcamPrivateSetFunction() {
76 }
77
78 bool WebcamPrivateSetFunction::RunSync() {
79   // Get parameters
80   scoped_ptr<webcam_private::Set::Params> params(
81       webcam_private::Set::Params::Create(*args_));
82   EXTENSION_FUNCTION_VALIDATE(params.get());
83
84   base::ScopedFD fd =
85       OpenWebcam(extension_id(), browser_context(), params->webcam_id);
86   if (!fd.is_valid()) {
87     SetError(kUnknownWebcam);
88     return false;
89   }
90
91   if (params->config.pan) {
92     SetWebcamParameter(fd.get(), V4L2_CID_PAN_ABSOLUTE,
93                        *(params->config.pan));
94   }
95
96   if (params->config.pan_direction) {
97     int direction = 0;
98     switch (params->config.pan_direction) {
99       case webcam_private::PAN_DIRECTION_NONE:
100       case webcam_private::PAN_DIRECTION_STOP:
101         direction = 0;
102         break;
103
104       case webcam_private::PAN_DIRECTION_RIGHT:
105         direction = 1;
106         break;
107
108       case webcam_private::PAN_DIRECTION_LEFT:
109         direction = -1;
110         break;
111     }
112     SetWebcamParameter(fd.get(), V4L2_CID_PAN_SPEED, direction);
113   }
114
115   if (params->config.tilt) {
116     SetWebcamParameter(fd.get(), V4L2_CID_TILT_ABSOLUTE,
117                        *(params->config.tilt));
118   }
119
120   if (params->config.tilt_direction) {
121     int direction = 0;
122     switch (params->config.tilt_direction) {
123       case webcam_private::TILT_DIRECTION_NONE:
124       case webcam_private::TILT_DIRECTION_STOP:
125         direction = 0;
126         break;
127
128       case webcam_private::TILT_DIRECTION_UP:
129         direction = 1;
130         break;
131
132       case webcam_private::TILT_DIRECTION_DOWN:
133         direction = -1;
134         break;
135     }
136     SetWebcamParameter(fd.get(), V4L2_CID_TILT_SPEED, direction);
137   }
138
139   if (params->config.zoom) {
140     SetWebcamParameter(fd.get(), V4L2_CID_ZOOM_ABSOLUTE,
141                        *(params->config.zoom));
142   }
143
144
145   return true;
146 }
147
148 WebcamPrivateGetFunction::WebcamPrivateGetFunction() {
149 }
150
151 WebcamPrivateGetFunction::~WebcamPrivateGetFunction() {
152 }
153
154 bool WebcamPrivateGetFunction::RunSync() {
155   // Get parameters
156   scoped_ptr<webcam_private::Get::Params> params(
157       webcam_private::Get::Params::Create(*args_));
158   EXTENSION_FUNCTION_VALIDATE(params.get());
159
160   base::ScopedFD fd =
161       OpenWebcam(extension_id(), browser_context(), params->webcam_id);
162   if (!fd.is_valid()) {
163     SetError(kUnknownWebcam);
164     return false;
165   }
166
167   webcam_private::WebcamConfiguration result;
168
169   int pan;
170   if (GetWebcamParameter(fd.get(), V4L2_CID_PAN_ABSOLUTE, &pan))
171     result.pan.reset(new double(pan));
172
173   int tilt;
174   if (GetWebcamParameter(fd.get(), V4L2_CID_TILT_ABSOLUTE, &tilt))
175     result.tilt.reset(new double(tilt));
176
177   int zoom;
178   if (GetWebcamParameter(fd.get(), V4L2_CID_ZOOM_ABSOLUTE, &zoom))
179     result.zoom.reset(new double(zoom));
180
181   SetResult(result.ToValue().release());
182
183   return true;
184 }
185
186 WebcamPrivateResetFunction::WebcamPrivateResetFunction() {
187 }
188
189 WebcamPrivateResetFunction::~WebcamPrivateResetFunction() {
190 }
191
192 bool WebcamPrivateResetFunction::RunSync() {
193   // Get parameters
194   scoped_ptr<webcam_private::Reset::Params> params(
195       webcam_private::Reset::Params::Create(*args_));
196   EXTENSION_FUNCTION_VALIDATE(params.get());
197
198   base::ScopedFD fd =
199       OpenWebcam(extension_id(), browser_context(), params->webcam_id);
200   if (!fd.is_valid()) {
201     SetError(kUnknownWebcam);
202     return false;
203   }
204
205   if (params->config.pan) {
206     struct v4l2_control v4l2_ctrl = {V4L2_CID_PAN_RESET};
207     HANDLE_EINTR(ioctl(fd.get(), VIDIOC_S_CTRL, &v4l2_ctrl));
208   }
209
210   if (params->config.tilt) {
211     struct v4l2_control v4l2_ctrl = {V4L2_CID_TILT_RESET};
212     HANDLE_EINTR(ioctl(fd.get(), VIDIOC_S_CTRL, &v4l2_ctrl));
213   }
214
215   if (params->config.zoom) {
216     const int kDefaultZoom = 100;
217     SetWebcamParameter(fd.get(), V4L2_CID_ZOOM_ABSOLUTE, kDefaultZoom);
218   }
219
220   return true;
221 }
222
223 }  // namespace extensions