本讲是Android Camera Native Framework专题的第14讲,我们介绍cameraserver进程启动之LogicalDeviceStatusChange。
更多资源:
| 资源 | 描述 |
|---|---|
| 在线课程 | 极客笔记在线课程 |
| 知识星球 | 星球名称:深入浅出Android Camera 星球ID: 17296815 |
| 极客笔记圈 |
Process Cache Status Callbacks
本讲我们介绍Logical CameraDevice的Status Callback是逻辑。
cameraDeviceStatusChangeLocked
上述流程图来自Android 13:
status_t CameraProviderManager::ProviderInfo::cameraDeviceStatusChangeLocked( std::string* id, const std::string& cameraDeviceName, CameraDeviceStatus newStatus) { bool known = false; std::string cameraId; for (auto& deviceInfo : mDevices) { if (deviceInfo->mName == cameraDeviceName) { Mutex::Autolock l(deviceInfo->mDeviceAvailableLock); ALOGI("Camera device %s status is now %s, was %s", cameraDeviceName.c_str(), FrameworkDeviceStatusToString(newStatus), FrameworkDeviceStatusToString(deviceInfo->mStatus)); deviceInfo->mStatus = newStatus; // TODO: Handle device removal (NOT_PRESENT) cameraId = deviceInfo->mId; known = true; deviceInfo->mIsDeviceAvailable = (newStatus == CameraDeviceStatus::PRESENT); deviceInfo->mDeviceAvailableSignal.signal(); break; } } // Previously unseen device; status must not be NOT_PRESENT if (!known) { if (newStatus == CameraDeviceStatus::NOT_PRESENT) { ALOGW("Camera provider %s says an unknown camera device %s is not present. Curious.", mProviderName.c_str(), cameraDeviceName.c_str()); return BAD_VALUE; } addDevice(cameraDeviceName, newStatus, &cameraId); } else if (newStatus == CameraDeviceStatus::NOT_PRESENT) { removeDevice(cameraId); } else if (isExternalLazyHAL()) { // Do not notify CameraService for PRESENT->PRESENT (lazy HAL restart) // because NOT_AVAILABLE is set on CameraService::connect and a PRESENT // notif. would overwrite it return BAD_VALUE; }if (reCacheConcurrentStreamingCameraIdsLocked() != OK) { ALOGE("%s: CameraProvider %s could not re-cache concurrent streaming camera id list ", __FUNCTION__, mProviderName.c_str()); } *id = cameraId; return OK;
}
Logical onCameraDeviceChanged
上述流程图来自Android 13:
void CameraService::onDeviceStatusChanged(const String8& id, CameraDeviceStatus newHalStatus) { ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__, id.string(), newHalStatus);StatusInternal newStatus = mapToInternal(newHalStatus); std::shared_ptr<CameraState> state = getCameraState(id); if (state == nullptr) { if (newStatus == StatusInternal::PRESENT) { ALOGI("%s: Unknown camera ID %s, a new camera is added", __FUNCTION__, id.string()); // First add as absent to make sure clients are notified below addStates(id); updateStatus(newStatus, id); } else { ALOGE("%s: Bad camera ID %s", __FUNCTION__, id.string()); } return; } StatusInternal oldStatus = state->getStatus(); if (oldStatus == newStatus) { ALOGE("%s: State transition to the same status %#x not allowed", __FUNCTION__, newStatus); return; } if (newStatus == StatusInternal::NOT_PRESENT) { logDeviceRemoved(id, String8::format("Device status changed from %d to %d", oldStatus, newStatus)); // Set the device status to NOT_PRESENT, clients will no longer be able to connect // to this device until the status changes updateStatus(StatusInternal::NOT_PRESENT, id); sp<BasicClient> clientToDisconnectOnline, clientToDisconnectOffline; { // Don't do this in updateStatus to avoid deadlock over mServiceLock Mutex::Autolock lock(mServiceLock); // Remove cached shim parameters state->setShimParams(CameraParameters()); // Remove online as well as offline client from the list of active clients, // if they are present clientToDisconnectOnline = removeClientLocked(id); clientToDisconnectOffline = removeClientLocked(kOfflineDevice + id); } disconnectClient(id, clientToDisconnectOnline); disconnectClient(kOfflineDevice + id, clientToDisconnectOffline); removeStates(id); } else { if (oldStatus == StatusInternal::NOT_PRESENT) { logDeviceAdded(id, String8::format("Device status changed from %d to %d", oldStatus, newStatus)); } updateStatus(newStatus, id); }
}
CameraService::updateStatus
上述流程图来自Android 13:
void CameraService::updateStatus(StatusInternal status, const String8& cameraId, std::initializer_list<StatusInternal> rejectSourceStates) { // Do not lock mServiceLock here or can get into a deadlock from // connect() -> disconnect -> updateStatusauto state = getCameraState(cameraId); if (state == nullptr) { ALOGW("%s: Could not update the status for %s, no such device exists", __FUNCTION__, cameraId.string()); return; } // Avoid calling getSystemCameraKind() with mStatusListenerLock held (b/141756275) SystemCameraKind deviceKind = SystemCameraKind::PUBLIC; if (getSystemCameraKind(cameraId, &deviceKind) != OK) { ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, cameraId.string()); return; } // Collect the logical cameras without holding mStatusLock in updateStatus // as that can lead to a deadlock(b/162192331). auto logicalCameraIds = getLogicalCameras(cameraId); // Update the status for this camera state, then send the onStatusChangedCallbacks to each // of the listeners with both the mStatusLock and mStatusListenerLock held state->updateStatus(status, cameraId, rejectSourceStates, [this, &deviceKind, &logicalCameraIds] (const String8& cameraId, StatusInternal status) { if (status != StatusInternal::ENUMERATING) { // Update torch status if it has a flash unit. Mutex::Autolock al(mTorchStatusMutex); TorchModeStatus torchStatus; if (getTorchStatusLocked(cameraId, &torchStatus) != NAME_NOT_FOUND) { TorchModeStatus newTorchStatus = status == StatusInternal::PRESENT ? TorchModeStatus::AVAILABLE_OFF : TorchModeStatus::NOT_AVAILABLE; if (torchStatus != newTorchStatus) { onTorchStatusChangedLocked(cameraId, newTorchStatus, deviceKind); } } } Mutex::Autolock lock(mStatusListenerLock); notifyPhysicalCameraStatusLocked(mapToInterface(status), String16(cameraId), logicalCameraIds, deviceKind); for (auto& listener : mListenerList) { bool isVendorListener = listener->isVendorListener(); if (shouldSkipStatusUpdates(deviceKind, isVendorListener, listener->getListenerPid(), listener->getListenerUid()) || isVendorListener) { ALOGV("Skipping discovery callback for system-only camera device %s", cameraId.c_str()); continue; } listener->getListener()->onStatusChanged(mapToInterface(status), String16(cameraId)); } });
}
CameraService::addStates
上述流程图来自Android 13:
void CameraService::addStates(const String8 id) { std::string cameraId(id.c_str()); CameraResourceCost cost; status_t res = mCameraProviderManager->getResourceCost(cameraId, &cost); if (res != OK) { ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res); return; } SystemCameraKind deviceKind = SystemCameraKind::PUBLIC; res = mCameraProviderManager->getSystemCameraKind(cameraId, &deviceKind); if (res != OK) { ALOGE("Failed to query device kind: %s (%d)", strerror(-res), res); return; } std::vector<std::string> physicalCameraIds; mCameraProviderManager->isLogicalCamera(cameraId, &physicalCameraIds); std::set<String8> conflicting; for (size_t i = 0; i < cost.conflictingDevices.size(); i++) { conflicting.emplace(String8(cost.conflictingDevices[i].c_str())); }{ Mutex::Autolock lock(mCameraStatesLock); mCameraStates.emplace(id, std::make_shared<CameraState>(id, cost.resourceCost, conflicting, deviceKind, physicalCameraIds)); } if (mFlashlight->hasFlashUnit(id)) { Mutex::Autolock al(mTorchStatusMutex); mTorchStatusMap.add(id, TorchModeStatus::AVAILABLE_OFF); broadcastTorchModeStatus(id, TorchModeStatus::AVAILABLE_OFF, deviceKind); } updateCameraNumAndIds(); logDeviceAdded(id, "Device added");
}
CameraService::removeStates
上述流程图来自Android 13:
void CameraService::removeStates(const String8 id) { updateCameraNumAndIds(); if (mFlashlight->hasFlashUnit(id)) { Mutex::Autolock al(mTorchStatusMutex); mTorchStatusMap.removeItem(id); }{ Mutex::Autolock lock(mCameraStatesLock); mCameraStates.erase(id); }
}





