Merge "CameraService: fix camera removal paths"
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index 3f64bcc..a1a8cd6 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -340,6 +340,9 @@
         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 6abfa81..514d37a 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -306,6 +306,17 @@
     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__,
@@ -370,6 +381,7 @@
             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 e9373a6..12ca372 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -512,8 +512,9 @@
     // 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 ae3bbc1..b3d1132 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -601,6 +601,15 @@
     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<String16>&) const {
     dprintf(fd, "== Camera Provider HAL %s (v2.4, %s) static info: %zu devices: ==\n",
             mProviderName.c_str(), mInterface->isRemote() ? "remote" : "passthrough",
@@ -674,6 +683,8 @@
                 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 e82282f..b14a2c6 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -384,6 +384,8 @@
 
         // 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