Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / extensions / browser / api / webcam_private / webcam_private_api_chromeos.cc
blobca7ad418f45acbda71f2616d68687b7fb63409ff
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 "extensions/browser/api/webcam_private/webcam_private_api.h"
7 #include "base/lazy_instance.h"
8 #include "content/public/browser/browser_context.h"
9 #include "content/public/browser/media_device_id.h"
10 #include "content/public/browser/resource_context.h"
11 #include "extensions/browser/api/webcam_private/v4l2_webcam.h"
12 #include "extensions/browser/api/webcam_private/visca_webcam.h"
13 #include "extensions/browser/process_manager.h"
14 #include "extensions/browser/process_manager_factory.h"
15 #include "extensions/common/api/webcam_private.h"
17 namespace webcam_private = extensions::api::webcam_private;
19 namespace content {
20 class BrowserContext;
21 } // namespace content
23 namespace {
25 const char kPathInUse[] = "Path in use";
26 const char kUnknownWebcam[] = "Unknown webcam id";
27 const char kOpenSerialWebcamError[] = "Can't open serial webcam.";
28 const char kGetWebcamPTZError[] = "Can't get web camera pan/tilt/zoom.";
29 const char kSetWebcamPTZError[] = "Can't set web camera pan/tilt/zoom.";
30 const char kResetWebcamError[] = "Can't reset web camera.";
32 } // namespace
34 namespace extensions {
36 // static
37 WebcamPrivateAPI* WebcamPrivateAPI::Get(content::BrowserContext* context) {
38 return GetFactoryInstance()->Get(context);
41 WebcamPrivateAPI::WebcamPrivateAPI(content::BrowserContext* context)
42 : browser_context_(context),
43 weak_ptr_factory_(this) {
44 webcam_resource_manager_.reset(
45 new ApiResourceManager<WebcamResource>(context));
48 WebcamPrivateAPI::~WebcamPrivateAPI() {
51 Webcam* WebcamPrivateAPI::GetWebcam(const std::string& extension_id,
52 const std::string& webcam_id) {
53 WebcamResource* webcam_resource = FindWebcamResource(extension_id, webcam_id);
54 if (webcam_resource)
55 return webcam_resource->GetWebcam();
57 std::string device_id;
58 GetDeviceId(extension_id, webcam_id, &device_id);
59 V4L2Webcam* v4l2_webcam(new V4L2Webcam(device_id));
60 if (!v4l2_webcam->Open()) {
61 return nullptr;
64 webcam_resource_manager_->Add(
65 new WebcamResource(extension_id, v4l2_webcam, webcam_id));
67 return v4l2_webcam;
70 bool WebcamPrivateAPI::OpenSerialWebcam(
71 const std::string& extension_id,
72 const std::string& device_path,
73 const base::Callback<void(const std::string&, bool)>& callback) {
74 const std::string& webcam_id = GetWebcamId(extension_id, device_path);
75 WebcamResource* webcam_resource = FindWebcamResource(extension_id, webcam_id);
76 if (webcam_resource)
77 return false;
79 ViscaWebcam* visca_webcam(new ViscaWebcam(device_path, extension_id));
80 visca_webcam->Open(base::Bind(
81 &WebcamPrivateAPI::OnOpenSerialWebcam, weak_ptr_factory_.GetWeakPtr(),
82 extension_id, device_path, make_scoped_refptr(visca_webcam), callback));
83 return true;
86 bool WebcamPrivateAPI::CloseWebcam(const std::string& extension_id,
87 const std::string& webcam_id) {
88 if (FindWebcamResource(extension_id, webcam_id)) {
89 RemoveWebcamResource(extension_id, webcam_id);
90 return true;
92 return false;
95 void WebcamPrivateAPI::OnOpenSerialWebcam(
96 const std::string& extension_id,
97 const std::string& device_path,
98 scoped_refptr<Webcam> webcam,
99 const base::Callback<void(const std::string&, bool)>& callback,
100 bool success) {
101 if (success) {
102 const std::string& webcam_id = GetWebcamId(extension_id, device_path);
103 webcam_resource_manager_->Add(
104 new WebcamResource(extension_id, webcam.get(), webcam_id));
105 callback.Run(webcam_id, true);
106 } else {
107 callback.Run("", false);
111 bool WebcamPrivateAPI::GetDeviceId(const std::string& extension_id,
112 const std::string& webcam_id,
113 std::string* device_id) {
114 GURL security_origin =
115 extensions::Extension::GetBaseURLFromExtensionId(extension_id);
117 return content::GetMediaDeviceIDForHMAC(
118 content::MEDIA_DEVICE_VIDEO_CAPTURE,
119 browser_context_->GetResourceContext()->GetMediaDeviceIDSalt(),
120 security_origin,
121 webcam_id,
122 device_id);
125 std::string WebcamPrivateAPI::GetWebcamId(const std::string& extension_id,
126 const std::string& device_id) {
127 GURL security_origin =
128 extensions::Extension::GetBaseURLFromExtensionId(extension_id);
130 return content::GetHMACForMediaDeviceID(
131 browser_context_->GetResourceContext()->GetMediaDeviceIDSalt(),
132 security_origin, device_id);
135 WebcamResource* WebcamPrivateAPI::FindWebcamResource(
136 const std::string& extension_id,
137 const std::string& webcam_id) const {
138 DCHECK(webcam_resource_manager_);
140 base::hash_set<int>* connection_ids =
141 webcam_resource_manager_->GetResourceIds(extension_id);
142 if (!connection_ids)
143 return nullptr;
145 for (const auto& connection_id : *connection_ids) {
146 WebcamResource* webcam_resource =
147 webcam_resource_manager_->Get(extension_id, connection_id);
148 if (webcam_resource && webcam_resource->GetWebcamId() == webcam_id)
149 return webcam_resource;
152 return nullptr;
155 bool WebcamPrivateAPI::RemoveWebcamResource(const std::string& extension_id,
156 const std::string& webcam_id) {
157 DCHECK(webcam_resource_manager_);
159 base::hash_set<int>* connection_ids =
160 webcam_resource_manager_->GetResourceIds(extension_id);
161 if (!connection_ids)
162 return false;
164 for (const auto& connection_id : *connection_ids) {
165 WebcamResource* webcam_resource =
166 webcam_resource_manager_->Get(extension_id, connection_id);
167 if (webcam_resource && webcam_resource->GetWebcamId() == webcam_id) {
168 webcam_resource_manager_->Remove(extension_id, connection_id);
169 return true;
173 return false;
176 WebcamPrivateOpenSerialWebcamFunction::WebcamPrivateOpenSerialWebcamFunction() {
179 WebcamPrivateOpenSerialWebcamFunction::
180 ~WebcamPrivateOpenSerialWebcamFunction() {
183 bool WebcamPrivateOpenSerialWebcamFunction::RunAsync() {
184 scoped_ptr<webcam_private::OpenSerialWebcam::Params> params(
185 webcam_private::OpenSerialWebcam::Params::Create(*args_));
186 EXTENSION_FUNCTION_VALIDATE(params.get());
188 if (WebcamPrivateAPI::Get(browser_context())
189 ->OpenSerialWebcam(
190 extension_id(), params->path,
191 base::Bind(&WebcamPrivateOpenSerialWebcamFunction::OnOpenWebcam,
192 this))) {
193 return true;
194 } else {
195 SetError(kPathInUse);
196 return false;
200 void WebcamPrivateOpenSerialWebcamFunction::OnOpenWebcam(
201 const std::string& webcam_id,
202 bool success) {
203 if (success) {
204 SetResult(new base::StringValue(webcam_id));
205 SendResponse(true);
206 } else {
207 SetError(kOpenSerialWebcamError);
208 SendResponse(false);
212 WebcamPrivateCloseWebcamFunction::WebcamPrivateCloseWebcamFunction() {
215 WebcamPrivateCloseWebcamFunction::~WebcamPrivateCloseWebcamFunction() {
218 bool WebcamPrivateCloseWebcamFunction::RunAsync() {
219 scoped_ptr<webcam_private::CloseWebcam::Params> params(
220 webcam_private::CloseWebcam::Params::Create(*args_));
221 EXTENSION_FUNCTION_VALIDATE(params.get());
223 return WebcamPrivateAPI::Get(browser_context())
224 ->CloseWebcam(extension_id(), params->webcam_id);
227 WebcamPrivateSetFunction::WebcamPrivateSetFunction() {
230 WebcamPrivateSetFunction::~WebcamPrivateSetFunction() {
233 bool WebcamPrivateSetFunction::RunAsync() {
234 scoped_ptr<webcam_private::Set::Params> params(
235 webcam_private::Set::Params::Create(*args_));
236 EXTENSION_FUNCTION_VALIDATE(params.get());
238 Webcam* webcam = WebcamPrivateAPI::Get(browser_context())
239 ->GetWebcam(extension_id(), params->webcam_id);
240 if (!webcam) {
241 SetError(kUnknownWebcam);
242 return false;
245 int pan_speed = 0;
246 int tilt_speed = 0;
247 if (params->config.pan_speed)
248 pan_speed = *(params->config.pan_speed);
250 if (params->config.tilt_speed)
251 tilt_speed = *(params->config.tilt_speed);
253 if (params->config.pan) {
254 webcam->SetPan(
255 *(params->config.pan), pan_speed,
256 base::Bind(&WebcamPrivateSetFunction::OnSetWebcamParameters, this));
259 if (params->config.pan_direction) {
260 Webcam::PanDirection direction = Webcam::PAN_STOP;
261 switch (params->config.pan_direction) {
262 case webcam_private::PAN_DIRECTION_NONE:
263 case webcam_private::PAN_DIRECTION_STOP:
264 direction = Webcam::PAN_STOP;
265 break;
267 case webcam_private::PAN_DIRECTION_RIGHT:
268 direction = Webcam::PAN_RIGHT;
269 break;
271 case webcam_private::PAN_DIRECTION_LEFT:
272 direction = Webcam::PAN_LEFT;
273 break;
275 webcam->SetPanDirection(
276 direction, pan_speed,
277 base::Bind(&WebcamPrivateSetFunction::OnSetWebcamParameters, this));
280 if (params->config.tilt) {
281 webcam->SetTilt(
282 *(params->config.tilt), tilt_speed,
283 base::Bind(&WebcamPrivateSetFunction::OnSetWebcamParameters, this));
286 if (params->config.tilt_direction) {
287 Webcam::TiltDirection direction = Webcam::TILT_STOP;
288 switch (params->config.tilt_direction) {
289 case webcam_private::TILT_DIRECTION_NONE:
290 case webcam_private::TILT_DIRECTION_STOP:
291 direction = Webcam::TILT_STOP;
292 break;
294 case webcam_private::TILT_DIRECTION_UP:
295 direction = Webcam::TILT_UP;
296 break;
298 case webcam_private::TILT_DIRECTION_DOWN:
299 direction = Webcam::TILT_DOWN;
300 break;
302 webcam->SetTiltDirection(
303 direction, tilt_speed,
304 base::Bind(&WebcamPrivateSetFunction::OnSetWebcamParameters, this));
307 if (params->config.zoom) {
308 webcam->SetZoom(
309 *(params->config.zoom),
310 base::Bind(&WebcamPrivateSetFunction::OnSetWebcamParameters, this));
313 return true;
316 void WebcamPrivateSetFunction::OnSetWebcamParameters(bool success) {
317 if (!success)
318 SetError(kSetWebcamPTZError);
321 WebcamPrivateGetFunction::WebcamPrivateGetFunction()
322 : pan_(0),
323 tilt_(0),
324 zoom_(0),
325 get_pan_(false),
326 get_tilt_(false),
327 get_zoom_(false),
328 success_(true) {}
330 WebcamPrivateGetFunction::~WebcamPrivateGetFunction() {
333 bool WebcamPrivateGetFunction::RunAsync() {
334 scoped_ptr<webcam_private::Get::Params> params(
335 webcam_private::Get::Params::Create(*args_));
336 EXTENSION_FUNCTION_VALIDATE(params.get());
338 Webcam* webcam = WebcamPrivateAPI::Get(browser_context())
339 ->GetWebcam(extension_id(), params->webcam_id);
340 if (!webcam) {
341 SetError(kUnknownWebcam);
342 return false;
345 webcam->GetPan(base::Bind(&WebcamPrivateGetFunction::OnGetWebcamParameters,
346 this, INQUIRY_PAN));
347 webcam->GetTilt(base::Bind(&WebcamPrivateGetFunction::OnGetWebcamParameters,
348 this, INQUIRY_TILT));
349 webcam->GetZoom(base::Bind(&WebcamPrivateGetFunction::OnGetWebcamParameters,
350 this, INQUIRY_ZOOM));
352 return true;
355 void WebcamPrivateGetFunction::OnGetWebcamParameters(InquiryType type,
356 bool success,
357 int value) {
358 if (!success_)
359 return;
360 success_ = success_ && success;
362 if (!success_) {
363 SetError(kGetWebcamPTZError);
364 SendResponse(false);
365 } else {
366 switch (type) {
367 case INQUIRY_PAN:
368 pan_ = value;
369 get_pan_ = true;
370 break;
371 case INQUIRY_TILT:
372 tilt_ = value;
373 get_tilt_ = true;
374 break;
375 case INQUIRY_ZOOM:
376 zoom_ = value;
377 get_zoom_ = true;
378 break;
380 if (get_pan_ && get_tilt_ && get_zoom_) {
381 webcam_private::WebcamConfiguration result;
382 result.pan.reset(new double(pan_));
383 result.tilt.reset(new double(tilt_));
384 result.zoom.reset(new double(zoom_));
385 SetResult(result.ToValue().release());
386 SendResponse(true);
391 WebcamPrivateResetFunction::WebcamPrivateResetFunction() {
394 WebcamPrivateResetFunction::~WebcamPrivateResetFunction() {
397 bool WebcamPrivateResetFunction::RunAsync() {
398 scoped_ptr<webcam_private::Reset::Params> params(
399 webcam_private::Reset::Params::Create(*args_));
400 EXTENSION_FUNCTION_VALIDATE(params.get());
402 Webcam* webcam = WebcamPrivateAPI::Get(browser_context())
403 ->GetWebcam(extension_id(), params->webcam_id);
404 if (!webcam) {
405 SetError(kUnknownWebcam);
406 return false;
409 webcam->Reset(params->config.pan, params->config.tilt, params->config.zoom,
410 base::Bind(&WebcamPrivateResetFunction::OnResetWebcam, this));
412 return true;
415 void WebcamPrivateResetFunction::OnResetWebcam(bool success) {
416 if (!success)
417 SetError(kResetWebcamError);
420 static base::LazyInstance<BrowserContextKeyedAPIFactory<WebcamPrivateAPI>>
421 g_factory = LAZY_INSTANCE_INITIALIZER;
423 // static
424 BrowserContextKeyedAPIFactory<WebcamPrivateAPI>*
425 WebcamPrivateAPI::GetFactoryInstance() {
426 return g_factory.Pointer();
429 template <>
430 void BrowserContextKeyedAPIFactory<WebcamPrivateAPI>
431 ::DeclareFactoryDependencies() {
432 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
433 DependsOn(ProcessManagerFactory::GetInstance());
436 } // namespace extensions