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

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

Issue 2878233002: media: add ArcCamera3Service Mojo service (Closed)
Patch Set: rebase on latest patch set of issue 2837273004 Created 3 years, 6 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 <algorithm> 10 #include <algorithm>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/bind_helpers.h" 14 #include "base/bind_helpers.h"
15 #include "base/strings/string_piece.h" 15 #include "base/strings/string_piece.h"
16 #include "media/capture/video/chromeos/camera_metadata_utils.h" 16 #include "media/capture/video/chromeos/camera_metadata_utils.h"
17 #include "media/capture/video/chromeos/pixel_format_utils.h" 17 #include "media/capture/video/chromeos/pixel_format_utils.h"
18 #include "media/capture/video/chromeos/video_capture_device_arc_chromeos.h" 18 #include "media/capture/video/chromeos/video_capture_device_arc_chromeos.h"
19 #include "mojo/edk/embedder/embedder.h"
20 #include "mojo/edk/embedder/incoming_broker_client_invitation.h"
21 #include "mojo/edk/embedder/named_platform_handle.h"
22 #include "mojo/edk/embedder/named_platform_handle_utils.h"
23 #include "mojo/edk/embedder/platform_channel_pair.h"
24 #include "mojo/edk/embedder/platform_channel_utils_posix.h"
25 #include "mojo/edk/embedder/platform_handle_vector.h"
26 19
27 namespace media { 20 namespace media {
28 21
29 namespace { 22 namespace {
30 23
31 const base::StringPiece kArcCamera3SocketPath("/var/run/camera/camera3.sock"); 24 const base::StringPiece kArcCamera3SocketPath("/var/run/camera/camera3.sock");
32 25
33 const base::TimeDelta kEventWaitTimeoutMs = 26 const base::TimeDelta kEventWaitTimeoutMs =
34 base::TimeDelta::FromMilliseconds(3000); 27 base::TimeDelta::FromMilliseconds(3000);
35 28
36 } // namespace 29 } // namespace
37 30
31 CameraHalDelegate::LocalCameraClient::LocalCameraClient(
32 scoped_refptr<CameraHalDelegate> camera_hal_delegate)
33 : camera_hal_delegate_(camera_hal_delegate) {}
34
35 void CameraHalDelegate::LocalCameraClient::NotifyCameraHalRegistered(
36 arc::mojom::CameraModulePtr camera_module) {
37 camera_hal_delegate_->SetCameraModule(camera_module.PassInterface());
38 }
39
38 CameraHalDelegate::CameraHalDelegate( 40 CameraHalDelegate::CameraHalDelegate(
39 scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner) 41 scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner)
40 : builtin_camera_info_updated_( 42 : camera_module_set_(base::WaitableEvent::ResetPolicy::MANUAL,
43 base::WaitableEvent::InitialState::NOT_SIGNALED),
44 builtin_camera_info_updated_(
41 base::WaitableEvent::ResetPolicy::MANUAL, 45 base::WaitableEvent::ResetPolicy::MANUAL,
42 base::WaitableEvent::InitialState::NOT_SIGNALED), 46 base::WaitableEvent::InitialState::NOT_SIGNALED),
43 num_builtin_cameras_(0), 47 num_builtin_cameras_(0),
44 ipc_task_runner_(std::move(ipc_task_runner)), 48 ipc_task_runner_(std::move(ipc_task_runner)),
45 camera_module_callbacks_(this) { 49 camera_module_callbacks_(this) {
46 DETACH_FROM_SEQUENCE(sequence_checker_); 50 DETACH_FROM_SEQUENCE(sequence_checker_);
47 } 51 }
48 52
49 CameraHalDelegate::~CameraHalDelegate() {} 53 CameraHalDelegate::~CameraHalDelegate() {}
50 54
51 bool CameraHalDelegate::StartCameraModuleIpc() { 55 void CameraHalDelegate::RegisterCameraClient() {
52 // Non-blocking socket handle. 56 auto client_observer = base::MakeUnique<LocalCameraClient>(this);
53 mojo::edk::ScopedPlatformHandle socket_handle = mojo::edk::CreateClientHandle( 57 ArcCamera3Service::GetInstance()->AddClientObserver(
54 mojo::edk::NamedPlatformHandle(kArcCamera3SocketPath)); 58 std::move(client_observer));
59 }
55 60
56 // Set socket to blocking 61 void CameraHalDelegate::SetCameraModule(
57 int flags = HANDLE_EINTR(fcntl(socket_handle.get().handle, F_GETFL)); 62 arc::mojom::CameraModulePtrInfo camera_module_ptr_info) {
58 if (flags == -1) {
59 PLOG(ERROR) << "fcntl(F_GETFL) failed: ";
60 return false;
61 }
62 if (HANDLE_EINTR(fcntl(socket_handle.get().handle, F_SETFL,
63 flags & ~O_NONBLOCK)) == -1) {
64 PLOG(ERROR) << "fcntl(F_SETFL) failed: ";
65 return false;
66 }
67
68 const size_t kTokenSize = 32;
69 char token[kTokenSize] = {};
70 std::deque<mojo::edk::PlatformHandle> platform_handles;
71 ssize_t ret = mojo::edk::PlatformChannelRecvmsg(
72 socket_handle.get(), token, sizeof(token), &platform_handles, true);
73 if (ret == -1) {
74 PLOG(ERROR) << "PlatformChannelRecvmsg failed: ";
75 return false;
76 }
77 if (platform_handles.size() != 1) {
78 LOG(ERROR) << "Unexpected number of handles received, expected 1: "
79 << platform_handles.size();
80 return false;
81 }
82 mojo::edk::ScopedPlatformHandle parent_pipe(platform_handles.back());
83 platform_handles.pop_back();
84 if (!parent_pipe.is_valid()) {
85 LOG(ERROR) << "Invalid parent pipe";
86 return false;
87 }
88 std::unique_ptr<mojo::edk::IncomingBrokerClientInvitation> invitation =
89 mojo::edk::IncomingBrokerClientInvitation::Accept(
90 mojo::edk::ConnectionParams(mojo::edk::TransportProtocol::kLegacy,
91 std::move(parent_pipe)));
92 mojo::ScopedMessagePipeHandle child_pipe =
93 invitation->ExtractMessagePipe(token);
94 DCHECK(child_pipe.is_valid());
95
96 camera_module_ = 63 camera_module_ =
97 mojo::MakeProxy(mojo::InterfacePtrInfo<arc::mojom::CameraModule>( 64 mojo::MakeProxy(std::move(camera_module_ptr_info), ipc_task_runner_);
98 std::move(child_pipe), 0u), 65 camera_module_set_.Signal();
99 ipc_task_runner_); 66 ipc_task_runner_->PostTask(
100 67 FROM_HERE,
101 VLOG(1) << "Camera module IPC connection established"; 68 base::Bind(&CameraHalDelegate::SetConnectionErrorHandlerOnModuleThread,
102 69 this));
103 return true;
104 } 70 }
105 71
106 void CameraHalDelegate::Reset() { 72 void CameraHalDelegate::Reset() {
107 ipc_task_runner_->PostTask( 73 ipc_task_runner_->PostTask(
108 FROM_HERE, 74 FROM_HERE,
109 base::Bind(&CameraHalDelegate::ResetMojoInterfaceOnModuleThread, this)); 75 base::Bind(&CameraHalDelegate::ResetMojoInterfaceOnModuleThread, this));
110 } 76 }
111 77
112 std::unique_ptr<VideoCaptureDevice> CameraHalDelegate::CreateDevice( 78 std::unique_ptr<VideoCaptureDevice> CameraHalDelegate::CreateDevice(
113 scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_screen_observer, 79 scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_screen_observer,
114 const VideoCaptureDeviceDescriptor& device_descriptor) { 80 const VideoCaptureDeviceDescriptor& device_descriptor) {
115 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 81 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
82 camera_module_set_.Wait();
116 std::unique_ptr<VideoCaptureDevice> capture_device; 83 std::unique_ptr<VideoCaptureDevice> capture_device;
117 if (!UpdateBuiltInCameraInfo()) { 84 if (!UpdateBuiltInCameraInfo()) {
118 return capture_device; 85 return capture_device;
119 } 86 }
120 if (camera_info_.find(device_descriptor.device_id) == camera_info_.end()) { 87 if (camera_info_.find(device_descriptor.device_id) == camera_info_.end()) {
121 LOG(ERROR) << "Invalid camera device: " << device_descriptor.device_id; 88 LOG(ERROR) << "Invalid camera device: " << device_descriptor.device_id;
122 return capture_device; 89 return capture_device;
123 } 90 }
124 capture_device.reset(new VideoCaptureDeviceArcChromeOS( 91 capture_device.reset(new VideoCaptureDeviceArcChromeOS(
125 std::move(task_runner_for_screen_observer), device_descriptor, this)); 92 std::move(task_runner_for_screen_observer), device_descriptor, this));
126 return capture_device; 93 return capture_device;
127 } 94 }
128 95
129 void CameraHalDelegate::GetSupportedFormats( 96 void CameraHalDelegate::GetSupportedFormats(
130 const VideoCaptureDeviceDescriptor& device_descriptor, 97 const VideoCaptureDeviceDescriptor& device_descriptor,
131 VideoCaptureFormats* supported_formats) { 98 VideoCaptureFormats* supported_formats) {
132 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 99 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
133 100
101 camera_module_set_.Wait();
134 if (!UpdateBuiltInCameraInfo()) { 102 if (!UpdateBuiltInCameraInfo()) {
135 return; 103 return;
136 } 104 }
137 std::string camera_id = device_descriptor.device_id; 105 std::string camera_id = device_descriptor.device_id;
138 if (camera_info_.find(camera_id) == camera_info_.end() || 106 if (camera_info_.find(camera_id) == camera_info_.end() ||
139 camera_info_[camera_id].is_null()) { 107 camera_info_[camera_id].is_null()) {
140 LOG(ERROR) << "Invalid camera_id: " << camera_id; 108 LOG(ERROR) << "Invalid camera_id: " << camera_id;
141 return; 109 return;
142 } 110 }
143 const arc::mojom::CameraInfoPtr& camera_info = camera_info_[camera_id]; 111 const arc::mojom::CameraInfoPtr& camera_info = camera_info_[camera_id];
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 VLOG(1) << "Supported format: " << width << "x" << height 148 VLOG(1) << "Supported format: " << width << "x" << height
181 << " fps=" << max_fps << " format=" << cr_format; 149 << " fps=" << max_fps << " format=" << cr_format;
182 supported_formats->emplace_back(gfx::Size(width, height), max_fps, 150 supported_formats->emplace_back(gfx::Size(width, height), max_fps,
183 cr_format); 151 cr_format);
184 } 152 }
185 } 153 }
186 154
187 void CameraHalDelegate::GetDeviceDescriptors( 155 void CameraHalDelegate::GetDeviceDescriptors(
188 VideoCaptureDeviceDescriptors* device_descriptors) { 156 VideoCaptureDeviceDescriptors* device_descriptors) {
189 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 157 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
158 camera_module_set_.Wait();
190 159
191 if (!UpdateBuiltInCameraInfo()) { 160 if (!UpdateBuiltInCameraInfo()) {
192 return; 161 return;
193 } 162 }
194 for (size_t id = 0; id < num_builtin_cameras_; ++id) { 163 for (size_t id = 0; id < num_builtin_cameras_; ++id) {
195 VideoCaptureDeviceDescriptor desc; 164 VideoCaptureDeviceDescriptor desc;
196 std::string camera_id = std::to_string(id); 165 std::string camera_id = std::to_string(id);
197 const arc::mojom::CameraInfoPtr& camera_info = camera_info_[camera_id]; 166 const arc::mojom::CameraInfoPtr& camera_info = camera_info_[camera_id];
198 if (!camera_info) { 167 if (!camera_info) {
199 continue; 168 continue;
(...skipping 21 matching lines...) Expand all
221 } 190 }
222 // TODO(jcliang): Remove this after JS API supports query camera facing 191 // TODO(jcliang): Remove this after JS API supports query camera facing
223 // (http://crbug.com/543997). 192 // (http://crbug.com/543997).
224 std::sort(device_descriptors->begin(), device_descriptors->end()); 193 std::sort(device_descriptors->begin(), device_descriptors->end());
225 } 194 }
226 195
227 void CameraHalDelegate::GetCameraInfo(int32_t camera_id, 196 void CameraHalDelegate::GetCameraInfo(int32_t camera_id,
228 const GetCameraInfoCallback& callback) { 197 const GetCameraInfoCallback& callback) {
229 // This method may be called on any thread. Currently this method is used by 198 // This method may be called on any thread. Currently this method is used by
230 // CameraDeviceDelegate to query camera info. 199 // CameraDeviceDelegate to query camera info.
200 camera_module_set_.Wait();
231 ipc_task_runner_->PostTask( 201 ipc_task_runner_->PostTask(
232 FROM_HERE, base::Bind(&CameraHalDelegate::GetCameraInfoOnModuleThread, 202 FROM_HERE, base::Bind(&CameraHalDelegate::GetCameraInfoOnModuleThread,
233 this, camera_id, callback)); 203 this, camera_id, callback));
234 } 204 }
235 205
236 void CameraHalDelegate::OpenDevice( 206 void CameraHalDelegate::OpenDevice(
237 int32_t camera_id, 207 int32_t camera_id,
238 arc::mojom::Camera3DeviceOpsRequest device_ops_request, 208 arc::mojom::Camera3DeviceOpsRequest device_ops_request,
239 const OpenDeviceCallback& callback) { 209 const OpenDeviceCallback& callback) {
240 // This method may be called on any thread. Currently this method is used by 210 // This method may be called on any thread. Currently this method is used by
241 // CameraDeviceDelegate to open a camera device. 211 // CameraDeviceDelegate to open a camera device.
212 camera_module_set_.Wait();
242 ipc_task_runner_->PostTask( 213 ipc_task_runner_->PostTask(
243 FROM_HERE, 214 FROM_HERE,
244 base::Bind(&CameraHalDelegate::OpenDeviceOnModuleThread, this, camera_id, 215 base::Bind(&CameraHalDelegate::OpenDeviceOnModuleThread, this, camera_id,
245 base::Passed(&device_ops_request), callback)); 216 base::Passed(&device_ops_request), callback));
246 } 217 }
247 218
248 void CameraHalDelegate::StartForTesting(arc::mojom::CameraModulePtrInfo info) { 219 void CameraHalDelegate::SetConnectionErrorHandlerOnModuleThread() {
249 camera_module_.Bind(std::move(info), ipc_task_runner_); 220 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
221 DCHECK(camera_module_set_.IsSignaled());
222 camera_module_.set_connection_error_handler(base::Bind(
223 &CameraHalDelegate::HandleMojoConnectionErrorOnModuleThread, this));
224 }
225
226 void CameraHalDelegate::HandleMojoConnectionErrorOnModuleThread() {
227 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
228 camera_module_.reset();
229 if (camera_module_callbacks_.is_bound()) {
230 camera_module_callbacks_.Unbind();
231 }
232 camera_module_set_.Reset();
250 } 233 }
251 234
252 void CameraHalDelegate::ResetMojoInterfaceOnModuleThread() { 235 void CameraHalDelegate::ResetMojoInterfaceOnModuleThread() {
253 DCHECK(ipc_task_runner_->BelongsToCurrentThread()); 236 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
254 camera_module_.reset(); 237 camera_module_.reset();
255 if (camera_module_callbacks_.is_bound()) { 238 if (camera_module_callbacks_.is_bound()) {
256 camera_module_callbacks_.Close(); 239 camera_module_callbacks_.Close();
257 } 240 }
258 } 241 }
259 242
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 339
357 // CameraModuleCallbacks implementations. 340 // CameraModuleCallbacks implementations.
358 void CameraHalDelegate::CameraDeviceStatusChange( 341 void CameraHalDelegate::CameraDeviceStatusChange(
359 int32_t camera_id, 342 int32_t camera_id,
360 arc::mojom::CameraDeviceStatus new_status) { 343 arc::mojom::CameraDeviceStatus new_status) {
361 DCHECK(ipc_task_runner_->BelongsToCurrentThread()); 344 DCHECK(ipc_task_runner_->BelongsToCurrentThread());
362 // TODO(jcliang): Handle status change for external cameras. 345 // TODO(jcliang): Handle status change for external cameras.
363 } 346 }
364 347
365 } // namespace media 348 } // namespace media
OLDNEW
« no previous file with comments | « media/capture/video/chromeos/camera_hal_delegate.h ('k') | media/capture/video/chromeos/camera_hal_delegate_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698