diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp index 3f64bccdb1..a1a8cd6d1b 100644 --- a/camera/ndk/impl/ACameraManager.cpp +++ b/camera/ndk/impl/ACameraManager.cpp @@ -340,6 +340,9 @@ void CameraManagerGlobal::onStatusChangedLocked( msg->setString(kCameraIdKey, AString(cameraId)); msg->post(); } + if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) { + mDeviceStatusMap.erase(cameraId); + } } } // namespace android diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 5fc1fa331b..536b54da61 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -316,6 +316,17 @@ void CameraService::addStates(const String8 id) { logDeviceAdded(id, "Device added"); } +void CameraService::removeStates(const String8 id) { + if (mFlashlight->hasFlashUnit(id)) { + mTorchStatusMap.removeItem(id); + } + + { + Mutex::Autolock lock(mCameraStatesLock); + mCameraStates.erase(id); + } +} + void CameraService::onDeviceStatusChanged(const String8& id, CameraDeviceStatus newHalStatus) { ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__, @@ -380,6 +391,7 @@ void CameraService::onDeviceStatusChanged(const String8& id, clientToDisconnect->disconnect(); } + removeStates(id); } else { if (oldStatus == StatusInternal::NOT_PRESENT) { logDeviceAdded(id, String8::format("Device status changed from %d to %d", oldStatus, diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 575cebf8ef..67db7ec4f8 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -551,8 +551,9 @@ private: // Eumerate all camera providers in the system status_t enumerateProviders(); - // Add a new camera to camera and torch state lists + // Add a new camera to camera and torch state lists or remove an unplugged one void addStates(const String8 id); + void removeStates(const String8 id); // Check if we can connect, before we acquire the service lock. // The returned originalClientPid is the PID of the original process that wants to connect to diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp index f2da232a5e..70e7761f38 100644 --- a/services/camera/libcameraservice/common/CameraProviderManager.cpp +++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp @@ -603,6 +603,15 @@ status_t CameraProviderManager::ProviderInfo::addDevice(const std::string& name, return OK; } +void CameraProviderManager::ProviderInfo::removeDevice(std::string id) { + for (auto it = mDevices.begin(); it != mDevices.end(); it++) { + if ((*it)->mId == id) { + mDevices.erase(it); + break; + } + } +} + status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector&) const { dprintf(fd, "== Camera Provider HAL %s (v2.4, %s) static info: %zu devices: ==\n", mProviderName.c_str(), mInterface->isRemote() ? "remote" : "passthrough", @@ -684,6 +693,8 @@ hardware::Return CameraProviderManager::ProviderInfo::cameraDeviceStatusCh return hardware::Void(); } addDevice(cameraDeviceName, newStatus, &id); + } else if (newStatus == CameraDeviceStatus::NOT_PRESENT) { + removeDevice(id); } listener = mManager->getStatusListener(); } diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h index 0f1f07b428..d02abb065f 100644 --- a/services/camera/libcameraservice/common/CameraProviderManager.h +++ b/services/camera/libcameraservice/common/CameraProviderManager.h @@ -387,6 +387,8 @@ private: // Generate vendor tag id static metadata_vendor_id_t generateVendorTagId(const std::string &name); + + void removeDevice(std::string id); }; // Utility to find a DeviceInfo by ID; pointer is only valid while mInterfaceMutex is held