Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(582)

Side by Side Diff: media/capture/video/chromeos/camera_hal_delegate.cc

Issue 2878233002: media: add ArcCamera3Service Mojo service (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/capture/video/chromeos/camera_hal_delegate.h" 5 #include "media/capture/video/chromeos/camera_hal_delegate.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <sys/uio.h> 8 #include <sys/uio.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/strings/string_piece.h" 12 #include "base/strings/string_piece.h"
13 #include "media/capture/video/chromeos/camera_metadata_utils.h" 13 #include "media/capture/video/chromeos/camera_metadata_utils.h"
14 #include "media/capture/video/chromeos/video_capture_device_arc_chromeos.h" 14 #include "media/capture/video/chromeos/video_capture_device_arc_chromeos.h"
15 #include "mojo/edk/embedder/embedder.h"
16 #include "mojo/edk/embedder/named_platform_handle.h"
17 #include "mojo/edk/embedder/named_platform_handle_utils.h"
18 #include "mojo/edk/embedder/pending_process_connection.h"
19 #include "mojo/edk/embedder/platform_channel_pair.h"
20 #include "mojo/edk/embedder/platform_channel_utils_posix.h"
21 #include "mojo/edk/embedder/platform_handle_vector.h"
22 15
23 namespace media { 16 namespace media {
24 17
25 namespace { 18 namespace {
26 19
27 const base::StringPiece kArcCamera3SocketPath("/var/run/camera/camera3.sock"); 20 const base::StringPiece kArcCamera3SocketPath("/var/run/camera/camera3.sock");
28 21
29 const base::TimeDelta kEventWaitTimeoutMs = 22 const base::TimeDelta kEventWaitTimeoutMs =
30 base::TimeDelta::FromMilliseconds(3000); 23 base::TimeDelta::FromMilliseconds(3000);
31 24
32 } // namespace 25 } // namespace
33 26
27 CameraHalDelegate::LocalCameraClient::LocalCameraClient(
28 scoped_refptr<CameraHalDelegate> camera_hal_delegate)
29 : camera_hal_delegate_(camera_hal_delegate) {}
30
31 void CameraHalDelegate::LocalCameraClient::NotifyCameraHalRegistered(
32 arc::mojom::CameraModulePtr camera_module) {
33 camera_hal_delegate_->SetCameraModule(camera_module.PassInterface());
34 }
35
34 CameraHalDelegate::CameraHalDelegate( 36 CameraHalDelegate::CameraHalDelegate(
35 const scoped_refptr<base::SingleThreadTaskRunner> module_task_runner) 37 const scoped_refptr<base::SingleThreadTaskRunner> module_task_runner)
36 : builtin_camera_info_updated_( 38 : camera_module_set_(base::WaitableEvent::ResetPolicy::MANUAL,
39 base::WaitableEvent::InitialState::NOT_SIGNALED),
40 builtin_camera_info_updated_(
37 base::WaitableEvent::ResetPolicy::MANUAL, 41 base::WaitableEvent::ResetPolicy::MANUAL,
38 base::WaitableEvent::InitialState::NOT_SIGNALED), 42 base::WaitableEvent::InitialState::NOT_SIGNALED),
39 num_builtin_cameras_(0), 43 num_builtin_cameras_(0),
40 module_task_runner_(module_task_runner), 44 module_task_runner_(module_task_runner),
41 camera_module_callbacks_(this) { 45 camera_module_callbacks_(this) {
42 // We need to detach |thread_checker_| here because constructor is called on 46 // We need to detach |thread_checker_| here because constructor is called on
43 // UI thread while the VideoCaptureDeviceFactory methods are called on capture 47 // UI thread while the VideoCaptureDeviceFactory methods are called on capture
44 // thread. 48 // thread.
45 thread_checker_.DetachFromThread(); 49 thread_checker_.DetachFromThread();
46 } 50 }
47 51
48 CameraHalDelegate::~CameraHalDelegate() { 52 CameraHalDelegate::~CameraHalDelegate() {
49 base::WaitableEvent interface_closed( 53 base::WaitableEvent interface_closed(
50 base::WaitableEvent::ResetPolicy::MANUAL, 54 base::WaitableEvent::ResetPolicy::MANUAL,
51 base::WaitableEvent::InitialState::NOT_SIGNALED); 55 base::WaitableEvent::InitialState::NOT_SIGNALED);
52 module_task_runner_->PostTask( 56 module_task_runner_->PostTask(
53 FROM_HERE, 57 FROM_HERE,
54 base::Bind(&CameraHalDelegate::ResetMojoInterfaceOnModuleThread, 58 base::Bind(&CameraHalDelegate::ResetMojoInterfaceOnModuleThread,
55 base::Unretained(this), base::Unretained(&interface_closed))); 59 base::Unretained(this), base::Unretained(&interface_closed)));
56 interface_closed.Wait(); 60 interface_closed.Wait();
57 } 61 }
58 62
59 bool CameraHalDelegate::StartCameraModuleIpc() { 63 void CameraHalDelegate::Start() {
60 // Non-blocking socket handle. 64 auto client_observer = base::MakeUnique<LocalCameraClient>(this);
61 mojo::edk::ScopedPlatformHandle socket_handle = mojo::edk::CreateClientHandle( 65 ArcCamera3Service::GetInstance()->AddClientObserver(
62 mojo::edk::NamedPlatformHandle(kArcCamera3SocketPath)); 66 std::move(client_observer));
67 }
63 68
64 // Set socket to blocking 69 void CameraHalDelegate::SetCameraModule(
65 int flags = HANDLE_EINTR(fcntl(socket_handle.get().handle, F_GETFL)); 70 arc::mojom::CameraModulePtrInfo camera_module_ptr_info) {
66 if (flags == -1) {
67 PLOG(ERROR) << "fcntl(F_GETFL) failed: ";
68 return false;
69 }
70 if (HANDLE_EINTR(fcntl(socket_handle.get().handle, F_SETFL,
71 flags & ~O_NONBLOCK)) == -1) {
72 PLOG(ERROR) << "fcntl(F_SETFL) failed: ";
73 return false;
74 }
75
76 const size_t kTokenSize = 32;
77 char token[kTokenSize] = {};
78 std::deque<mojo::edk::PlatformHandle> platform_handles;
79 ssize_t ret = mojo::edk::PlatformChannelRecvmsg(
80 socket_handle.get(), token, sizeof(token), &platform_handles, true);
81 if (ret == -1) {
82 PLOG(ERROR) << "PlatformChannelRecvmsg failed: ";
83 return false;
84 }
85 if (platform_handles.size() != 1) {
86 LOG(ERROR) << "Unexpected number of handles received, expected 1: "
87 << platform_handles.size();
88 return false;
89 }
90 mojo::edk::ScopedPlatformHandle parent_pipe(platform_handles.back());
91 platform_handles.pop_back();
92 if (!parent_pipe.is_valid()) {
93 LOG(ERROR) << "Invalid parent pipe";
94 return false;
95 }
96 mojo::edk::SetParentPipeHandle(std::move(parent_pipe));
97
98 mojo::ScopedMessagePipeHandle child_pipe =
99 mojo::edk::CreateChildMessagePipe(std::string(token, kTokenSize));
100
101 camera_module_ = 71 camera_module_ =
102 mojo::MakeProxy(mojo::InterfacePtrInfo<arc::mojom::CameraModule>( 72 mojo::MakeProxy(std::move(camera_module_ptr_info), module_task_runner_);
103 std::move(child_pipe), 0u), 73 camera_module_set_.Signal();
104 module_task_runner_); 74 module_task_runner_->PostTask(
105 75 FROM_HERE,
106 VLOG(1) << "Camera module IPC connection established"; 76 base::Bind(&CameraHalDelegate::SetConnectionErrorHandlerOnModuleThread,
107 77 this));
108 return true;
109 } 78 }
110 79
111 std::unique_ptr<VideoCaptureDevice> CameraHalDelegate::CreateDevice( 80 std::unique_ptr<VideoCaptureDevice> CameraHalDelegate::CreateDevice(
112 const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, 81 const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
113 const VideoCaptureDeviceDescriptor& device_descriptor) { 82 const VideoCaptureDeviceDescriptor& device_descriptor) {
114 DCHECK(thread_checker_.CalledOnValidThread()); 83 DCHECK(thread_checker_.CalledOnValidThread());
84 camera_module_set_.Wait();
115 std::unique_ptr<VideoCaptureDevice> capture_device; 85 std::unique_ptr<VideoCaptureDevice> capture_device;
116 if (!UpdateBuiltInCameraInfo()) { 86 if (!UpdateBuiltInCameraInfo()) {
117 return capture_device; 87 return capture_device;
118 } 88 }
119 if (camera_info_.find(device_descriptor.device_id) == camera_info_.end()) { 89 if (camera_info_.find(device_descriptor.device_id) == camera_info_.end()) {
120 LOG(ERROR) << "Invalid camera device: " << device_descriptor.device_id; 90 LOG(ERROR) << "Invalid camera device: " << device_descriptor.device_id;
121 return capture_device; 91 return capture_device;
122 } 92 }
123 capture_device.reset(new VideoCaptureDeviceArcChromeOS( 93 capture_device.reset(new VideoCaptureDeviceArcChromeOS(
124 ui_task_runner, device_descriptor, this)); 94 ui_task_runner, device_descriptor, this));
125 return capture_device; 95 return capture_device;
126 } 96 }
127 97
128 void CameraHalDelegate::GetSupportedFormats( 98 void CameraHalDelegate::GetSupportedFormats(
129 const VideoCaptureDeviceDescriptor& device_descriptor, 99 const VideoCaptureDeviceDescriptor& device_descriptor,
130 VideoCaptureFormats* supported_formats) { 100 VideoCaptureFormats* supported_formats) {
131 DCHECK(thread_checker_.CalledOnValidThread()); 101 DCHECK(thread_checker_.CalledOnValidThread());
132 102
103 camera_module_set_.Wait();
133 if (!UpdateBuiltInCameraInfo()) { 104 if (!UpdateBuiltInCameraInfo()) {
134 return; 105 return;
135 } 106 }
136 std::string camera_id = device_descriptor.device_id; 107 std::string camera_id = device_descriptor.device_id;
137 if (camera_info_.find(camera_id) == camera_info_.end() || 108 if (camera_info_.find(camera_id) == camera_info_.end() ||
138 camera_info_[camera_id].is_null()) { 109 camera_info_[camera_id].is_null()) {
139 // The camera may be removed already or is not ready yet. 110 // The camera may be removed already or is not ready yet.
140 VLOG(1) << "Invalid camera_id: " << camera_id; 111 VLOG(1) << "Invalid camera_id: " << camera_id;
141 return; 112 return;
142 } 113 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 VLOG(1) << "Supported format: " << width << "x" << height 164 VLOG(1) << "Supported format: " << width << "x" << height
194 << " fps=" << max_fps << " format=" << cr_format; 165 << " fps=" << max_fps << " format=" << cr_format;
195 supported_formats->emplace_back(gfx::Size(width, height), max_fps, 166 supported_formats->emplace_back(gfx::Size(width, height), max_fps,
196 cr_format); 167 cr_format);
197 } 168 }
198 } 169 }
199 170
200 void CameraHalDelegate::GetDeviceDescriptors( 171 void CameraHalDelegate::GetDeviceDescriptors(
201 VideoCaptureDeviceDescriptors* device_descriptors) { 172 VideoCaptureDeviceDescriptors* device_descriptors) {
202 DCHECK(thread_checker_.CalledOnValidThread()); 173 DCHECK(thread_checker_.CalledOnValidThread());
174 camera_module_set_.Wait();
203 175
204 if (!UpdateBuiltInCameraInfo()) { 176 if (!UpdateBuiltInCameraInfo()) {
205 return; 177 return;
206 } 178 }
207 for (size_t id = 0; id < num_builtin_cameras_; ++id) { 179 for (size_t id = 0; id < num_builtin_cameras_; ++id) {
208 VideoCaptureDeviceDescriptor desc; 180 VideoCaptureDeviceDescriptor desc;
209 std::string camera_id = std::to_string(id); 181 std::string camera_id = std::to_string(id);
210 const arc::mojom::CameraInfoPtr& camera_info = camera_info_[camera_id]; 182 const arc::mojom::CameraInfoPtr& camera_info = camera_info_[camera_id];
211 if (!camera_info) { 183 if (!camera_info) {
212 continue; 184 continue;
(...skipping 18 matching lines...) Expand all
231 // about malformed values. 203 // about malformed values.
232 } 204 }
233 device_descriptors->push_back(desc); 205 device_descriptors->push_back(desc);
234 } 206 }
235 } 207 }
236 208
237 void CameraHalDelegate::GetCameraInfo(int32_t camera_id, 209 void CameraHalDelegate::GetCameraInfo(int32_t camera_id,
238 const GetCameraInfoCallback& callback) { 210 const GetCameraInfoCallback& callback) {
239 // This method may be called on any thread. Currently this method is used by 211 // This method may be called on any thread. Currently this method is used by
240 // VideoCaptureDeviceArcChromeOS to query camera info. 212 // VideoCaptureDeviceArcChromeOS to query camera info.
213 camera_module_set_.Wait();
241 module_task_runner_->PostTask( 214 module_task_runner_->PostTask(
242 FROM_HERE, base::Bind(&CameraHalDelegate::GetCameraInfoOnModuleThread, 215 FROM_HERE, base::Bind(&CameraHalDelegate::GetCameraInfoOnModuleThread,
243 this, camera_id, callback)); 216 this, camera_id, callback));
244 } 217 }
245 218
246 void CameraHalDelegate::OpenDevice(int32_t camera_id, 219 void CameraHalDelegate::OpenDevice(int32_t camera_id,
247 const OpenDeviceCallback& callback) { 220 const OpenDeviceCallback& callback) {
248 // This method may be called on any thread. Currently this method is used by 221 // This method may be called on any thread. Currently this method is used by
249 // VideoCaptureDeviceArcChromeOS to open a camera device. 222 // VideoCaptureDeviceArcChromeOS to open a camera device.
223 camera_module_set_.Wait();
250 module_task_runner_->PostTask( 224 module_task_runner_->PostTask(
251 FROM_HERE, base::Bind(&CameraHalDelegate::OpenDeviceOnModuleThread, this, 225 FROM_HERE, base::Bind(&CameraHalDelegate::OpenDeviceOnModuleThread, this,
252 camera_id, callback)); 226 camera_id, callback));
253 } 227 }
254 228
229 void CameraHalDelegate::SetConnectionErrorHandlerOnModuleThread() {
230 DCHECK(module_task_runner_->BelongsToCurrentThread());
231 DCHECK(camera_module_set_.IsSignaled());
232 camera_module_.set_connection_error_handler(base::Bind(
233 &CameraHalDelegate::HandleMojoConnectionErrorOnModuleThread, this));
234 }
235
236 void CameraHalDelegate::HandleMojoConnectionErrorOnModuleThread() {
237 DCHECK(module_task_runner_->BelongsToCurrentThread());
238 camera_module_.reset();
239 if (camera_module_callbacks_.is_bound()) {
240 camera_module_callbacks_.Unbind();
241 }
242 camera_module_set_.Reset();
243 }
244
255 void CameraHalDelegate::ResetMojoInterfaceOnModuleThread( 245 void CameraHalDelegate::ResetMojoInterfaceOnModuleThread(
256 base::WaitableEvent* interface_closed) { 246 base::WaitableEvent* interface_closed) {
257 DCHECK(module_task_runner_->BelongsToCurrentThread()); 247 DCHECK(module_task_runner_->BelongsToCurrentThread());
258 camera_module_.reset(); 248 camera_module_.reset();
259 if (camera_module_callbacks_.is_bound()) { 249 if (camera_module_callbacks_.is_bound()) {
260 camera_module_callbacks_.Unbind(); 250 camera_module_callbacks_.Unbind();
261 } 251 }
262 interface_closed->Signal(); 252 interface_closed->Signal();
263 } 253 }
264 254
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 351
362 // CameraModuleCallbacks implementations. 352 // CameraModuleCallbacks implementations.
363 void CameraHalDelegate::CameraDeviceStatusChange( 353 void CameraHalDelegate::CameraDeviceStatusChange(
364 int32_t camera_id, 354 int32_t camera_id,
365 arc::mojom::CameraDeviceStatus new_status) { 355 arc::mojom::CameraDeviceStatus new_status) {
366 DCHECK(module_task_runner_->BelongsToCurrentThread()); 356 DCHECK(module_task_runner_->BelongsToCurrentThread());
367 // TODO(jcliang): Handle status change for external cameras. 357 // TODO(jcliang): Handle status change for external cameras.
368 } 358 }
369 359
370 } // namespace media 360 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698