camera: usb: Still enable USB HAL when CrOS config fails
CrOS config may fail because the device identity (sku id, firmware
version, etc) is mis-configured in firmware or config files. Do not
block USB camera basic functionality in this case.
The CrosDeviceConfig is refactored to avoid accessing uninitialized
data.
BUG=b:174197592,b:169781914
TEST=Deploy and check USB HAL initialization.
Change-Id: I4f79a34e9fe5e84c96c7196c27d26552ec33abb5
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2562990
Commit-Queue: Ren-Pei Zeng <kamesan@chromium.org>
Tested-by: Ren-Pei Zeng <kamesan@chromium.org>
Reviewed-by: Shik Chen <shik@chromium.org>
diff --git a/camera/hal/usb/camera_hal.cc b/camera/hal/usb/camera_hal.cc
index 47a4492..df0116b 100644
--- a/camera/hal/usb/camera_hal.cc
+++ b/camera/hal/usb/camera_hal.cc
@@ -111,7 +111,7 @@
CameraHal::CameraHal()
: task_runner_(nullptr),
udev_watcher_(std::make_unique<UdevWatcher>(this, "video4linux")),
- cros_device_config_(CrosDeviceConfig::Get()) {
+ cros_device_config_(CrosDeviceConfig::Create()) {
thread_checker_.DetachFromThread();
}
@@ -146,9 +146,11 @@
LOGF(ERROR) << "Camera " << id << " is already opened";
return -EBUSY;
}
- if (!cameras_.empty() && (cros_device_config_.model_name == "treeya360" ||
- cros_device_config_.model_name == "nuwani360" ||
- cros_device_config_.model_name == "pompom")) {
+ if (!cameras_.empty() &&
+ (cros_device_config_ != nullptr &&
+ (cros_device_config_->GetModelName() == "treeya360" ||
+ cros_device_config_->GetModelName() == "nuwani360" ||
+ cros_device_config_->GetModelName() == "pompom"))) {
// It cannot open multiple cameras at the same time due to USB bandwidth
// limitation (b/147333530, b/171856355).
// TODO(shik): Use |conflicting_devices| to implement this logic after we
@@ -227,9 +229,9 @@
int CameraHal::Init() {
DCHECK(thread_checker_.CalledOnValidThread());
- if (!cros_device_config_.is_initialized) {
- LOGF(ERROR) << "Failed to initialize CrOS device config";
- return -ENODEV;
+ if (cros_device_config_ == nullptr) {
+ LOGF(WARNING) << "Failed to initialize CrOS device config, camera HAL may "
+ "function incorrectly";
}
if (!udev_watcher_->Start(base::ThreadTaskRunnerHandle::Get())) {
@@ -270,9 +272,10 @@
num_builtin_cameras_ = 1;
}
- if (cros_device_config_.usb_camera_count.has_value()) {
- if (num_builtin_cameras_ != *cros_device_config_.usb_camera_count) {
- LOGF(ERROR) << "Expected " << *cros_device_config_.usb_camera_count
+ if (cros_device_config_ != nullptr &&
+ cros_device_config_->IsUsbCameraCountAvailable()) {
+ if (num_builtin_cameras_ != cros_device_config_->GetUsbCameraCount()) {
+ LOGF(ERROR) << "Expected " << cros_device_config_->GetUsbCameraCount()
<< " cameras from Chrome OS config, found "
<< num_builtin_cameras_;
return -ENODEV;
@@ -429,7 +432,8 @@
// Mark the camera as v1 if it is a built-in camera and the CrOS device is
// marked as a v1 device.
- if (info_ptr != nullptr && cros_device_config_.is_v1_device) {
+ if (info_ptr != nullptr && cros_device_config_ != nullptr &&
+ cros_device_config_->IsV1Device()) {
info.quirks |= kQuirkV1Device;
}
diff --git a/camera/hal/usb/camera_hal.h b/camera/hal/usb/camera_hal.h
index c108bc0..3ccf7ae 100644
--- a/camera/hal/usb/camera_hal.h
+++ b/camera/hal/usb/camera_hal.h
@@ -100,7 +100,7 @@
std::unique_ptr<UdevWatcher> udev_watcher_;
// Used to access to the main configuration for Chrome OS.
- CrosDeviceConfig cros_device_config_;
+ std::unique_ptr<CrosDeviceConfig> cros_device_config_;
// Map from device path to camera id.
std::map<std::string, int> path_to_id_;
diff --git a/camera/hal/usb/cros_device_config.cc b/camera/hal/usb/cros_device_config.cc
index 932acd2..093b7ee 100644
--- a/camera/hal/usb/cros_device_config.cc
+++ b/camera/hal/usb/cros_device_config.cc
@@ -20,22 +20,18 @@
} // namespace
-CrosDeviceConfig::CrosDeviceConfig() {}
-
-CrosDeviceConfig::~CrosDeviceConfig() {}
-
-CrosDeviceConfig CrosDeviceConfig::Get() {
+std::unique_ptr<CrosDeviceConfig> CrosDeviceConfig::Create() {
CrosDeviceConfig res = {};
brillo::CrosConfig cros_config;
if (!cros_config.Init()) {
LOGF(ERROR) << "Failed to initialize CrOS config";
- return res;
+ return nullptr;
}
if (!cros_config.GetString("/", "name", &res.model_name)) {
LOGF(ERROR) << "Failed to get model name of CrOS device";
- return res;
+ return nullptr;
}
std::string use_legacy_usb;
@@ -80,8 +76,7 @@
return count;
}();
- res.is_initialized = true;
- return res;
+ return std::make_unique<CrosDeviceConfig>(res);
}
} // namespace cros
diff --git a/camera/hal/usb/cros_device_config.h b/camera/hal/usb/cros_device_config.h
index 52452a7..1f6390b 100644
--- a/camera/hal/usb/cros_device_config.h
+++ b/camera/hal/usb/cros_device_config.h
@@ -7,6 +7,7 @@
#ifndef CAMERA_HAL_USB_CROS_DEVICE_CONFIG_H_
#define CAMERA_HAL_USB_CROS_DEVICE_CONFIG_H_
+#include <memory>
#include <string>
#include <base/optional.h>
@@ -15,16 +16,20 @@
namespace cros {
// This structs wraps the brillo::CrosConfig and stores the required values.
-struct CrosDeviceConfig {
+class CrosDeviceConfig {
public:
- CrosDeviceConfig();
- CrosDeviceConfig(const CrosDeviceConfig& other) = default;
- CrosDeviceConfig& operator=(const CrosDeviceConfig& other) = default;
- ~CrosDeviceConfig();
+ static std::unique_ptr<CrosDeviceConfig> Create();
- static CrosDeviceConfig Get();
+ bool IsV1Device() const { return is_v1_device; }
+ const std::string& GetModelName() const { return model_name; }
+ bool IsUsbCameraCountAvailable() const {
+ return usb_camera_count.has_value();
+ }
+ int GetUsbCameraCount() const { return *usb_camera_count; }
- bool is_initialized;
+ private:
+ CrosDeviceConfig() = default;
+
bool is_v1_device;
std::string model_name;
base::Optional<int> usb_camera_count;