1 // Copyright (c) 2012 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 "chrome/browser/chromeos/camera_detector.h"
8 #include "base/files/file_enumerator.h"
9 #include "base/files/file_util.h"
10 #include "base/location.h"
11 #include "base/strings/string_split.h"
12 #include "base/strings/string_util.h"
13 #include "base/task_runner_util.h"
14 #include "base/threading/sequenced_worker_pool.h"
15 #include "components/storage_monitor/udev_util_linux.h"
16 #include "content/public/browser/browser_thread.h"
22 // Sysfs directory containing V4L devices.
23 const char kV4LSubsystemDir
[] = "/sys/class/video4linux/";
24 // Name of the udev property with V4L capabilities.
25 const char kV4LCapabilities
[] = "ID_V4L_CAPABILITIES";
26 // Delimiter character for udev V4L capabilities.
27 const char kV4LCapabilitiesDelim
= ':';
28 // V4L capability that denotes a capture-enabled device.
29 const char kV4LCaptureCapability
[] = "capture";
33 using content::BrowserThread
;
36 CameraDetector::CameraPresence
CameraDetector::camera_presence_
=
37 CameraDetector::kCameraPresenceUnknown
;
40 bool CameraDetector::presence_check_in_progress_
= false;
43 void CameraDetector::StartPresenceCheck(const base::Closure
& callback
) {
44 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
45 if (presence_check_in_progress_
)
47 DVLOG(1) << "Starting camera presence check";
48 presence_check_in_progress_
= true;
49 base::PostTaskAndReplyWithResult(
50 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
51 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN
).get(),
53 base::Bind(&CameraDetector::CheckPresence
),
54 base::Bind(&CameraDetector::OnPresenceCheckDone
, callback
));
58 void CameraDetector::OnPresenceCheckDone(const base::Closure
& callback
,
60 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
61 camera_presence_
= present
? kCameraPresent
: kCameraAbsent
;
62 presence_check_in_progress_
= false;
67 bool CameraDetector::CheckPresence() {
68 // We do a quick check using udev database because opening each /dev/videoX
69 // device may trigger costly device initialization.
70 base::FileEnumerator
file_enum(
71 base::FilePath(kV4LSubsystemDir
), false /* not recursive */,
72 base::FileEnumerator::FILES
| base::FileEnumerator::SHOW_SYM_LINKS
);
73 for (base::FilePath path
= file_enum
.Next(); !path
.empty();
74 path
= file_enum
.Next()) {
75 std::string v4l_capabilities
;
76 if (storage_monitor::GetUdevDevicePropertyValueByPath(
77 path
, kV4LCapabilities
, &v4l_capabilities
)) {
78 std::vector
<std::string
> caps
= base::SplitString(
79 v4l_capabilities
, std::string(1, kV4LCapabilitiesDelim
),
80 base::TRIM_WHITESPACE
, base::SPLIT_WANT_ALL
);
81 if (find(caps
.begin(), caps
.end(), kV4LCaptureCapability
) != caps
.end()) {
89 } // namespace chromeos