blob: 0cde82c6ecbe3058686239fa6ccd6c5a57b26342 [file] [log] [blame]
Jackeagle0cc335a2018-10-19 00:06:49 -04001From f584caaf5f6cd31cc6b8e30a4b62893d6d85818e Mon Sep 17 00:00:00 2001
2From: Jackeagle <jackeagle102@gmail.com>
3Date: Thu, 18 Oct 2018 04:21:22 -0400
4Subject: [PATCH 1/5] [SQUASH] Revert Camera Specific AOSP Reverts
5
6Revert "Revert "CameraService: fix camera removal paths""
7
8This reverts commit e1922854c4bf71d9170011b904b701d1b38e303e.
9
10Revert "Revert "CameraService: Update camera and torch state lists also at runtime""
11
12This reverts commit cb343b767cd41829bb994c9c0e671a9c3e5d7cfb.
13
14Revert "Revert "Camera: Add API level to service proxy notification""
15
16This reverts commit 48888c68523e50038e92b8d73fa4d471fe266972.
17
18Revert "Revert "Camera: expose external camera to API1""
19
20This reverts commit 92607517666eca78bb94817f780977c7024cdda4.
21
22Revert "Revert "Camera: fix camera ID in flashlight control""
23
24This reverts commit 2c7225b2fe3017d1fd146e55420c6b616f44d16b.
25
26Revert "Revert "Camera: Support all API1 compatible camera devices""
27
28This reverts commit 842255a5aff37bb06d43a06bb44be0a67c4570ac.
29
30Revert "Revert "Camera: Filter logical camera ids to API1 app""
31
32This reverts commit 4e10dacc6a5edc0b4382e570173e9f7ff89af9bd.
33---
34 .../aidl/android/hardware/ICameraServiceProxy.aidl | 8 +-
35 camera/ndk/impl/ACameraManager.cpp | 3 +
36 .../camera/libcameraservice/CameraFlashlight.cpp | 52 ++--
37 .../camera/libcameraservice/CameraFlashlight.h | 11 +-
38 services/camera/libcameraservice/CameraService.cpp | 317 ++++++++++-----------
39 services/camera/libcameraservice/CameraService.h | 35 ++-
40 .../camera/libcameraservice/api1/Camera2Client.cpp | 7 +-
41 .../camera/libcameraservice/api1/Camera2Client.h | 3 +-
42 .../camera/libcameraservice/api1/CameraClient.cpp | 14 +-
43 .../libcameraservice/api1/client2/Parameters.cpp | 56 +++-
44 .../libcameraservice/api1/client2/Parameters.h | 7 +
45 .../libcameraservice/api2/CameraDeviceClient.cpp | 59 ++--
46 .../libcameraservice/api2/CameraDeviceClient.h | 1 +
47 .../libcameraservice/common/Camera2ClientBase.cpp | 15 +-
48 .../libcameraservice/common/Camera2ClientBase.h | 3 +
49 .../common/CameraProviderManager.cpp | 173 ++++++++---
50 .../common/CameraProviderManager.h | 30 +-
51 17 files changed, 476 insertions(+), 318 deletions(-)
52
53diff --git a/camera/aidl/android/hardware/ICameraServiceProxy.aidl b/camera/aidl/android/hardware/ICameraServiceProxy.aidl
54index 5dc23eb..7575948 100644
55--- a/camera/aidl/android/hardware/ICameraServiceProxy.aidl
56+++ b/camera/aidl/android/hardware/ICameraServiceProxy.aidl
57@@ -46,8 +46,14 @@ interface ICameraServiceProxy
58 const int CAMERA_FACING_EXTERNAL = 2;
59
60 /**
61+ * Values for notifyCameraState api level
62+ */
63+ const int CAMERA_API_LEVEL_1 = 1;
64+ const int CAMERA_API_LEVEL_2 = 2;
65+
66+ /**
67 * Update the status of a camera device.
68 */
69 oneway void notifyCameraState(String cameraId, int facing, int newCameraState,
70- String clientName);
71+ String clientName, int apiLevel);
72 }
73diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
74index e409ddd..c59d0e7 100644
75--- a/camera/ndk/impl/ACameraManager.cpp
76+++ b/camera/ndk/impl/ACameraManager.cpp
77@@ -340,6 +340,9 @@ void CameraManagerGlobal::onStatusChangedLocked(
78 msg->setString(kCameraIdKey, AString(cameraId));
79 msg->post();
80 }
81+ if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
82+ mDeviceStatusMap.erase(cameraId);
83+ }
84 }
85
86 } // namespace android
87diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
88index 9c45331..61b9acb 100644
89--- a/services/camera/libcameraservice/CameraFlashlight.cpp
90+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
91@@ -32,13 +32,15 @@
92
93 namespace android {
94
95+using hardware::camera::common::V1_0::TorchModeStatus;
96+
97 /////////////////////////////////////////////////////////////////////
98 // CameraFlashlight implementation begins
99 // used by camera service to control flashflight.
100 /////////////////////////////////////////////////////////////////////
101
102 CameraFlashlight::CameraFlashlight(sp<CameraProviderManager> providerManager,
103- camera_module_callbacks_t* callbacks) :
104+ CameraProviderManager::StatusListener* callbacks) :
105 mProviderManager(providerManager),
106 mCallbacks(callbacks),
107 mFlashlightMapInitialized(false) {
108@@ -59,7 +61,7 @@ status_t CameraFlashlight::createFlashlightControl(const String8& cameraId) {
109 } else {
110 // Only HAL1 devices do not support setTorchMode
111 mFlashControl =
112- new CameraHardwareInterfaceFlashControl(mProviderManager, *mCallbacks);
113+ new CameraHardwareInterfaceFlashControl(mProviderManager, mCallbacks);
114 }
115
116 return OK;
117@@ -118,19 +120,15 @@ status_t CameraFlashlight::setTorchMode(const String8& cameraId, bool enabled) {
118 return res;
119 }
120
121-int CameraFlashlight::getNumberOfCameras() {
122- return mProviderManager->getAPI1CompatibleCameraCount();
123-}
124-
125 status_t CameraFlashlight::findFlashUnits() {
126 Mutex::Autolock l(mLock);
127 status_t res;
128
129 std::vector<String8> cameraIds;
130- int numberOfCameras = getNumberOfCameras();
131+ std::vector<std::string> ids = mProviderManager->getAPI1CompatibleCameraDeviceIds();
132+ int numberOfCameras = static_cast<int>(ids.size());
133 cameraIds.resize(numberOfCameras);
134 // No module, must be provider
135- std::vector<std::string> ids = mProviderManager->getAPI1CompatibleCameraDeviceIds();
136 for (size_t i = 0; i < cameraIds.size(); i++) {
137 cameraIds[i] = String8(ids[i].c_str());
138 }
139@@ -184,7 +182,8 @@ bool CameraFlashlight::hasFlashUnitLocked(const String8& cameraId) {
140
141 ssize_t index = mHasFlashlightMap.indexOfKey(cameraId);
142 if (index == NAME_NOT_FOUND) {
143- ALOGE("%s: camera %s not present when findFlashUnits() was called",
144+ // Might be external camera
145+ ALOGW("%s: camera %s not present when findFlashUnits() was called",
146 __FUNCTION__, cameraId.string());
147 return false;
148 }
149@@ -218,12 +217,13 @@ status_t CameraFlashlight::prepareDeviceOpen(const String8& cameraId) {
150
151 if (mOpenedCameraIds.size() == 0) {
152 // notify torch unavailable for all cameras with a flash
153- int numCameras = getNumberOfCameras();
154+ std::vector<std::string> ids = mProviderManager->getAPI1CompatibleCameraDeviceIds();
155+ int numCameras = static_cast<int>(ids.size());
156 for (int i = 0; i < numCameras; i++) {
157- if (hasFlashUnitLocked(String8::format("%d", i))) {
158- mCallbacks->torch_mode_status_change(mCallbacks,
159- String8::format("%d", i).string(),
160- TORCH_MODE_STATUS_NOT_AVAILABLE);
161+ String8 id8(ids[i].c_str());
162+ if (hasFlashUnitLocked(id8)) {
163+ mCallbacks->onTorchStatusChanged(
164+ id8, TorchModeStatus::NOT_AVAILABLE);
165 }
166 }
167 }
168@@ -263,12 +263,13 @@ status_t CameraFlashlight::deviceClosed(const String8& cameraId) {
169
170 if (isBackwardCompatibleMode(cameraId)) {
171 // notify torch available for all cameras with a flash
172- int numCameras = getNumberOfCameras();
173+ std::vector<std::string> ids = mProviderManager->getAPI1CompatibleCameraDeviceIds();
174+ int numCameras = static_cast<int>(ids.size());
175 for (int i = 0; i < numCameras; i++) {
176- if (hasFlashUnitLocked(String8::format("%d", i))) {
177- mCallbacks->torch_mode_status_change(mCallbacks,
178- String8::format("%d", i).string(),
179- TORCH_MODE_STATUS_AVAILABLE_OFF);
180+ String8 id8(ids[i].c_str());
181+ if (hasFlashUnitLocked(id8)) {
182+ mCallbacks->onTorchStatusChanged(
183+ id8, TorchModeStatus::AVAILABLE_OFF);
184 }
185 }
186 }
187@@ -315,9 +316,9 @@ status_t ProviderFlashControl::setTorchMode(const String8& cameraId, bool enable
188
189 CameraHardwareInterfaceFlashControl::CameraHardwareInterfaceFlashControl(
190 sp<CameraProviderManager> manager,
191- const camera_module_callbacks_t& callbacks) :
192+ CameraProviderManager::StatusListener* callbacks) :
193 mProviderManager(manager),
194- mCallbacks(&callbacks),
195+ mCallbacks(callbacks),
196 mTorchEnabled(false) {
197 }
198
199@@ -333,8 +334,7 @@ CameraHardwareInterfaceFlashControl::~CameraHardwareInterfaceFlashControl() {
200 if (mCallbacks) {
201 ALOGV("%s: notify the framework that torch was turned off",
202 __FUNCTION__);
203- mCallbacks->torch_mode_status_change(mCallbacks,
204- mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
205+ mCallbacks->onTorchStatusChanged(mCameraId, TorchModeStatus::AVAILABLE_OFF);
206 }
207 }
208 }
209@@ -368,8 +368,7 @@ status_t CameraHardwareInterfaceFlashControl::setTorchMode(
210 // disabling the torch mode of currently opened device
211 disconnectCameraDevice();
212 mTorchEnabled = false;
213- mCallbacks->torch_mode_status_change(mCallbacks,
214- cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
215+ mCallbacks->onTorchStatusChanged(cameraId, TorchModeStatus::AVAILABLE_OFF);
216 return OK;
217 }
218
219@@ -379,8 +378,7 @@ status_t CameraHardwareInterfaceFlashControl::setTorchMode(
220 }
221
222 mTorchEnabled = true;
223- mCallbacks->torch_mode_status_change(mCallbacks,
224- cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON);
225+ mCallbacks->onTorchStatusChanged(cameraId, TorchModeStatus::AVAILABLE_ON);
226 return OK;
227 }
228
229diff --git a/services/camera/libcameraservice/CameraFlashlight.h b/services/camera/libcameraservice/CameraFlashlight.h
230index c86ee85..1baaba2 100644
231--- a/services/camera/libcameraservice/CameraFlashlight.h
232+++ b/services/camera/libcameraservice/CameraFlashlight.h
233@@ -19,7 +19,6 @@
234
235 #include <gui/GLConsumer.h>
236 #include <gui/Surface.h>
237-#include <hardware/camera_common.h>
238 #include <utils/KeyedVector.h>
239 #include <utils/SortedVector.h>
240 #include "common/CameraProviderManager.h"
241@@ -55,7 +54,7 @@ class FlashControlBase : public virtual VirtualLightRefBase {
242 class CameraFlashlight : public virtual VirtualLightRefBase {
243 public:
244 CameraFlashlight(sp<CameraProviderManager> providerManager,
245- camera_module_callbacks_t* callbacks);
246+ CameraProviderManager::StatusListener* callbacks);
247 virtual ~CameraFlashlight();
248
249 // Find all flash units. This must be called before other methods. All
250@@ -93,13 +92,11 @@ class CameraFlashlight : public virtual VirtualLightRefBase {
251 // opening cameras)
252 bool isBackwardCompatibleMode(const String8& cameraId);
253
254- int getNumberOfCameras();
255-
256 sp<FlashControlBase> mFlashControl;
257
258 sp<CameraProviderManager> mProviderManager;
259
260- const camera_module_callbacks_t *mCallbacks;
261+ CameraProviderManager::StatusListener* mCallbacks;
262 SortedVector<String8> mOpenedCameraIds;
263
264 // camera id -> if it has a flash unit
265@@ -134,7 +131,7 @@ class CameraHardwareInterfaceFlashControl : public FlashControlBase {
266 public:
267 CameraHardwareInterfaceFlashControl(
268 sp<CameraProviderManager> manager,
269- const camera_module_callbacks_t& callbacks);
270+ CameraProviderManager::StatusListener* callbacks);
271 virtual ~CameraHardwareInterfaceFlashControl();
272
273 // FlashControlBase
274@@ -166,7 +163,7 @@ class CameraHardwareInterfaceFlashControl : public FlashControlBase {
275 status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash, bool keepDeviceOpen);
276
277 sp<CameraProviderManager> mProviderManager;
278- const camera_module_callbacks_t *mCallbacks;
279+ CameraProviderManager::StatusListener* mCallbacks;
280 sp<CameraHardwareInterface> mDevice;
281 String8 mCameraId;
282 CameraParameters mParameters;
283diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
284index 01220e3..de0fac5 100644
285--- a/services/camera/libcameraservice/CameraService.cpp
286+++ b/services/camera/libcameraservice/CameraService.cpp
287@@ -109,79 +109,13 @@ static void setLogLevel(int level) {
288
289 // ----------------------------------------------------------------------------
290
291-extern "C" {
292-static void camera_device_status_change(
293- const struct camera_module_callbacks* callbacks,
294- int camera_id,
295- int new_status) {
296- sp<CameraService> cs = const_cast<CameraService*>(
297- static_cast<const CameraService*>(callbacks));
298- String8 id = String8::format("%d", camera_id);
299-
300- CameraDeviceStatus newStatus{CameraDeviceStatus::NOT_PRESENT};
301- switch (new_status) {
302- case CAMERA_DEVICE_STATUS_NOT_PRESENT:
303- newStatus = CameraDeviceStatus::NOT_PRESENT;
304- break;
305- case CAMERA_DEVICE_STATUS_PRESENT:
306- newStatus = CameraDeviceStatus::PRESENT;
307- break;
308- case CAMERA_DEVICE_STATUS_ENUMERATING:
309- newStatus = CameraDeviceStatus::ENUMERATING;
310- break;
311- default:
312- ALOGW("Unknown device status change to %d", new_status);
313- break;
314- }
315- cs->onDeviceStatusChanged(id, newStatus);
316-}
317-
318-static void torch_mode_status_change(
319- const struct camera_module_callbacks* callbacks,
320- const char* camera_id,
321- int new_status) {
322- if (!callbacks || !camera_id) {
323- ALOGE("%s invalid parameters. callbacks %p, camera_id %p", __FUNCTION__,
324- callbacks, camera_id);
325- }
326- sp<CameraService> cs = const_cast<CameraService*>(
327- static_cast<const CameraService*>(callbacks));
328-
329- TorchModeStatus status;
330- switch (new_status) {
331- case TORCH_MODE_STATUS_NOT_AVAILABLE:
332- status = TorchModeStatus::NOT_AVAILABLE;
333- break;
334- case TORCH_MODE_STATUS_AVAILABLE_OFF:
335- status = TorchModeStatus::AVAILABLE_OFF;
336- break;
337- case TORCH_MODE_STATUS_AVAILABLE_ON:
338- status = TorchModeStatus::AVAILABLE_ON;
339- break;
340- default:
341- ALOGE("Unknown torch status %d", new_status);
342- return;
343- }
344-
345- cs->onTorchStatusChanged(
346- String8(camera_id),
347- status);
348-}
349-} // extern "C"
350-
351-// ----------------------------------------------------------------------------
352-
353 static const String16 sManageCameraPermission("android.permission.MANAGE_CAMERA");
354
355 CameraService::CameraService() :
356 mEventLog(DEFAULT_EVENT_LOG_LENGTH),
357- mNumberOfCameras(0), mNumberOfNormalCameras(0),
358+ mNumberOfCameras(0),
359 mSoundRef(0), mInitialized(false) {
360 ALOGI("CameraService started (pid=%d)", getpid());
361-
362- this->camera_device_status_change = android::camera_device_status_change;
363- this->torch_mode_status_change = android::torch_mode_status_change;
364-
365 mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
366 }
367
368@@ -211,72 +145,43 @@ void CameraService::onFirstRef()
369
370 status_t CameraService::enumerateProviders() {
371 status_t res;
372- Mutex::Autolock l(mServiceLock);
373
374- if (nullptr == mCameraProviderManager.get()) {
375- mCameraProviderManager = new CameraProviderManager();
376- res = mCameraProviderManager->initialize(this);
377- if (res != OK) {
378- ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
379- __FUNCTION__, strerror(-res), res);
380- return res;
381- }
382- }
383+ std::vector<std::string> deviceIds;
384+ {
385+ Mutex::Autolock l(mServiceLock);
386
387- mNumberOfCameras = mCameraProviderManager->getCameraCount();
388- mNumberOfNormalCameras =
389- mCameraProviderManager->getAPI1CompatibleCameraCount();
390+ if (nullptr == mCameraProviderManager.get()) {
391+ mCameraProviderManager = new CameraProviderManager();
392+ res = mCameraProviderManager->initialize(this);
393+ if (res != OK) {
394+ ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
395+ __FUNCTION__, strerror(-res), res);
396+ return res;
397+ }
398+ }
399
400- // Setup vendor tags before we call get_camera_info the first time
401- // because HAL might need to setup static vendor keys in get_camera_info
402- // TODO: maybe put this into CameraProviderManager::initialize()?
403- mCameraProviderManager->setUpVendorTags();
404
405- if (nullptr == mFlashlight.get()) {
406- mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
407- }
408+ // Setup vendor tags before we call get_camera_info the first time
409+ // because HAL might need to setup static vendor keys in get_camera_info
410+ // TODO: maybe put this into CameraProviderManager::initialize()?
411+ mCameraProviderManager->setUpVendorTags();
412
413- res = mFlashlight->findFlashUnits();
414- if (res != OK) {
415- ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
416- }
417-
418- for (auto& cameraId : mCameraProviderManager->getCameraDeviceIds()) {
419- String8 id8 = String8(cameraId.c_str());
420- bool cameraFound = false;
421- {
422+ if (nullptr == mFlashlight.get()) {
423+ mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
424+ }
425
426- Mutex::Autolock lock(mCameraStatesLock);
427- auto iter = mCameraStates.find(id8);
428- if (iter != mCameraStates.end()) {
429- cameraFound = true;
430- }
431+ res = mFlashlight->findFlashUnits();
432+ if (res != OK) {
433+ ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
434 }
435
436- if (!cameraFound) {
437- hardware::camera::common::V1_0::CameraResourceCost cost;
438- res = mCameraProviderManager->getResourceCost(cameraId, &cost);
439- if (res != OK) {
440- ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
441- continue;
442- }
443- std::set<String8> conflicting;
444- for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
445- conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
446- }
447+ deviceIds = mCameraProviderManager->getCameraDeviceIds();
448+ }
449
450- {
451- Mutex::Autolock lock(mCameraStatesLock);
452- mCameraStates.emplace(id8,
453- std::make_shared<CameraState>(id8, cost.resourceCost, conflicting));
454- }
455- }
456
457+ for (auto& cameraId : deviceIds) {
458+ String8 id8 = String8(cameraId.c_str());
459 onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
460-
461- if (mFlashlight->hasFlashUnit(id8)) {
462- mTorchStatusMap.add(id8, TorchModeStatus::AVAILABLE_OFF);
463- }
464 }
465
466 return OK;
467@@ -312,6 +217,54 @@ void CameraService::onNewProviderRegistered() {
468 enumerateProviders();
469 }
470
471+void CameraService::updateCameraNumAndIds() {
472+ Mutex::Autolock l(mServiceLock);
473+ mNumberOfCameras = mCameraProviderManager->getCameraCount();
474+ mNormalDeviceIds =
475+ mCameraProviderManager->getAPI1CompatibleCameraDeviceIds();
476+}
477+
478+void CameraService::addStates(const String8 id) {
479+ std::string cameraId(id.c_str());
480+ hardware::camera::common::V1_0::CameraResourceCost cost;
481+ status_t res = mCameraProviderManager->getResourceCost(cameraId, &cost);
482+ if (res != OK) {
483+ ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
484+ return;
485+ }
486+ std::set<String8> conflicting;
487+ for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
488+ conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
489+ }
490+
491+ {
492+ Mutex::Autolock lock(mCameraStatesLock);
493+ mCameraStates.emplace(id, std::make_shared<CameraState>(id, cost.resourceCost,
494+ conflicting));
495+ }
496+
497+ if (mFlashlight->hasFlashUnit(id)) {
498+ Mutex::Autolock al(mTorchStatusMutex);
499+ mTorchStatusMap.add(id, TorchModeStatus::AVAILABLE_OFF);
500+ }
501+
502+ updateCameraNumAndIds();
503+ logDeviceAdded(id, "Device added");
504+}
505+
506+void CameraService::removeStates(const String8 id) {
507+ updateCameraNumAndIds();
508+ if (mFlashlight->hasFlashUnit(id)) {
509+ Mutex::Autolock al(mTorchStatusMutex);
510+ mTorchStatusMap.removeItem(id);
511+ }
512+
513+ {
514+ Mutex::Autolock lock(mCameraStatesLock);
515+ mCameraStates.erase(id);
516+ }
517+}
518+
519 void CameraService::onDeviceStatusChanged(const String8& id,
520 CameraDeviceStatus newHalStatus) {
521 ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__,
522@@ -323,8 +276,13 @@ void CameraService::onDeviceStatusChanged(const String8& id,
523
524 if (state == nullptr) {
525 if (newStatus == StatusInternal::PRESENT) {
526- ALOGW("%s: Unknown camera ID %s, probably newly registered?",
527+ ALOGI("%s: Unknown camera ID %s, a new camera is added",
528 __FUNCTION__, id.string());
529+
530+ // First add as absent to make sure clients are notified below
531+ addStates(id);
532+
533+ updateStatus(newStatus, id);
534 } else {
535 ALOGE("%s: Bad camera ID %s", __FUNCTION__, id.string());
536 }
537@@ -341,15 +299,16 @@ void CameraService::onDeviceStatusChanged(const String8& id,
538 if (newStatus == StatusInternal::NOT_PRESENT) {
539 logDeviceRemoved(id, String8::format("Device status changed from %d to %d", oldStatus,
540 newStatus));
541+
542+ // Set the device status to NOT_PRESENT, clients will no longer be able to connect
543+ // to this device until the status changes
544+ updateStatus(StatusInternal::NOT_PRESENT, id);
545+
546 sp<BasicClient> clientToDisconnect;
547 {
548 // Don't do this in updateStatus to avoid deadlock over mServiceLock
549 Mutex::Autolock lock(mServiceLock);
550
551- // Set the device status to NOT_PRESENT, clients will no longer be able to connect
552- // to this device until the status changes
553- updateStatus(StatusInternal::NOT_PRESENT, id);
554-
555 // Remove cached shim parameters
556 state->setShimParams(CameraParameters());
557
558@@ -371,6 +330,7 @@ void CameraService::onDeviceStatusChanged(const String8& id,
559 clientToDisconnect->disconnect();
560 }
561
562+ removeStates(id);
563 } else {
564 if (oldStatus == StatusInternal::NOT_PRESENT) {
565 logDeviceAdded(id, String8::format("Device status changed from %d to %d", oldStatus,
566@@ -451,7 +411,7 @@ Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
567 Mutex::Autolock l(mServiceLock);
568 switch (type) {
569 case CAMERA_TYPE_BACKWARD_COMPATIBLE:
570- *numCameras = mNumberOfNormalCameras;
571+ *numCameras = static_cast<int>(mNormalDeviceIds.size());
572 break;
573 case CAMERA_TYPE_ALL:
574 *numCameras = mNumberOfCameras;
575@@ -481,7 +441,8 @@ Status CameraService::getCameraInfo(int cameraId,
576 }
577
578 Status ret = Status::ok();
579- status_t err = mCameraProviderManager->getCameraInfo(std::to_string(cameraId), cameraInfo);
580+ status_t err = mCameraProviderManager->getCameraInfo(
581+ cameraIdIntToStrLocked(cameraId), cameraInfo);
582 if (err != OK) {
583 ret = STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
584 "Error retrieving camera info from device %d: %s (%d)", cameraId,
585@@ -491,13 +452,19 @@ Status CameraService::getCameraInfo(int cameraId,
586 return ret;
587 }
588
589-int CameraService::cameraIdToInt(const String8& cameraId) {
590- int id;
591- bool success = base::ParseInt(cameraId.string(), &id, 0);
592- if (!success) {
593- return -1;
594+std::string CameraService::cameraIdIntToStrLocked(int cameraIdInt) {
595+ if (cameraIdInt < 0 || cameraIdInt >= static_cast<int>(mNormalDeviceIds.size())) {
596+ ALOGE("%s: input id %d invalid: valid range (0, %zu)",
597+ __FUNCTION__, cameraIdInt, mNormalDeviceIds.size());
598+ return std::string{};
599 }
600- return id;
601+
602+ return mNormalDeviceIds[cameraIdInt];
603+}
604+
605+String8 CameraService::cameraIdIntToStr(int cameraIdInt) {
606+ Mutex::Autolock lock(mServiceLock);
607+ return String8(cameraIdIntToStrLocked(cameraIdInt).c_str());
608 }
609
610 Status CameraService::getCameraCharacteristics(const String16& cameraId,
611@@ -614,8 +581,8 @@ Status CameraService::filterGetInfoErrorCode(status_t err) {
612
613 Status CameraService::makeClient(const sp<CameraService>& cameraService,
614 const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
615- int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
616- int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
617+ int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,
618+ bool legacyMode, int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
619 /*out*/sp<BasicClient>* client) {
620
621 if (halVersion < 0 || halVersion == deviceVersion) {
622@@ -625,8 +592,9 @@ Status CameraService::makeClient(const sp<CameraService>& cameraService,
623 case CAMERA_DEVICE_API_VERSION_1_0:
624 if (effectiveApiLevel == API_1) { // Camera1 API route
625 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
626- *client = new CameraClient(cameraService, tmp, packageName, cameraIdToInt(cameraId),
627- facing, clientPid, clientUid, getpid(), legacyMode);
628+ *client = new CameraClient(cameraService, tmp, packageName,
629+ api1CameraId, facing, clientPid, clientUid,
630+ getpid(), legacyMode);
631 } else { // Camera2 API route
632 ALOGW("Camera using old HAL version: %d", deviceVersion);
633 return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
634@@ -641,8 +609,10 @@ Status CameraService::makeClient(const sp<CameraService>& cameraService,
635 case CAMERA_DEVICE_API_VERSION_3_4:
636 if (effectiveApiLevel == API_1) { // Camera1 API route
637 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
638- *client = new Camera2Client(cameraService, tmp, packageName, cameraIdToInt(cameraId),
639- facing, clientPid, clientUid, servicePid, legacyMode);
640+ *client = new Camera2Client(cameraService, tmp, packageName,
641+ cameraId, api1CameraId,
642+ facing, clientPid, clientUid,
643+ servicePid, legacyMode);
644 } else { // Camera2 API route
645 sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
646 static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
647@@ -664,8 +634,9 @@ Status CameraService::makeClient(const sp<CameraService>& cameraService,
648 halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
649 // Only support higher HAL version device opened as HAL1.0 device.
650 sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
651- *client = new CameraClient(cameraService, tmp, packageName, cameraIdToInt(cameraId),
652- facing, clientPid, clientUid, servicePid, legacyMode);
653+ *client = new CameraClient(cameraService, tmp, packageName,
654+ api1CameraId, facing, clientPid, clientUid,
655+ servicePid, legacyMode);
656 } else {
657 // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
658 ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
659@@ -765,7 +736,8 @@ Status CameraService::initializeShimMetadata(int cameraId) {
660 Status ret = Status::ok();
661 sp<Client> tmp = nullptr;
662 if (!(ret = connectHelper<ICameraClient,Client>(
663- sp<ICameraClient>{nullptr}, id, static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED),
664+ sp<ICameraClient>{nullptr}, id, cameraId,
665+ static_cast<int>(CAMERA_HAL_API_VERSION_UNSPECIFIED),
666 internalPackageName, uid, USE_CALLING_PID,
667 API_1, /*legacyMode*/ false, /*shimUpdateOnly*/ true,
668 /*out*/ tmp)
669@@ -1222,7 +1194,7 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien
670
671 Status CameraService::connect(
672 const sp<ICameraClient>& cameraClient,
673- int cameraId,
674+ int api1CameraId,
675 const String16& clientPackageName,
676 int clientUid,
677 int clientPid,
678@@ -1231,9 +1203,10 @@ Status CameraService::connect(
679
680 ATRACE_CALL();
681 Status ret = Status::ok();
682- String8 id = String8::format("%d", cameraId);
683+
684+ String8 id = cameraIdIntToStr(api1CameraId);
685 sp<Client> client = nullptr;
686- ret = connectHelper<ICameraClient,Client>(cameraClient, id,
687+ ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
688 CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, clientPid, API_1,
689 /*legacyMode*/ false, /*shimUpdateOnly*/ false,
690 /*out*/client);
691@@ -1250,18 +1223,18 @@ Status CameraService::connect(
692
693 Status CameraService::connectLegacy(
694 const sp<ICameraClient>& cameraClient,
695- int cameraId, int halVersion,
696+ int api1CameraId, int halVersion,
697 const String16& clientPackageName,
698 int clientUid,
699 /*out*/
700 sp<ICamera>* device) {
701
702 ATRACE_CALL();
703- String8 id = String8::format("%d", cameraId);
704+ String8 id = cameraIdIntToStr(api1CameraId);
705
706 Status ret = Status::ok();
707 sp<Client> client = nullptr;
708- ret = connectHelper<ICameraClient,Client>(cameraClient, id, halVersion,
709+ ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId, halVersion,
710 clientPackageName, clientUid, USE_CALLING_PID, API_1,
711 /*legacyMode*/ true, /*shimUpdateOnly*/ false,
712 /*out*/client);
713@@ -1289,6 +1262,7 @@ Status CameraService::connectDevice(
714 String8 id = String8(cameraId);
715 sp<CameraDeviceClient> client = nullptr;
716 ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
717+ /*api1CameraId*/-1,
718 CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
719 clientUid, USE_CALLING_PID, API_2,
720 /*legacyMode*/ false, /*shimUpdateOnly*/ false,
721@@ -1306,8 +1280,8 @@ Status CameraService::connectDevice(
722
723 template<class CALLBACK, class CLIENT>
724 Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
725- int halVersion, const String16& clientPackageName, int clientUid, int clientPid,
726- apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
727+ int api1CameraId, int halVersion, const String16& clientPackageName, int clientUid,
728+ int clientPid, apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
729 /*out*/sp<CLIENT>& device) {
730 binder::Status ret = binder::Status::ok();
731
732@@ -1390,8 +1364,10 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8&
733 }
734
735 sp<BasicClient> tmp = nullptr;
736- if(!(ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid,
737- clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
738+ if(!(ret = makeClient(this, cameraCb, clientPackageName,
739+ cameraId, api1CameraId, facing,
740+ clientPid, clientUid, getpid(), legacyMode,
741+ halVersion, deviceVersion, effectiveApiLevel,
742 /*out*/&tmp)).isOk()) {
743 return ret;
744 }
745@@ -2102,7 +2078,8 @@ void CameraService::playSound(sound_kind kind) {
746 CameraService::Client::Client(const sp<CameraService>& cameraService,
747 const sp<ICameraClient>& cameraClient,
748 const String16& clientPackageName,
749- const String8& cameraIdStr, int cameraFacing,
750+ const String8& cameraIdStr,
751+ int api1CameraId, int cameraFacing,
752 int clientPid, uid_t clientUid,
753 int servicePid) :
754 CameraService::BasicClient(cameraService,
755@@ -2111,7 +2088,7 @@ CameraService::Client::Client(const sp<CameraService>& cameraService,
756 cameraIdStr, cameraFacing,
757 clientPid, clientUid,
758 servicePid),
759- mCameraId(CameraService::cameraIdToInt(cameraIdStr))
760+ mCameraId(api1CameraId)
761 {
762 int callingPid = getCallingPid();
763 LOG1("Client::Client E (pid %d, id %d)", callingPid, mCameraId);
764@@ -2279,9 +2256,13 @@ status_t CameraService::BasicClient::startCameraOps() {
765 // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
766 sCameraService->updateStatus(StatusInternal::NOT_AVAILABLE, mCameraIdStr);
767
768+ int apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1;
769+ if (canCastToApiClient(API_2)) {
770+ apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2;
771+ }
772 // Transition device state to OPEN
773 sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_OPEN,
774- mCameraIdStr, mCameraFacing, mClientPackageName);
775+ mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
776
777 return OK;
778 }
779@@ -2296,16 +2277,23 @@ status_t CameraService::BasicClient::finishCameraOps() {
780 mClientPackageName);
781 mOpsActive = false;
782
783+ // This function is called when a client disconnects. This should
784+ // release the camera, but actually only if it was in a proper
785+ // functional state, i.e. with status NOT_AVAILABLE
786 std::initializer_list<StatusInternal> rejected = {StatusInternal::PRESENT,
787- StatusInternal::ENUMERATING};
788+ StatusInternal::ENUMERATING, StatusInternal::NOT_PRESENT};
789
790 // Transition to PRESENT if the camera is not in either of the rejected states
791 sCameraService->updateStatus(StatusInternal::PRESENT,
792 mCameraIdStr, rejected);
793
794+ int apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1;
795+ if (canCastToApiClient(API_2)) {
796+ apiLevel = hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2;
797+ }
798 // Transition device state to CLOSED
799 sCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_CLOSED,
800- mCameraIdStr, mCameraFacing, mClientPackageName);
801+ mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
802 }
803 // Always stop watching, even if no camera op is active
804 if (mOpsCallback != NULL) {
805@@ -2548,7 +2536,7 @@ void CameraService::UidPolicy::updateOverrideUid(uid_t uid, String16 callingPack
806
807 CameraService::CameraState::CameraState(const String8& id, int cost,
808 const std::set<String8>& conflicting) : mId(id),
809- mStatus(StatusInternal::PRESENT), mCost(cost), mConflicting(conflicting) {}
810+ mStatus(StatusInternal::NOT_PRESENT), mCost(cost), mConflicting(conflicting) {}
811
812 CameraService::CameraState::~CameraState() {}
813
814@@ -2724,7 +2712,10 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) {
815 }
816 dprintf(fd, "\n== Service global info: ==\n\n");
817 dprintf(fd, "Number of camera devices: %d\n", mNumberOfCameras);
818- dprintf(fd, "Number of normal camera devices: %d\n", mNumberOfNormalCameras);
819+ dprintf(fd, "Number of normal camera devices: %zu\n", mNormalDeviceIds.size());
820+ for (size_t i = 0; i < mNormalDeviceIds.size(); i++) {
821+ dprintf(fd, " Device %zu maps to \"%s\"\n", i, mNormalDeviceIds[i].c_str());
822+ }
823 String8 activeClientString = mActiveClientManager.toString();
824 dprintf(fd, "Active Camera Clients:\n%s", activeClientString.string());
825 dprintf(fd, "Allowed user IDs: %s\n", toString(mAllowedUsers).string());
826@@ -2979,11 +2970,11 @@ void CameraService::CameraState::updateStatus(StatusInternal status,
827 }
828
829 void CameraService::updateProxyDeviceState(int newState,
830- const String8& cameraId, int facing, const String16& clientName) {
831+ const String8& cameraId, int facing, const String16& clientName, int apiLevel) {
832 sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
833 if (proxyBinder == nullptr) return;
834 String16 id(cameraId);
835- proxyBinder->notifyCameraState(id, newState, facing, clientName);
836+ proxyBinder->notifyCameraState(id, newState, facing, clientName, apiLevel);
837 }
838
839 status_t CameraService::getTorchStatusLocked(
840diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
841index 6724c49..8d4bcdb 100644
842--- a/services/camera/libcameraservice/CameraService.h
843+++ b/services/camera/libcameraservice/CameraService.h
844@@ -62,7 +62,6 @@ class CameraService :
845 public BinderService<CameraService>,
846 public virtual ::android::hardware::BnCameraService,
847 public virtual IBinder::DeathRecipient,
848- public camera_module_callbacks_t,
849 public virtual CameraProviderManager::StatusListener
850 {
851 friend class BinderService<CameraService>;
852@@ -190,7 +189,8 @@ public:
853 int newState,
854 const String8& cameraId,
855 int facing,
856- const String16& clientName);
857+ const String16& clientName,
858+ int apiLevel);
859
860 /////////////////////////////////////////////////////////////////////
861 // CameraDeviceFactory functionality
862@@ -334,6 +334,7 @@ public:
863 const sp<hardware::ICameraClient>& cameraClient,
864 const String16& clientPackageName,
865 const String8& cameraIdStr,
866+ int api1CameraId,
867 int cameraFacing,
868 int clientPid,
869 uid_t clientUid,
870@@ -555,6 +556,11 @@ private:
871 // Eumerate all camera providers in the system
872 status_t enumerateProviders();
873
874+ // Add/remove a new camera to camera and torch state lists or remove an unplugged one
875+ // Caller must not hold mServiceLock
876+ void addStates(const String8 id);
877+ void removeStates(const String8 id);
878+
879 // Check if we can connect, before we acquire the service lock.
880 // The returned originalClientPid is the PID of the original process that wants to connect to
881 // camera.
882@@ -578,7 +584,7 @@ private:
883 // Single implementation shared between the various connect calls
884 template<class CALLBACK, class CLIENT>
885 binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
886- int halVersion, const String16& clientPackageName,
887+ int api1CameraId, int halVersion, const String16& clientPackageName,
888 int clientUid, int clientPid,
889 apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
890 /*out*/sp<CLIENT>& device);
891@@ -643,9 +649,16 @@ private:
892 void finishConnectLocked(const sp<BasicClient>& client, const DescriptorPtr& desc);
893
894 /**
895- * Returns the integer corresponding to the given camera ID string, or -1 on failure.
896+ * Returns the underlying camera Id string mapped to a camera id int
897+ * Empty string is returned when the cameraIdInt is invalid.
898+ */
899+ String8 cameraIdIntToStr(int cameraIdInt);
900+
901+ /**
902+ * Returns the underlying camera Id string mapped to a camera id int
903+ * Empty string is returned when the cameraIdInt is invalid.
904 */
905- static int cameraIdToInt(const String8& cameraId);
906+ std::string cameraIdIntToStrLocked(int cameraIdInt);
907
908 /**
909 * Remove a single client corresponding to the given camera id from the list of active clients.
910@@ -713,8 +726,14 @@ private:
911 */
912 void dumpEventLog(int fd);
913
914+ /**
915+ * This method will acquire mServiceLock
916+ */
917+ void updateCameraNumAndIds();
918+
919 int mNumberOfCameras;
920- int mNumberOfNormalCameras;
921+
922+ std::vector<std::string> mNormalDeviceIds;
923
924 // sounds
925 sp<MediaPlayer> newMediaPlayer(const char *file);
926@@ -824,8 +843,8 @@ private:
927
928 static binder::Status makeClient(const sp<CameraService>& cameraService,
929 const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
930- int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
931- int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
932+ int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,
933+ bool legacyMode, int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
934 /*out*/sp<BasicClient>* client);
935
936 status_t checkCameraAccess(const String16& opPackageName);
937diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
938index dd1cf2c..65faac9 100644
939--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
940+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
941@@ -49,16 +49,17 @@ static int getCallingPid() {
942 Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
943 const sp<hardware::ICameraClient>& cameraClient,
944 const String16& clientPackageName,
945- int cameraId,
946+ const String8& cameraDeviceId,
947+ int api1CameraId,
948 int cameraFacing,
949 int clientPid,
950 uid_t clientUid,
951 int servicePid,
952 bool legacyMode):
953 Camera2ClientBase(cameraService, cameraClient, clientPackageName,
954- String8::format("%d", cameraId), cameraFacing,
955+ cameraDeviceId, api1CameraId, cameraFacing,
956 clientPid, clientUid, servicePid),
957- mParameters(cameraId, cameraFacing)
958+ mParameters(api1CameraId, cameraFacing)
959 {
960 ATRACE_CALL();
961
962diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
963index c17cbd4..44929c3 100644
964--- a/services/camera/libcameraservice/api1/Camera2Client.h
965+++ b/services/camera/libcameraservice/api1/Camera2Client.h
966@@ -91,7 +91,8 @@ public:
967 Camera2Client(const sp<CameraService>& cameraService,
968 const sp<hardware::ICameraClient>& cameraClient,
969 const String16& clientPackageName,
970- int cameraId,
971+ const String8& cameraDeviceId,
972+ int api1CameraId,
973 int cameraFacing,
974 int clientPid,
975 uid_t clientUid,
976diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
977index e2c8b8b..2358c1e 100644
978--- a/services/camera/libcameraservice/api1/CameraClient.cpp
979+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
980@@ -42,7 +42,7 @@ CameraClient::CameraClient(const sp<CameraService>& cameraService,
981 int clientPid, int clientUid,
982 int servicePid, bool legacyMode):
983 Client(cameraService, cameraClient, clientPackageName,
984- String8::format("%d", cameraId), cameraFacing, clientPid,
985+ String8::format("%d", cameraId), cameraId, cameraFacing, clientPid,
986 clientUid, servicePid)
987 {
988 int callingPid = getCallingPid();
989@@ -264,7 +264,8 @@ binder::Status CameraClient::disconnect() {
990 mHardware->stopPreview();
991 sCameraService->updateProxyDeviceState(
992 hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
993- mCameraIdStr, mCameraFacing, mClientPackageName);
994+ mCameraIdStr, mCameraFacing, mClientPackageName,
995+ hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
996 mHardware->cancelPicture();
997 // Release the hardware resources.
998 mHardware->release();
999@@ -427,7 +428,8 @@ status_t CameraClient::startPreviewMode() {
1000 if (result == NO_ERROR) {
1001 sCameraService->updateProxyDeviceState(
1002 hardware::ICameraServiceProxy::CAMERA_STATE_ACTIVE,
1003- mCameraIdStr, mCameraFacing, mClientPackageName);
1004+ mCameraIdStr, mCameraFacing, mClientPackageName,
1005+ hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
1006 }
1007 return result;
1008 }
1009@@ -470,7 +472,8 @@ void CameraClient::stopPreview() {
1010 mHardware->stopPreview();
1011 sCameraService->updateProxyDeviceState(
1012 hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
1013- mCameraIdStr, mCameraFacing, mClientPackageName);
1014+ mCameraIdStr, mCameraFacing, mClientPackageName,
1015+ hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
1016 mPreviewBuffer.clear();
1017 }
1018
1019@@ -981,7 +984,8 @@ void CameraClient::handleShutter(void) {
1020 // idle now, until preview is restarted
1021 sCameraService->updateProxyDeviceState(
1022 hardware::ICameraServiceProxy::CAMERA_STATE_IDLE,
1023- mCameraIdStr, mCameraFacing, mClientPackageName);
1024+ mCameraIdStr, mCameraFacing, mClientPackageName,
1025+ hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1);
1026
1027 mLock.unlock();
1028 }
1029diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp
1030index 7373b81..d66dec4 100644
1031--- a/services/camera/libcameraservice/api1/client2/Parameters.cpp
1032+++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp
1033@@ -761,12 +761,17 @@ status_t Parameters::initialize(const CameraMetadata *info, int deviceVersion) {
1034 focusingAreas.clear();
1035 focusingAreas.add(Parameters::Area(0,0,0,0,0));
1036
1037- camera_metadata_ro_entry_t availableFocalLengths =
1038- staticInfo(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, 0, 0, false);
1039- if (!availableFocalLengths.count) return NO_INIT;
1040+ if (fastInfo.isExternalCamera) {
1041+ params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, -1.0);
1042+ } else {
1043+ camera_metadata_ro_entry_t availableFocalLengths =
1044+ staticInfo(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, 0, 0, false);
1045+ if (!availableFocalLengths.count) return NO_INIT;
1046+
1047+ float minFocalLength = availableFocalLengths.data.f[0];
1048+ params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
1049+ }
1050
1051- float minFocalLength = availableFocalLengths.data.f[0];
1052- params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
1053
1054 float horizFov, vertFov;
1055 res = calculatePictureFovs(&horizFov, &vertFov);
1056@@ -1104,9 +1109,15 @@ status_t Parameters::buildFastInfo() {
1057 focusDistanceCalibration.data.u8[0] !=
1058 ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED);
1059
1060+
1061+ camera_metadata_ro_entry_t hwLevel = staticInfo(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL);
1062+ if (!hwLevel.count) return NO_INIT;
1063+ fastInfo.isExternalCamera =
1064+ hwLevel.data.u8[0] == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL;
1065+
1066 camera_metadata_ro_entry_t availableFocalLengths =
1067- staticInfo(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
1068- if (!availableFocalLengths.count) return NO_INIT;
1069+ staticInfo(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, 0, 0, /*required*/false);
1070+ if (!availableFocalLengths.count && !fastInfo.isExternalCamera) return NO_INIT;
1071
1072 SortedVector<int32_t> availableFormats = getAvailableOutputFormats();
1073 if (!availableFormats.size()) return NO_INIT;
1074@@ -1191,10 +1202,14 @@ status_t Parameters::buildFastInfo() {
1075
1076 // Find smallest (widest-angle) focal length to use as basis of still
1077 // picture FOV reporting.
1078- fastInfo.minFocalLength = availableFocalLengths.data.f[0];
1079- for (size_t i = 1; i < availableFocalLengths.count; i++) {
1080- if (fastInfo.minFocalLength > availableFocalLengths.data.f[i]) {
1081- fastInfo.minFocalLength = availableFocalLengths.data.f[i];
1082+ if (fastInfo.isExternalCamera) {
1083+ fastInfo.minFocalLength = -1.0;
1084+ } else {
1085+ fastInfo.minFocalLength = availableFocalLengths.data.f[0];
1086+ for (size_t i = 1; i < availableFocalLengths.count; i++) {
1087+ if (fastInfo.minFocalLength > availableFocalLengths.data.f[i]) {
1088+ fastInfo.minFocalLength = availableFocalLengths.data.f[i];
1089+ }
1090 }
1091 }
1092
1093@@ -2921,8 +2936,13 @@ status_t Parameters::getFilteredSizes(Size limit, Vector<Size> *sizes) {
1094 if (sc.isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT &&
1095 sc.format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
1096 sc.width <= limit.width && sc.height <= limit.height) {
1097- Size sz = {sc.width, sc.height};
1098- sizes->push(sz);
1099+ int64_t minFrameDuration = getMinFrameDurationNs(
1100+ {sc.width, sc.height}, HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED);
1101+ if (minFrameDuration > MAX_PREVIEW_RECORD_DURATION_NS) {
1102+ // Filter slow sizes from preview/record
1103+ continue;
1104+ }
1105+ sizes->push({sc.width, sc.height});
1106 }
1107 }
1108
1109@@ -3132,6 +3152,16 @@ Parameters::CropRegion Parameters::calculateCropRegion(bool previewOnly) const {
1110
1111 status_t Parameters::calculatePictureFovs(float *horizFov, float *vertFov)
1112 const {
1113+ if (fastInfo.isExternalCamera) {
1114+ if (horizFov != NULL) {
1115+ *horizFov = -1.0;
1116+ }
1117+ if (vertFov != NULL) {
1118+ *vertFov = -1.0;
1119+ }
1120+ return OK;
1121+ }
1122+
1123 camera_metadata_ro_entry_t sensorSize =
1124 staticInfo(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, 2, 2);
1125 if (!sensorSize.count) return NO_INIT;
1126diff --git a/services/camera/libcameraservice/api1/client2/Parameters.h b/services/camera/libcameraservice/api1/client2/Parameters.h
1127index f0bde5b..97f8ea7 100644
1128--- a/services/camera/libcameraservice/api1/client2/Parameters.h
1129+++ b/services/camera/libcameraservice/api1/client2/Parameters.h
1130@@ -209,6 +209,11 @@ struct Parameters {
1131 static const int32_t FPS_MARGIN = 1;
1132 // Max FPS for default parameters
1133 static const int32_t MAX_DEFAULT_FPS = 30;
1134+ // Minimum FPS for a size to be listed in supported preview/video sizes
1135+ // Set to slightly less than 30.0 to have some tolerance margin
1136+ static constexpr double MIN_PREVIEW_RECORD_FPS = 29.97;
1137+ // Maximum frame duration for a size to be listed in supported preview/video sizes
1138+ static constexpr int64_t MAX_PREVIEW_RECORD_DURATION_NS = 1e9 / MIN_PREVIEW_RECORD_FPS;
1139
1140 // Full static camera info, object owned by someone else, such as
1141 // Camera2Device.
1142@@ -235,6 +240,7 @@ struct Parameters {
1143 }
1144 };
1145 DefaultKeyedVector<uint8_t, OverrideModes> sceneModeOverrides;
1146+ bool isExternalCamera;
1147 float minFocalLength;
1148 bool useFlexibleYuv;
1149 Size maxJpegSize;
1150@@ -383,6 +389,7 @@ private:
1151 Vector<Size> availablePreviewSizes;
1152 Vector<Size> availableVideoSizes;
1153 // Get size list (that are no larger than limit) from static metadata.
1154+ // This method filtered size with minFrameDuration < MAX_PREVIEW_RECORD_DURATION_NS
1155 status_t getFilteredSizes(Size limit, Vector<Size> *sizes);
1156 // Get max size (from the size array) that matches the given aspect ratio.
1157 Size getMaxSizeForRatio(float ratio, const int32_t* sizeArray, size_t count);
1158diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
1159index 2297ed3..98d0534 100644
1160--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
1161+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
1162@@ -49,6 +49,7 @@ CameraDeviceClientBase::CameraDeviceClientBase(
1163 const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
1164 const String16& clientPackageName,
1165 const String8& cameraId,
1166+ int api1CameraId,
1167 int cameraFacing,
1168 int clientPid,
1169 uid_t clientUid,
1170@@ -62,6 +63,8 @@ CameraDeviceClientBase::CameraDeviceClientBase(
1171 clientUid,
1172 servicePid),
1173 mRemoteCallback(remoteCallback) {
1174+ // We don't need it for API2 clients, but Camera2ClientBase requires it.
1175+ (void) api1CameraId;
1176 }
1177
1178 // Interface used by CameraService
1179@@ -75,7 +78,8 @@ CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
1180 uid_t clientUid,
1181 int servicePid) :
1182 Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
1183- cameraId, cameraFacing, clientPid, clientUid, servicePid),
1184+ cameraId, /*API1 camera ID*/ -1,
1185+ cameraFacing, clientPid, clientUid, servicePid),
1186 mInputStream(),
1187 mStreamingRequestId(REQUEST_ID_NONE),
1188 mRequestIdCounter(0) {
1189@@ -620,11 +624,19 @@ binder::Status CameraDeviceClient::createStream(
1190 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1191 }
1192
1193- if (!checkPhysicalCameraId(physicalCameraId)) {
1194- String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
1195+ if (physicalCameraId.size() > 0) {
1196+ std::vector<std::string> physicalCameraIds;
1197+ std::string physicalId(physicalCameraId.string());
1198+ bool logicalCamera =
1199+ CameraProviderManager::isLogicalCamera(mDevice->info(), &physicalCameraIds);
1200+ if (!logicalCamera ||
1201+ std::find(physicalCameraIds.begin(), physicalCameraIds.end(), physicalId) ==
1202+ physicalCameraIds.end()) {
1203+ String8 msg = String8::format("Camera %s: Camera doesn't support physicalCameraId %s.",
1204 mCameraIdStr.string(), physicalCameraId.string());
1205- ALOGE("%s: %s", __FUNCTION__, msg.string());
1206- return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1207+ ALOGE("%s: %s", __FUNCTION__, msg.string());
1208+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1209+ }
1210 }
1211 std::vector<sp<Surface>> surfaces;
1212 std::vector<sp<IBinder>> binders;
1213@@ -1140,43 +1152,6 @@ binder::Status CameraDeviceClient::createSurfaceFromGbp(
1214 return binder::Status::ok();
1215 }
1216
1217-bool CameraDeviceClient::checkPhysicalCameraId(const String8& physicalCameraId) {
1218- if (0 == physicalCameraId.size()) {
1219- return true;
1220- }
1221-
1222- CameraMetadata staticInfo = mDevice->info();
1223- camera_metadata_entry_t entryCap;
1224- bool isLogicalCam = false;
1225-
1226- entryCap = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
1227- for (size_t i = 0; i < entryCap.count; ++i) {
1228- uint8_t capability = entryCap.data.u8[i];
1229- if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
1230- isLogicalCam = true;
1231- }
1232- }
1233- if (!isLogicalCam) {
1234- return false;
1235- }
1236-
1237- camera_metadata_entry_t entryIds = staticInfo.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
1238- const uint8_t* ids = entryIds.data.u8;
1239- size_t start = 0;
1240- for (size_t i = 0; i < entryIds.count; ++i) {
1241- if (ids[i] == '\0') {
1242- if (start != i) {
1243- String8 currentId((const char*)ids+start);
1244- if (currentId == physicalCameraId) {
1245- return true;
1246- }
1247- }
1248- start = i+1;
1249- }
1250- }
1251- return false;
1252-}
1253-
1254 bool CameraDeviceClient::roundBufferDimensionNearest(int32_t width, int32_t height,
1255 int32_t format, android_dataspace dataSpace, const CameraMetadata& info,
1256 /*out*/int32_t* outWidth, /*out*/int32_t* outHeight) {
1257diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
1258index 5bec39c..5aaf5aa 100644
1259--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
1260+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
1261@@ -45,6 +45,7 @@ protected:
1262 const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
1263 const String16& clientPackageName,
1264 const String8& cameraId,
1265+ int api1CameraId,
1266 int cameraFacing,
1267 int clientPid,
1268 uid_t clientUid,
1269diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
1270index 5c6711a..ce006a7 100644
1271--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
1272+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
1273@@ -48,15 +48,16 @@ Camera2ClientBase<TClientBase>::Camera2ClientBase(
1274 const sp<TCamCallbacks>& remoteCallback,
1275 const String16& clientPackageName,
1276 const String8& cameraId,
1277+ int api1CameraId,
1278 int cameraFacing,
1279 int clientPid,
1280 uid_t clientUid,
1281 int servicePid):
1282 TClientBase(cameraService, remoteCallback, clientPackageName,
1283- cameraId, cameraFacing, clientPid, clientUid, servicePid),
1284+ cameraId, api1CameraId, cameraFacing, clientPid, clientUid, servicePid),
1285 mSharedCameraCallbacks(remoteCallback),
1286 mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),
1287- mDeviceActive(false)
1288+ mDeviceActive(false), mApi1CameraId(api1CameraId)
1289 {
1290 ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),
1291 String8(clientPackageName).string(), clientPid, clientUid);
1292@@ -252,7 +253,9 @@ void Camera2ClientBase<TClientBase>::notifyIdle() {
1293 if (mDeviceActive) {
1294 getCameraService()->updateProxyDeviceState(
1295 hardware::ICameraServiceProxy::CAMERA_STATE_IDLE, TClientBase::mCameraIdStr,
1296- TClientBase::mCameraFacing, TClientBase::mClientPackageName);
1297+ TClientBase::mCameraFacing, TClientBase::mClientPackageName,
1298+ ((mApi1CameraId < 0) ? hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2 :
1299+ hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1));
1300 }
1301 mDeviceActive = false;
1302
1303@@ -268,7 +271,9 @@ void Camera2ClientBase<TClientBase>::notifyShutter(const CaptureResultExtras& re
1304 if (!mDeviceActive) {
1305 getCameraService()->updateProxyDeviceState(
1306 hardware::ICameraServiceProxy::CAMERA_STATE_ACTIVE, TClientBase::mCameraIdStr,
1307- TClientBase::mCameraFacing, TClientBase::mClientPackageName);
1308+ TClientBase::mCameraFacing, TClientBase::mClientPackageName,
1309+ ((mApi1CameraId < 0) ? hardware::ICameraServiceProxy::CAMERA_API_LEVEL_2 :
1310+ hardware::ICameraServiceProxy::CAMERA_API_LEVEL_1));
1311 }
1312 mDeviceActive = true;
1313
1314@@ -331,7 +336,7 @@ void Camera2ClientBase<TClientBase>::notifyRepeatingRequestError(long lastFrameN
1315
1316 template <typename TClientBase>
1317 int Camera2ClientBase<TClientBase>::getCameraId() const {
1318- return std::stoi(TClientBase::mCameraIdStr.string());
1319+ return mApi1CameraId;
1320 }
1321
1322 template <typename TClientBase>
1323diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
1324index 4da422a..e74fbdf 100644
1325--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
1326+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
1327@@ -49,6 +49,7 @@ public:
1328 const sp<TCamCallbacks>& remoteCallback,
1329 const String16& clientPackageName,
1330 const String8& cameraId,
1331+ int api1CameraId,
1332 int cameraFacing,
1333 int clientPid,
1334 uid_t clientUid,
1335@@ -140,6 +141,8 @@ protected:
1336
1337 bool mDeviceActive;
1338
1339+ const int mApi1CameraId; // -1 if client is API2
1340+
1341 private:
1342 template<typename TProviderPtr>
1343 status_t initializeImpl(TProviderPtr providerPtr, const String8& monitorTags);
1344diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
1345index 4bc78dd..21cfd44 100644
1346--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
1347+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
1348@@ -20,11 +20,13 @@
1349
1350 #include "CameraProviderManager.h"
1351
1352+#include <algorithm>
1353 #include <chrono>
1354 #include <inttypes.h>
1355 #include <hidl/ServiceManagement.h>
1356 #include <functional>
1357 #include <camera_metadata_hidden.h>
1358+#include <android-base/parseint.h>
1359
1360 namespace android {
1361
1362@@ -39,9 +41,6 @@ const std::string kLegacyProviderName("legacy/0");
1363 const std::string kExternalProviderName("external/0");
1364 #endif
1365
1366-// Slash-separated list of provider types to consider for use via the old camera API
1367-const std::string kStandardProviderTypes("internal/legacy");
1368-
1369 } // anonymous namespace
1370
1371 CameraProviderManager::HardwareServiceInteractionProxy
1372@@ -83,18 +82,7 @@ int CameraProviderManager::getCameraCount() const {
1373 std::lock_guard<std::mutex> lock(mInterfaceMutex);
1374 int count = 0;
1375 for (auto& provider : mProviders) {
1376- count += provider->mUniqueDeviceCount;
1377- }
1378- return count;
1379-}
1380-
1381-int CameraProviderManager::getAPI1CompatibleCameraCount() const {
1382- std::lock_guard<std::mutex> lock(mInterfaceMutex);
1383- int count = 0;
1384- for (auto& provider : mProviders) {
1385- if (kStandardProviderTypes.find(provider->getType()) != std::string::npos) {
1386- count += provider->mUniqueAPI1CompatibleCameraIds.size();
1387- }
1388+ count += provider->mUniqueCameraIds.size();
1389 }
1390 return count;
1391 }
1392@@ -114,12 +102,33 @@ std::vector<std::string> CameraProviderManager::getAPI1CompatibleCameraDeviceIds
1393 std::lock_guard<std::mutex> lock(mInterfaceMutex);
1394 std::vector<std::string> deviceIds;
1395 for (auto& provider : mProviders) {
1396- if (kStandardProviderTypes.find(provider->getType()) != std::string::npos) {
1397- for (auto& id : provider->mUniqueAPI1CompatibleCameraIds) {
1398- deviceIds.push_back(id);
1399- }
1400- }
1401+ std::vector<std::string> providerDeviceIds = provider->mUniqueAPI1CompatibleCameraIds;
1402+
1403+ // API1 app doesn't handle logical and physical camera devices well. So
1404+ // for each [logical, physical1, physical2, ...] id combo, only take the
1405+ // first id advertised by HAL, and filter out the rest.
1406+ filterLogicalCameraIdsLocked(providerDeviceIds);
1407+
1408+ deviceIds.insert(deviceIds.end(), providerDeviceIds.begin(), providerDeviceIds.end());
1409 }
1410+
1411+ std::sort(deviceIds.begin(), deviceIds.end(),
1412+ [](const std::string& a, const std::string& b) -> bool {
1413+ uint32_t aUint = 0, bUint = 0;
1414+ bool aIsUint = base::ParseUint(a, &aUint);
1415+ bool bIsUint = base::ParseUint(b, &bUint);
1416+
1417+ // Uint device IDs first
1418+ if (aIsUint && bIsUint) {
1419+ return aUint < bUint;
1420+ } else if (aIsUint) {
1421+ return true;
1422+ } else if (bIsUint) {
1423+ return false;
1424+ }
1425+ // Simple string compare if both id are not uint
1426+ return a < b;
1427+ });
1428 return deviceIds;
1429 }
1430
1431@@ -172,11 +181,7 @@ status_t CameraProviderManager::getCameraInfo(const std::string &id,
1432 status_t CameraProviderManager::getCameraCharacteristics(const std::string &id,
1433 CameraMetadata* characteristics) const {
1434 std::lock_guard<std::mutex> lock(mInterfaceMutex);
1435-
1436- auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
1437- if (deviceInfo == nullptr) return NAME_NOT_FOUND;
1438-
1439- return deviceInfo->getCameraCharacteristics(characteristics);
1440+ return getCameraCharacteristicsLocked(id, characteristics);
1441 }
1442
1443 status_t CameraProviderManager::getHighestSupportedVersion(const std::string &id,
1444@@ -391,6 +396,37 @@ metadata_vendor_id_t CameraProviderManager::getProviderTagIdLocked(
1445 return ret;
1446 }
1447
1448+bool CameraProviderManager::isLogicalCamera(const CameraMetadata& staticInfo,
1449+ std::vector<std::string>* physicalCameraIds) {
1450+ bool isLogicalCam = false;
1451+ camera_metadata_ro_entry_t entryCap;
1452+
1453+ entryCap = staticInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
1454+ for (size_t i = 0; i < entryCap.count; ++i) {
1455+ uint8_t capability = entryCap.data.u8[i];
1456+ if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
1457+ isLogicalCam = true;
1458+ break;
1459+ }
1460+ }
1461+ if (!isLogicalCam) {
1462+ return false;
1463+ }
1464+
1465+ camera_metadata_ro_entry_t entryIds = staticInfo.find(ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
1466+ const uint8_t* ids = entryIds.data.u8;
1467+ size_t start = 0;
1468+ for (size_t i = 0; i < entryIds.count; ++i) {
1469+ if (ids[i] == '\0') {
1470+ if (start != i) {
1471+ physicalCameraIds->push_back((const char*)ids+start);
1472+ }
1473+ start = i+1;
1474+ }
1475+ }
1476+ return true;
1477+}
1478+
1479 status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
1480 for (const auto& providerInfo : mProviders) {
1481 if (providerInfo->mProviderName == newProvider) {
1482@@ -484,6 +520,8 @@ status_t CameraProviderManager::ProviderInfo::initialize() {
1483 }
1484 ALOGI("Connecting to new camera provider: %s, isRemote? %d",
1485 mProviderName.c_str(), mInterface->isRemote());
1486+ // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
1487+ // before setCallback returns
1488 hardware::Return<Status> status = mInterface->setCallback(this);
1489 if (!status.isOk()) {
1490 ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
1491@@ -540,17 +578,10 @@ status_t CameraProviderManager::ProviderInfo::initialize() {
1492 }
1493 }
1494
1495- for (auto& device : mDevices) {
1496- mUniqueCameraIds.insert(device->mId);
1497- if (device->isAPI1Compatible()) {
1498- mUniqueAPI1CompatibleCameraIds.insert(device->mId);
1499- }
1500- }
1501- mUniqueDeviceCount = mUniqueCameraIds.size();
1502-
1503 ALOGI("Camera provider %s ready with %zu camera devices",
1504 mProviderName.c_str(), mDevices.size());
1505
1506+ mInitialized = true;
1507 return OK;
1508 }
1509
1510@@ -598,15 +629,36 @@ status_t CameraProviderManager::ProviderInfo::addDevice(const std::string& name,
1511 }
1512 if (deviceInfo == nullptr) return BAD_VALUE;
1513 deviceInfo->mStatus = initialStatus;
1514+ bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
1515
1516 mDevices.push_back(std::move(deviceInfo));
1517
1518+ mUniqueCameraIds.insert(id);
1519+ if (isAPI1Compatible) {
1520+ mUniqueAPI1CompatibleCameraIds.push_back(id);
1521+ }
1522+
1523 if (parsedId != nullptr) {
1524 *parsedId = id;
1525 }
1526 return OK;
1527 }
1528
1529+void CameraProviderManager::ProviderInfo::removeDevice(std::string id) {
1530+ for (auto it = mDevices.begin(); it != mDevices.end(); it++) {
1531+ if ((*it)->mId == id) {
1532+ mUniqueCameraIds.erase(id);
1533+ if ((*it)->isAPI1Compatible()) {
1534+ mUniqueAPI1CompatibleCameraIds.erase(std::remove(
1535+ mUniqueAPI1CompatibleCameraIds.begin(),
1536+ mUniqueAPI1CompatibleCameraIds.end(), id));
1537+ }
1538+ mDevices.erase(it);
1539+ break;
1540+ }
1541+ }
1542+}
1543+
1544 status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const {
1545 dprintf(fd, "== Camera Provider HAL %s (v2.4, %s) static info: %zu devices: ==\n",
1546 mProviderName.c_str(), mInterface->isRemote() ? "remote" : "passthrough",
1547@@ -666,6 +718,7 @@ hardware::Return<void> CameraProviderManager::ProviderInfo::cameraDeviceStatusCh
1548 CameraDeviceStatus newStatus) {
1549 sp<StatusListener> listener;
1550 std::string id;
1551+ bool initialized = false;
1552 {
1553 std::lock_guard<std::mutex> lock(mLock);
1554 bool known = false;
1555@@ -688,11 +741,17 @@ hardware::Return<void> CameraProviderManager::ProviderInfo::cameraDeviceStatusCh
1556 return hardware::Void();
1557 }
1558 addDevice(cameraDeviceName, newStatus, &id);
1559+ } else if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
1560+ removeDevice(id);
1561 }
1562 listener = mManager->getStatusListener();
1563+ initialized = mInitialized;
1564 }
1565 // Call without lock held to allow reentrancy into provider manager
1566- if (listener != nullptr) {
1567+ // Don't send the callback if providerInfo hasn't been initialized.
1568+ // CameraService will initialize device status after provider is
1569+ // initialized
1570+ if (listener != nullptr && initialized) {
1571 listener->onDeviceStatusChanged(String8(id.c_str()), newStatus);
1572 }
1573 return hardware::Void();
1574@@ -1396,5 +1455,51 @@ status_t HidlVendorTagDescriptor::createDescriptorFromHidl(
1575 return OK;
1576 }
1577
1578+status_t CameraProviderManager::getCameraCharacteristicsLocked(const std::string &id,
1579+ CameraMetadata* characteristics) const {
1580+ auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
1581+ if (deviceInfo == nullptr) return NAME_NOT_FOUND;
1582+
1583+ return deviceInfo->getCameraCharacteristics(characteristics);
1584+}
1585+
1586+void CameraProviderManager::filterLogicalCameraIdsLocked(
1587+ std::vector<std::string>& deviceIds) const
1588+{
1589+ std::unordered_set<std::string> removedIds;
1590+
1591+ for (auto& deviceId : deviceIds) {
1592+ CameraMetadata info;
1593+ status_t res = getCameraCharacteristicsLocked(deviceId, &info);
1594+ if (res != OK) {
1595+ ALOGE("%s: Failed to getCameraCharacteristics for id %s", __FUNCTION__,
1596+ deviceId.c_str());
1597+ return;
1598+ }
1599+
1600+ // idCombo contains the ids of a logical camera and its physical cameras
1601+ std::vector<std::string> idCombo;
1602+ bool logicalCamera = CameraProviderManager::isLogicalCamera(info, &idCombo);
1603+ if (!logicalCamera) {
1604+ continue;
1605+ }
1606+ idCombo.push_back(deviceId);
1607+
1608+ for (auto& id : deviceIds) {
1609+ auto foundId = std::find(idCombo.begin(), idCombo.end(), id);
1610+ if (foundId == idCombo.end()) {
1611+ continue;
1612+ }
1613+
1614+ idCombo.erase(foundId);
1615+ removedIds.insert(idCombo.begin(), idCombo.end());
1616+ break;
1617+ }
1618+ }
1619+
1620+ deviceIds.erase(std::remove_if(deviceIds.begin(), deviceIds.end(),
1621+ [&removedIds](const std::string& s) {return removedIds.find(s) != removedIds.end();}),
1622+ deviceIds.end());
1623+}
1624
1625 } // namespace android
1626diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
1627index 0f1f07b..b8b8b8c 100644
1628--- a/services/camera/libcameraservice/common/CameraProviderManager.h
1629+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
1630@@ -18,7 +18,7 @@
1631 #define ANDROID_SERVERS_CAMERA_CAMERAPROVIDER_H
1632
1633 #include <vector>
1634-#include <set>
1635+#include <unordered_set>
1636 #include <string>
1637 #include <mutex>
1638
1639@@ -125,16 +125,14 @@ public:
1640 */
1641 int getCameraCount() const;
1642
1643+ std::vector<std::string> getCameraDeviceIds() const;
1644+
1645 /**
1646 * Retrieve the number of API1 compatible cameras; these are internal and
1647 * backwards-compatible. This is the set of cameras that will be
1648- * accessible via the old camera API, with IDs in range of
1649- * [0, getAPI1CompatibleCameraCount()-1]. This value is not expected to change dynamically.
1650+ * accessible via the old camera API.
1651+ * The return value may change dynamically due to external camera hotplug.
1652 */
1653- int getAPI1CompatibleCameraCount() const;
1654-
1655- std::vector<std::string> getCameraDeviceIds() const;
1656-
1657 std::vector<std::string> getAPI1CompatibleCameraDeviceIds() const;
1658
1659 /**
1660@@ -232,6 +230,13 @@ public:
1661 hardware::hidl_version minVersion = hardware::hidl_version{0,0},
1662 hardware::hidl_version maxVersion = hardware::hidl_version{1000,0}) const;
1663
1664+ /*
1665+ * Check if a camera with staticInfo is a logical camera. And if yes, return
1666+ * the physical camera ids.
1667+ */
1668+ static bool isLogicalCamera(const CameraMetadata& staticInfo,
1669+ std::vector<std::string>* physicalCameraIds);
1670+
1671 private:
1672 // All private members, unless otherwise noted, expect mInterfaceMutex to be locked before use
1673 mutable std::mutex mInterfaceMutex;
1674@@ -314,9 +319,9 @@ private:
1675 static status_t setTorchMode(InterfaceT& interface, bool enabled);
1676 };
1677 std::vector<std::unique_ptr<DeviceInfo>> mDevices;
1678- std::set<std::string> mUniqueCameraIds;
1679+ std::unordered_set<std::string> mUniqueCameraIds;
1680 int mUniqueDeviceCount;
1681- std::set<std::string> mUniqueAPI1CompatibleCameraIds;
1682+ std::vector<std::string> mUniqueAPI1CompatibleCameraIds;
1683
1684 // HALv1-specific camera fields, including the actual device interface
1685 struct DeviceInfo1 : public DeviceInfo {
1686@@ -366,6 +371,8 @@ private:
1687
1688 CameraProviderManager *mManager;
1689
1690+ bool mInitialized = false;
1691+
1692 // Templated method to instantiate the right kind of DeviceInfo and call the
1693 // right CameraProvider getCameraDeviceInterface_* method.
1694 template<class DeviceInfoT>
1695@@ -387,6 +394,8 @@ private:
1696
1697 // Generate vendor tag id
1698 static metadata_vendor_id_t generateVendorTagId(const std::string &name);
1699+
1700+ void removeDevice(std::string id);
1701 };
1702
1703 // Utility to find a DeviceInfo by ID; pointer is only valid while mInterfaceMutex is held
1704@@ -412,6 +421,9 @@ private:
1705 static const char* torchStatusToString(
1706 const hardware::camera::common::V1_0::TorchModeStatus&);
1707
1708+ status_t getCameraCharacteristicsLocked(const std::string &id,
1709+ CameraMetadata* characteristics) const;
1710+ void filterLogicalCameraIdsLocked(std::vector<std::string>& deviceIds) const;
1711 };
1712
1713 } // namespace android
1714--
17152.7.4
1716