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 "content/public/common/media_stream_request.h"
12 #include "extensions/browser/api/webcam_private/v4l2_webcam.h"
13 #include "extensions/browser/api/webcam_private/webcam.h"
14 #include "extensions/browser/process_manager.h"
15 #include "extensions/browser/process_manager_factory.h"
16 #include "extensions/common/api/webcam_private.h"
18 namespace webcam_private
= extensions::core_api::webcam_private
;
22 } // namespace content
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 process_manager_observer_(this),
38 weak_ptr_factory_(this) {
39 process_manager_observer_
.Add(ProcessManager::Get(browser_context_
));
42 WebcamPrivateAPI::~WebcamPrivateAPI() {}
44 Webcam
* WebcamPrivateAPI::GetWebcam(const std::string
& extension_id
,
45 const std::string
& webcam_id
) {
46 std::string device_id
;
47 if (!GetDeviceId(extension_id
, webcam_id
, &device_id
)) {
51 auto ix
= webcams_
.find(device_id
);
52 if (ix
!= webcams_
.end()) {
53 ix
->second
->AddExtensionRef(extension_id
);
54 return ix
->second
.get();
57 scoped_ptr
<V4L2Webcam
> v4l2_webcam(new V4L2Webcam(device_id
));
58 if (!v4l2_webcam
->Open()) {
62 linked_ptr
<Webcam
> webcam(v4l2_webcam
.release());
64 webcams_
[device_id
] = webcam
;
65 webcam
->AddExtensionRef(extension_id
);
70 bool WebcamPrivateAPI::GetDeviceId(const std::string
& extension_id
,
71 const std::string
& webcam_id
,
72 std::string
* device_id
) {
73 GURL security_origin
=
74 extensions::Extension::GetBaseURLFromExtensionId(extension_id
);
76 return content::GetMediaDeviceIDForHMAC(
77 content::MEDIA_DEVICE_VIDEO_CAPTURE
,
78 browser_context_
->GetResourceContext()->GetMediaDeviceIDSalt(),
84 void WebcamPrivateAPI::OnBackgroundHostClose(const std::string
& extension_id
) {
85 for (auto webcam
= webcams_
.begin();
86 webcam
!= webcams_
.end(); /* No increment */ ) {
87 auto next
= std::next(webcam
);
88 webcam
->second
->RemoveExtensionRef(extension_id
);
89 if (webcam
->second
->ShouldDelete())
90 webcams_
.erase(webcam
);
95 WebcamPrivateSetFunction::WebcamPrivateSetFunction() {
98 WebcamPrivateSetFunction::~WebcamPrivateSetFunction() {
101 bool WebcamPrivateSetFunction::RunSync() {
103 scoped_ptr
<webcam_private::Set::Params
> params(
104 webcam_private::Set::Params::Create(*args_
));
105 EXTENSION_FUNCTION_VALIDATE(params
.get());
107 Webcam
* webcam
= WebcamPrivateAPI::Get(browser_context())->
108 GetWebcam(extension_id(), params
->webcam_id
);
110 SetError(kUnknownWebcam
);
114 if (params
->config
.pan
) {
115 webcam
->SetPan(*(params
->config
.pan
));
118 if (params
->config
.pan_direction
) {
119 Webcam::PanDirection direction
= Webcam::PAN_STOP
;
120 switch (params
->config
.pan_direction
) {
121 case webcam_private::PAN_DIRECTION_NONE
:
122 case webcam_private::PAN_DIRECTION_STOP
:
123 direction
= Webcam::PAN_STOP
;
126 case webcam_private::PAN_DIRECTION_RIGHT
:
127 direction
= Webcam::PAN_RIGHT
;
130 case webcam_private::PAN_DIRECTION_LEFT
:
131 direction
= Webcam::PAN_LEFT
;
134 webcam
->SetPanDirection(direction
);
137 if (params
->config
.tilt
) {
138 webcam
->SetTilt(*(params
->config
.tilt
));
141 if (params
->config
.tilt_direction
) {
142 Webcam::TiltDirection direction
= Webcam::TILT_STOP
;
143 switch (params
->config
.tilt_direction
) {
144 case webcam_private::TILT_DIRECTION_NONE
:
145 case webcam_private::TILT_DIRECTION_STOP
:
146 direction
= Webcam::TILT_STOP
;
149 case webcam_private::TILT_DIRECTION_UP
:
150 direction
= Webcam::TILT_UP
;
153 case webcam_private::TILT_DIRECTION_DOWN
:
154 direction
= Webcam::TILT_DOWN
;
157 webcam
->SetTiltDirection(direction
);
160 if (params
->config
.zoom
) {
161 webcam
->SetZoom(*(params
->config
.zoom
));
168 WebcamPrivateGetFunction::WebcamPrivateGetFunction() {
171 WebcamPrivateGetFunction::~WebcamPrivateGetFunction() {
174 bool WebcamPrivateGetFunction::RunSync() {
176 scoped_ptr
<webcam_private::Get::Params
> params(
177 webcam_private::Get::Params::Create(*args_
));
178 EXTENSION_FUNCTION_VALIDATE(params
.get());
180 Webcam
* webcam
= WebcamPrivateAPI::Get(browser_context())->
181 GetWebcam(extension_id(), params
->webcam_id
);
183 SetError(kUnknownWebcam
);
187 webcam_private::WebcamConfiguration result
;
190 if (webcam
->GetPan(&pan
))
191 result
.pan
.reset(new double(pan
));
194 if (webcam
->GetTilt(&tilt
))
195 result
.tilt
.reset(new double(tilt
));
198 if (webcam
->GetZoom(&zoom
))
199 result
.zoom
.reset(new double(zoom
));
201 SetResult(result
.ToValue().release());
206 WebcamPrivateResetFunction::WebcamPrivateResetFunction() {
209 WebcamPrivateResetFunction::~WebcamPrivateResetFunction() {
212 bool WebcamPrivateResetFunction::RunSync() {
214 scoped_ptr
<webcam_private::Reset::Params
> params(
215 webcam_private::Reset::Params::Create(*args_
));
216 EXTENSION_FUNCTION_VALIDATE(params
.get());
218 Webcam
* webcam
= WebcamPrivateAPI::Get(browser_context())->
219 GetWebcam(extension_id(), params
->webcam_id
);
221 SetError(kUnknownWebcam
);
225 webcam
->Reset(params
->config
.pan
, params
->config
.tilt
, params
->config
.zoom
);
230 static base::LazyInstance
<BrowserContextKeyedAPIFactory
<WebcamPrivateAPI
>>
231 g_factory
= LAZY_INSTANCE_INITIALIZER
;
234 BrowserContextKeyedAPIFactory
<WebcamPrivateAPI
>*
235 WebcamPrivateAPI::GetFactoryInstance() {
236 return g_factory
.Pointer();
240 void BrowserContextKeyedAPIFactory
<WebcamPrivateAPI
>
241 ::DeclareFactoryDependencies() {
242 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
243 DependsOn(ProcessManagerFactory::GetInstance());
246 } // namespace extensions