Camera: plumb external camera API1 support
And also some refactoring to unify external camera
config file logics.
Bug: 72261912
Change-Id: If83d779c57540809bdaa58a5a32cf4ade734fafe
diff --git a/camera/provider/2.4/default/ExternalCameraProvider.cpp b/camera/provider/2.4/default/ExternalCameraProvider.cpp
index 7657fa3..faa4e3a 100644
--- a/camera/provider/2.4/default/ExternalCameraProvider.cpp
+++ b/camera/provider/2.4/default/ExternalCameraProvider.cpp
@@ -24,7 +24,6 @@
#include <linux/videodev2.h>
#include "ExternalCameraProvider.h"
#include "ExternalCameraDevice_3_4.h"
-#include "tinyxml2.h" // XML parsing
namespace android {
namespace hardware {
@@ -38,6 +37,8 @@
const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/external/(.+)");
const int kMaxDevicePathLen = 256;
const char* kDevicePath = "/dev/";
+constexpr char kPrefix[] = "video";
+constexpr int kPrefixLen = sizeof(kPrefix) - 1;
bool matchDeviceName(const hidl_string& deviceName, std::string* deviceVersion,
std::string* cameraId) {
@@ -58,6 +59,7 @@
} // anonymous namespace
ExternalCameraProvider::ExternalCameraProvider() :
+ mCfg(ExternalCameraConfig::loadFromCfg()),
mHotPlugThread(this) {
mHotPlugThread.run("ExtCamHotPlug", PRIORITY_BACKGROUND);
}
@@ -69,8 +71,17 @@
Return<Status> ExternalCameraProvider::setCallback(
const sp<ICameraProviderCallback>& callback) {
- Mutex::Autolock _l(mLock);
- mCallbacks = callback;
+ {
+ Mutex::Autolock _l(mLock);
+ mCallbacks = callback;
+ }
+ // Send a callback for all devices to initialize
+ {
+ for (const auto& pair : mCameraStatusMap) {
+ mCallbacks->cameraDeviceStatusChange(pair.first, pair.second);
+ }
+ }
+
return Status::OK;
}
@@ -82,14 +93,9 @@
}
Return<void> ExternalCameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) {
- std::vector<hidl_string> deviceNameList;
- for (auto const& kvPair : mCameraStatusMap) {
- if (kvPair.second == CameraDeviceStatus::PRESENT) {
- deviceNameList.push_back(kvPair.first);
- }
- }
- hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
- ALOGV("ExtCam: number of cameras is %zu", deviceNameList.size());
+ // External camera HAL always report 0 camera, and extra cameras
+ // are just reported via cameraDeviceStatusChange callbacks
+ hidl_vec<hidl_string> hidlDeviceNameList;
_hidl_cb(Status::OK, hidlDeviceNameList);
return Void();
}
@@ -130,7 +136,7 @@
sp<device::V3_2::ICameraDevice> device;
sp<device::V3_4::implementation::ExternalCameraDevice> deviceImpl =
new device::V3_4::implementation::ExternalCameraDevice(
- cameraId);
+ cameraId, mCfg);
if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
device = nullptr;
@@ -194,59 +200,10 @@
}
}
-std::unordered_set<std::string>
-ExternalCameraProvider::HotplugThread::initInternalDevices() {
- std::unordered_set<std::string> ret;
- using device::V3_4::implementation::ExternalCameraDeviceConfig;
- const char* configPath = ExternalCameraDeviceConfig::kDefaultCfgPath;
-
- using namespace tinyxml2;
-
- XMLDocument configXml;
- XMLError err = configXml.LoadFile(configPath);
- if (err != XML_SUCCESS) {
- ALOGE("%s: Unable to load external camera config file '%s'. Error: %s",
- __FUNCTION__, configPath, XMLDocument::ErrorIDToName(err));
- } else {
- ALOGI("%s: load external camera config succeed!", __FUNCTION__);
- }
-
- XMLElement *extCam = configXml.FirstChildElement("ExternalCamera");
- if (extCam == nullptr) {
- ALOGI("%s: no external camera config specified", __FUNCTION__);
- return ret;
- }
-
- XMLElement *providerCfg = extCam->FirstChildElement("Provider");
- if (providerCfg == nullptr) {
- ALOGI("%s: no external camera provider config specified", __FUNCTION__);
- return ret;
- }
-
- XMLElement *ignore = providerCfg->FirstChildElement("ignore");
- if (ignore == nullptr) {
- ALOGI("%s: no internal ignored device specified", __FUNCTION__);
- return ret;
- }
-
- XMLElement *id = ignore->FirstChildElement("id");
- while (id != nullptr) {
- const char* text = id->GetText();
- if (text != nullptr) {
- ret.insert(text);
- ALOGI("%s: device %s will be ignored by external camera provider",
- __FUNCTION__, text);
- }
- id = id->NextSiblingElement("id");
- }
-
- return ret;
-}
-
ExternalCameraProvider::HotplugThread::HotplugThread(ExternalCameraProvider* parent) :
Thread(/*canCallJava*/false),
mParent(parent),
- mInternalDevices(initInternalDevices()) {}
+ mInternalDevices(parent->mCfg.mInternalDevices) {}
ExternalCameraProvider::HotplugThread::~HotplugThread() {}
@@ -261,10 +218,10 @@
struct dirent* de;
while ((de = readdir(devdir)) != 0) {
// Find external v4l devices that's existing before we start watching and add them
- if (!strncmp("video", de->d_name, 5)) {
+ if (!strncmp(kPrefix, de->d_name, kPrefixLen)) {
// TODO: This might reject some valid devices. Ex: internal is 33 and a device named 3
// is added.
- std::string deviceId(de->d_name + 5);
+ std::string deviceId(de->d_name + kPrefixLen);
if (mInternalDevices.count(deviceId) == 0) {
ALOGV("Non-internal v4l device %s found", de->d_name);
char v4l2DevicePath[kMaxDevicePathLen];
@@ -300,8 +257,8 @@
while (offset < ret) {
struct inotify_event* event = (struct inotify_event*)&eventBuf[offset];
if (event->wd == mWd) {
- if (!strncmp("video", event->name, 5)) {
- std::string deviceId(event->name + 5);
+ if (!strncmp(kPrefix, event->name, kPrefixLen)) {
+ std::string deviceId(event->name + kPrefixLen);
if (mInternalDevices.count(deviceId) == 0) {
char v4l2DevicePath[kMaxDevicePathLen];
snprintf(v4l2DevicePath, kMaxDevicePathLen,
diff --git a/camera/provider/2.4/default/ExternalCameraProvider.h b/camera/provider/2.4/default/ExternalCameraProvider.h
index 64a8878..c83cc70 100644
--- a/camera/provider/2.4/default/ExternalCameraProvider.h
+++ b/camera/provider/2.4/default/ExternalCameraProvider.h
@@ -25,6 +25,7 @@
#include <android/hardware/camera/provider/2.4/ICameraProvider.h>
#include <hidl/Status.h>
#include <hidl/MQDescriptor.h>
+#include "ExternalCameraUtils.h"
namespace android {
namespace hardware {
@@ -36,6 +37,7 @@
using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
using ::android::hardware::camera::common::V1_0::Status;
using ::android::hardware::camera::common::V1_0::VendorTagSection;
+using ::android::hardware::camera::external::common::ExternalCameraConfig;
using ::android::hardware::camera::provider::V2_4::ICameraProvider;
using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
using ::android::hardware::Return;
@@ -81,8 +83,6 @@
virtual bool threadLoop() override;
private:
- static std::unordered_set<std::string> initInternalDevices();
-
ExternalCameraProvider* mParent = nullptr;
const std::unordered_set<std::string> mInternalDevices;
@@ -93,6 +93,7 @@
Mutex mLock;
sp<ICameraProviderCallback> mCallbacks = nullptr;
std::unordered_map<std::string, CameraDeviceStatus> mCameraStatusMap; // camera id -> status
+ const ExternalCameraConfig mCfg;
HotplugThread mHotPlugThread;
};