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
;
21 } // namespace content
24 const char kPathInUse
[] = "Path in use";
25 const char kUnknownWebcam
[] = "Unknown webcam id";
28 namespace extensions
{
31 WebcamPrivateAPI
* WebcamPrivateAPI::Get(content::BrowserContext
* context
) {
32 return GetFactoryInstance()->Get(context
);
35 WebcamPrivateAPI::WebcamPrivateAPI(content::BrowserContext
* context
)
36 : browser_context_(context
),
37 weak_ptr_factory_(this) {
38 webcam_resource_manager_
.reset(
39 new ApiResourceManager
<WebcamResource
>(context
));
42 WebcamPrivateAPI::~WebcamPrivateAPI() {
45 Webcam
* WebcamPrivateAPI::GetWebcam(const std::string
& extension_id
,
46 const std::string
& webcam_id
) {
47 WebcamResource
* webcam_resource
= FindWebcamResource(extension_id
, webcam_id
);
49 return webcam_resource
->GetWebcam();
51 std::string device_id
;
52 GetDeviceId(extension_id
, webcam_id
, &device_id
);
53 V4L2Webcam
* v4l2_webcam(new V4L2Webcam(device_id
));
54 if (!v4l2_webcam
->Open()) {
58 webcam_resource_manager_
->Add(
59 new WebcamResource(extension_id
, v4l2_webcam
, webcam_id
));
64 bool WebcamPrivateAPI::OpenSerialWebcam(
65 const std::string
& extension_id
,
66 const std::string
& device_path
,
67 const base::Callback
<void(const std::string
&, bool)>& callback
) {
68 const std::string
& webcam_id
= GetWebcamId(extension_id
, device_path
);
69 WebcamResource
* webcam_resource
= FindWebcamResource(extension_id
, webcam_id
);
73 ViscaWebcam
* visca_webcam(new ViscaWebcam(device_path
, extension_id
));
74 visca_webcam
->Open(base::Bind(
75 &WebcamPrivateAPI::OnOpenSerialWebcam
, weak_ptr_factory_
.GetWeakPtr(),
76 extension_id
, device_path
, make_scoped_refptr(visca_webcam
), callback
));
80 bool WebcamPrivateAPI::CloseWebcam(const std::string
& extension_id
,
81 const std::string
& webcam_id
) {
82 if (FindWebcamResource(extension_id
, webcam_id
)) {
83 RemoveWebcamResource(extension_id
, webcam_id
);
89 void WebcamPrivateAPI::OnOpenSerialWebcam(
90 const std::string
& extension_id
,
91 const std::string
& device_path
,
92 scoped_refptr
<Webcam
> webcam
,
93 const base::Callback
<void(const std::string
&, bool)>& callback
,
96 const std::string
& webcam_id
= GetWebcamId(extension_id
, device_path
);
97 webcam_resource_manager_
->Add(
98 new WebcamResource(extension_id
, webcam
.get(), webcam_id
));
99 callback
.Run(webcam_id
, true);
101 callback
.Run("", false);
105 bool WebcamPrivateAPI::GetDeviceId(const std::string
& extension_id
,
106 const std::string
& webcam_id
,
107 std::string
* device_id
) {
108 GURL security_origin
=
109 extensions::Extension::GetBaseURLFromExtensionId(extension_id
);
111 return content::GetMediaDeviceIDForHMAC(
112 content::MEDIA_DEVICE_VIDEO_CAPTURE
,
113 browser_context_
->GetResourceContext()->GetMediaDeviceIDSalt(),
119 std::string
WebcamPrivateAPI::GetWebcamId(const std::string
& extension_id
,
120 const std::string
& device_id
) {
121 GURL security_origin
=
122 extensions::Extension::GetBaseURLFromExtensionId(extension_id
);
124 return content::GetHMACForMediaDeviceID(
125 browser_context_
->GetResourceContext()->GetMediaDeviceIDSalt(),
126 security_origin
, device_id
);
129 WebcamResource
* WebcamPrivateAPI::FindWebcamResource(
130 const std::string
& extension_id
,
131 const std::string
& webcam_id
) const {
132 DCHECK(webcam_resource_manager_
);
134 base::hash_set
<int>* connection_ids
=
135 webcam_resource_manager_
->GetResourceIds(extension_id
);
139 for (const auto& connection_id
: *connection_ids
) {
140 WebcamResource
* webcam_resource
=
141 webcam_resource_manager_
->Get(extension_id
, connection_id
);
142 if (webcam_resource
&& webcam_resource
->GetWebcamId() == webcam_id
)
143 return webcam_resource
;
149 bool WebcamPrivateAPI::RemoveWebcamResource(const std::string
& extension_id
,
150 const std::string
& webcam_id
) {
151 DCHECK(webcam_resource_manager_
);
153 base::hash_set
<int>* connection_ids
=
154 webcam_resource_manager_
->GetResourceIds(extension_id
);
158 for (const auto& connection_id
: *connection_ids
) {
159 WebcamResource
* webcam_resource
=
160 webcam_resource_manager_
->Get(extension_id
, connection_id
);
161 if (webcam_resource
&& webcam_resource
->GetWebcamId() == webcam_id
) {
162 webcam_resource_manager_
->Remove(extension_id
, connection_id
);
170 WebcamPrivateOpenSerialWebcamFunction::WebcamPrivateOpenSerialWebcamFunction() {
173 WebcamPrivateOpenSerialWebcamFunction::
174 ~WebcamPrivateOpenSerialWebcamFunction() {
177 bool WebcamPrivateOpenSerialWebcamFunction::RunAsync() {
178 scoped_ptr
<webcam_private::OpenSerialWebcam::Params
> params(
179 webcam_private::OpenSerialWebcam::Params::Create(*args_
));
180 EXTENSION_FUNCTION_VALIDATE(params
.get());
182 if (WebcamPrivateAPI::Get(browser_context())
184 extension_id(), params
->path
,
185 base::Bind(&WebcamPrivateOpenSerialWebcamFunction::OnOpenWebcam
,
189 SetError(kPathInUse
);
194 void WebcamPrivateOpenSerialWebcamFunction::OnOpenWebcam(
195 const std::string
& webcam_id
,
198 SetResult(new base::StringValue(webcam_id
));
201 SetError(kUnknownWebcam
);
206 WebcamPrivateCloseWebcamFunction::WebcamPrivateCloseWebcamFunction() {
209 WebcamPrivateCloseWebcamFunction::~WebcamPrivateCloseWebcamFunction() {
212 bool WebcamPrivateCloseWebcamFunction::RunAsync() {
213 scoped_ptr
<webcam_private::CloseWebcam::Params
> params(
214 webcam_private::CloseWebcam::Params::Create(*args_
));
215 EXTENSION_FUNCTION_VALIDATE(params
.get());
217 return WebcamPrivateAPI::Get(browser_context())
218 ->CloseWebcam(extension_id(), params
->webcam_id
);
221 WebcamPrivateSetFunction::WebcamPrivateSetFunction() {
224 WebcamPrivateSetFunction::~WebcamPrivateSetFunction() {
227 bool WebcamPrivateSetFunction::RunSync() {
228 scoped_ptr
<webcam_private::Set::Params
> params(
229 webcam_private::Set::Params::Create(*args_
));
230 EXTENSION_FUNCTION_VALIDATE(params
.get());
232 Webcam
* webcam
= WebcamPrivateAPI::Get(browser_context())
233 ->GetWebcam(extension_id(), params
->webcam_id
);
235 SetError(kUnknownWebcam
);
239 if (params
->config
.pan
) {
240 webcam
->SetPan(*(params
->config
.pan
));
243 if (params
->config
.pan_direction
) {
244 Webcam::PanDirection direction
= Webcam::PAN_STOP
;
245 switch (params
->config
.pan_direction
) {
246 case webcam_private::PAN_DIRECTION_NONE
:
247 case webcam_private::PAN_DIRECTION_STOP
:
248 direction
= Webcam::PAN_STOP
;
251 case webcam_private::PAN_DIRECTION_RIGHT
:
252 direction
= Webcam::PAN_RIGHT
;
255 case webcam_private::PAN_DIRECTION_LEFT
:
256 direction
= Webcam::PAN_LEFT
;
259 webcam
->SetPanDirection(direction
);
262 if (params
->config
.tilt
) {
263 webcam
->SetTilt(*(params
->config
.tilt
));
266 if (params
->config
.tilt_direction
) {
267 Webcam::TiltDirection direction
= Webcam::TILT_STOP
;
268 switch (params
->config
.tilt_direction
) {
269 case webcam_private::TILT_DIRECTION_NONE
:
270 case webcam_private::TILT_DIRECTION_STOP
:
271 direction
= Webcam::TILT_STOP
;
274 case webcam_private::TILT_DIRECTION_UP
:
275 direction
= Webcam::TILT_UP
;
278 case webcam_private::TILT_DIRECTION_DOWN
:
279 direction
= Webcam::TILT_DOWN
;
282 webcam
->SetTiltDirection(direction
);
285 if (params
->config
.zoom
) {
286 webcam
->SetZoom(*(params
->config
.zoom
));
293 WebcamPrivateGetFunction::WebcamPrivateGetFunction() {
296 WebcamPrivateGetFunction::~WebcamPrivateGetFunction() {
299 bool WebcamPrivateGetFunction::RunSync() {
300 scoped_ptr
<webcam_private::Get::Params
> params(
301 webcam_private::Get::Params::Create(*args_
));
302 EXTENSION_FUNCTION_VALIDATE(params
.get());
304 Webcam
* webcam
= WebcamPrivateAPI::Get(browser_context())
305 ->GetWebcam(extension_id(), params
->webcam_id
);
307 SetError(kUnknownWebcam
);
311 webcam_private::WebcamConfiguration result
;
314 if (webcam
->GetPan(&pan
))
315 result
.pan
.reset(new double(pan
));
318 if (webcam
->GetTilt(&tilt
))
319 result
.tilt
.reset(new double(tilt
));
322 if (webcam
->GetZoom(&zoom
))
323 result
.zoom
.reset(new double(zoom
));
325 SetResult(result
.ToValue().release());
330 WebcamPrivateResetFunction::WebcamPrivateResetFunction() {
333 WebcamPrivateResetFunction::~WebcamPrivateResetFunction() {
336 bool WebcamPrivateResetFunction::RunSync() {
337 scoped_ptr
<webcam_private::Reset::Params
> params(
338 webcam_private::Reset::Params::Create(*args_
));
339 EXTENSION_FUNCTION_VALIDATE(params
.get());
341 Webcam
* webcam
= WebcamPrivateAPI::Get(browser_context())
342 ->GetWebcam(extension_id(), params
->webcam_id
);
344 SetError(kUnknownWebcam
);
348 webcam
->Reset(params
->config
.pan
, params
->config
.tilt
, params
->config
.zoom
);
353 static base::LazyInstance
<BrowserContextKeyedAPIFactory
<WebcamPrivateAPI
>>
354 g_factory
= LAZY_INSTANCE_INITIALIZER
;
357 BrowserContextKeyedAPIFactory
<WebcamPrivateAPI
>*
358 WebcamPrivateAPI::GetFactoryInstance() {
359 return g_factory
.Pointer();
363 void BrowserContextKeyedAPIFactory
<WebcamPrivateAPI
>
364 ::DeclareFactoryDependencies() {
365 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
366 DependsOn(ProcessManagerFactory::GetInstance());
369 } // namespace extensions