diff options
4 files changed, 120 insertions, 72 deletions
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 414d563..67a1d5d 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -140,76 +140,90 @@ void CameraService::onFirstRef() BnCameraService::onFirstRef(); camera_module_t *rawModule; - if (hw_get_module(CAMERA_HARDWARE_MODULE_ID, - (const hw_module_t **)&rawModule) < 0) { - ALOGE("Could not load camera HAL module"); + int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID, + (const hw_module_t **)&rawModule); + if (err < 0) { + ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err)); + logServiceError("Could not load camera HAL module", err); mNumberOfCameras = 0; + return; } - else { - mModule = new CameraModule(rawModule); - ALOGI("Loaded \"%s\" camera module", mModule->getModuleName()); - mNumberOfCameras = mModule->getNumberOfCameras(); - - mFlashlight = new CameraFlashlight(*mModule, *this); - status_t res = mFlashlight->findFlashUnits(); - if (res) { - // impossible because we haven't open any camera devices. - ALOGE("Failed to find flash units."); - } - for (int i = 0; i < mNumberOfCameras; i++) { - String8 cameraId = String8::format("%d", i); - - // Defaults to use for cost and conflicting devices - int cost = 100; - char** conflicting_devices = nullptr; - size_t conflicting_devices_length = 0; - - // If using post-2.4 module version, query the cost + conflicting devices from the HAL - if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) { - struct camera_info info; - status_t rc = mModule->getCameraInfo(i, &info); - if (rc == NO_ERROR) { - cost = info.resource_cost; - conflicting_devices = info.conflicting_devices; - conflicting_devices_length = info.conflicting_devices_length; - } else { - ALOGE("%s: Received error loading camera info for device %d, cost and" - " conflicting devices fields set to defaults for this device.", - __FUNCTION__, i); - } - } + mModule = new CameraModule(rawModule); + ALOGI("Loaded \"%s\" camera module", mModule->getModuleName()); + err = mModule->init(); + if (err != OK) { + ALOGE("Could not initialize camera HAL module: %d (%s)", err, + strerror(-err)); + logServiceError("Could not initialize camera HAL module", err); - std::set<String8> conflicting; - for (size_t i = 0; i < conflicting_devices_length; i++) { - conflicting.emplace(String8(conflicting_devices[i])); - } + mNumberOfCameras = 0; + delete mModule; + mModule = nullptr; + return; + } - // Initialize state for each camera device - { - Mutex::Autolock lock(mCameraStatesLock); - mCameraStates.emplace(cameraId, std::make_shared<CameraState>(cameraId, cost, - conflicting)); - } + mNumberOfCameras = mModule->getNumberOfCameras(); - if (mFlashlight->hasFlashUnit(cameraId)) { - mTorchStatusMap.add(cameraId, - ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF); + mFlashlight = new CameraFlashlight(*mModule, *this); + status_t res = mFlashlight->findFlashUnits(); + if (res) { + // impossible because we haven't open any camera devices. + ALOGE("Failed to find flash units."); + } + + for (int i = 0; i < mNumberOfCameras; i++) { + String8 cameraId = String8::format("%d", i); + + // Defaults to use for cost and conflicting devices + int cost = 100; + char** conflicting_devices = nullptr; + size_t conflicting_devices_length = 0; + + // If using post-2.4 module version, query the cost + conflicting devices from the HAL + if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4) { + struct camera_info info; + status_t rc = mModule->getCameraInfo(i, &info); + if (rc == NO_ERROR) { + cost = info.resource_cost; + conflicting_devices = info.conflicting_devices; + conflicting_devices_length = info.conflicting_devices_length; + } else { + ALOGE("%s: Received error loading camera info for device %d, cost and" + " conflicting devices fields set to defaults for this device.", + __FUNCTION__, i); } } - if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_1) { - mModule->setCallbacks(this); + std::set<String8> conflicting; + for (size_t i = 0; i < conflicting_devices_length; i++) { + conflicting.emplace(String8(conflicting_devices[i])); } - VendorTagDescriptor::clearGlobalVendorTagDescriptor(); + // Initialize state for each camera device + { + Mutex::Autolock lock(mCameraStatesLock); + mCameraStates.emplace(cameraId, std::make_shared<CameraState>(cameraId, cost, + conflicting)); + } - if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_2) { - setUpVendorTags(); + if (mFlashlight->hasFlashUnit(cameraId)) { + mTorchStatusMap.add(cameraId, + ICameraServiceListener::TORCH_STATUS_AVAILABLE_OFF); } + } + + if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_1) { + mModule->setCallbacks(this); + } + + VendorTagDescriptor::clearGlobalVendorTagDescriptor(); - CameraDeviceFactory::registerService(this); + if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_2) { + setUpVendorTags(); } + + CameraDeviceFactory::registerService(this); } CameraService::~CameraService() { @@ -1554,6 +1568,11 @@ void CameraService::logClientDied(int clientPid, const char* reason) { logEvent(String8::format("DIED client(s) with PID %d, reason: (%s)", clientPid, reason)); } +void CameraService::logServiceError(const char* msg, int errorCode) { + String8 curTime = getFormattedCurrentTime(); + logEvent(String8::format("SERVICE ERROR: %s : %d (%s)", msg, errorCode, strerror(errorCode))); +} + status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { @@ -1996,6 +2015,10 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) { if (!mModule) { result = String8::format("No camera module available!\n"); write(fd, result.string(), result.size()); + + // Dump event log for error information + dumpEventLog(fd); + if (locked) mServiceLock.unlock(); return NO_ERROR; } @@ -2021,20 +2044,7 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) { desc->dump(fd, /*verbosity*/2, /*indentation*/4); } - result = String8("Prior client events (most recent at top):\n"); - - { - Mutex::Autolock l(mLogLock); - for (const auto& msg : mEventLog) { - result.appendFormat("%s\n", msg.string()); - } - - if (mEventLog.size() == DEFAULT_EVENT_LOG_LENGTH) { - result.append("...\n"); - } - } - - write(fd, result.string(), result.size()); + dumpEventLog(fd); bool stateLocked = tryLock(mCameraStatesLock); if (!stateLocked) { @@ -2142,6 +2152,24 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) { return NO_ERROR; } +void CameraService::dumpEventLog(int fd) { + String8 result = String8("\nPrior client events (most recent at top):\n"); + + Mutex::Autolock l(mLogLock); + for (const auto& msg : mEventLog) { + result.appendFormat(" %s\n", msg.string()); + } + + if (mEventLog.size() == DEFAULT_EVENT_LOG_LENGTH) { + result.append(" ...\n"); + } else if (mEventLog.size() == 0) { + result.append(" [no events yet]\n"); + } + result.append("\n"); + + write(fd, result.string(), result.size()); +} + void CameraService::handleTorchClientBinderDied(const wp<IBinder> &who) { Mutex::Autolock al(mTorchClientMapMutex); for (size_t i = 0; i < mTorchClientMap.size(); i++) { diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 91c7d59..84e61c5 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -590,6 +590,16 @@ private: */ void logClientDied(int clientPid, const char* reason); + /** + * Add a event log message that a serious service-level error has occured + */ + void logServiceError(const char* msg, int errorCode); + + /** + * Dump the event log to an FD + */ + void dumpEventLog(int fd); + int mNumberOfCameras; // sounds diff --git a/services/camera/libcameraservice/common/CameraModule.cpp b/services/camera/libcameraservice/common/CameraModule.cpp index e5b12ae..5e0ac9f 100644 --- a/services/camera/libcameraservice/common/CameraModule.cpp +++ b/services/camera/libcameraservice/common/CameraModule.cpp @@ -57,6 +57,14 @@ CameraModule::CameraModule(camera_module_t *module) { mCameraInfoMap.setCapacity(getNumberOfCameras()); } +int CameraModule::init() { + if (getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_4 && + mModule->init != NULL) { + return mModule->init(); + } + return OK; +} + int CameraModule::getCameraInfo(int cameraId, struct camera_info *info) { Mutex::Autolock lock(mCameraInfoLock); if (cameraId < 0) { @@ -92,7 +100,7 @@ int CameraModule::getCameraInfo(int cameraId, struct camera_info *info) { assert(index != NAME_NOT_FOUND); // return the cached camera info *info = mCameraInfoMap[index]; - return 0; + return OK; } int CameraModule::open(const char* id, struct hw_device_t** device) { @@ -160,4 +168,3 @@ void* CameraModule::getDso() { } }; // namespace android - diff --git a/services/camera/libcameraservice/common/CameraModule.h b/services/camera/libcameraservice/common/CameraModule.h index e285b21..c21092e 100644 --- a/services/camera/libcameraservice/common/CameraModule.h +++ b/services/camera/libcameraservice/common/CameraModule.h @@ -34,6 +34,10 @@ class CameraModule { public: CameraModule(camera_module_t *module); + // Must be called after construction + // Returns OK on success, NO_INIT on failure + int init(); + int getCameraInfo(int cameraId, struct camera_info *info); int getNumberOfCameras(void); int open(const char* id, struct hw_device_t** device); @@ -63,4 +67,3 @@ private: } // namespace android #endif - |