blob: 419250ce03b7106e532fa949ae8e0dfddf475131 [file] [log] [blame]
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "ACameraManager"
19
20#include <memory>
21#include "ACameraManager.h"
22#include "ACameraMetadata.h"
23#include "ACameraDevice.h"
24#include <utils/Vector.h>
Ivan Podogovee844a82016-09-15 11:32:41 +010025#include <cutils/properties.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080026#include <stdlib.h>
27#include <camera/VendorTagDescriptor.h>
28
Jayant Chowdhary6df26072018-11-06 23:55:12 -080029using namespace android::acam;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080030
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080031namespace android {
Jayant Chowdhary6df26072018-11-06 23:55:12 -080032namespace acam {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080033// Static member definitions
34const char* CameraManagerGlobal::kCameraIdKey = "CameraId";
Shuzhen Wang43858162020-01-10 13:42:15 -080035const char* CameraManagerGlobal::kPhysicalCameraIdKey = "PhysicalCameraId";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080036const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
37const char* CameraManagerGlobal::kContextKey = "CallbackContext";
Shuzhen Wang7e540682020-04-10 13:30:25 -070038const nsecs_t CameraManagerGlobal::kCallbackDrainTimeout = 5000000; // 5 ms
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080039Mutex CameraManagerGlobal::sLock;
40CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
41
42CameraManagerGlobal&
43CameraManagerGlobal::getInstance() {
44 Mutex::Autolock _l(sLock);
45 CameraManagerGlobal* instance = sInstance;
46 if (instance == nullptr) {
47 instance = new CameraManagerGlobal();
48 sInstance = instance;
49 }
50 return *instance;
51}
52
53CameraManagerGlobal::~CameraManagerGlobal() {
54 // clear sInstance so next getInstance call knows to create a new one
55 Mutex::Autolock _sl(sLock);
56 sInstance = nullptr;
57 Mutex::Autolock _l(mLock);
58 if (mCameraService != nullptr) {
59 IInterface::asBinder(mCameraService)->unlinkToDeath(mDeathNotifier);
Yin-Chia Yehead91462016-01-06 16:45:08 -080060 mCameraService->removeListener(mCameraServiceListener);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080061 }
62 mDeathNotifier.clear();
63 if (mCbLooper != nullptr) {
64 mCbLooper->unregisterHandler(mHandler->id());
65 mCbLooper->stop();
66 }
67 mCbLooper.clear();
68 mHandler.clear();
69 mCameraServiceListener.clear();
70 mCameraService.clear();
71}
72
Ivan Podogovee844a82016-09-15 11:32:41 +010073static bool isCameraServiceDisabled() {
74 char value[PROPERTY_VALUE_MAX];
75 property_get("config.disable_cameraservice", value, "0");
76 return (strncmp(value, "0", 2) != 0 && strncasecmp(value, "false", 6) != 0);
77}
78
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080079sp<hardware::ICameraService> CameraManagerGlobal::getCameraService() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080080 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -070081 return getCameraServiceLocked();
82}
83
84sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080085 if (mCameraService.get() == nullptr) {
Ivan Podogovee844a82016-09-15 11:32:41 +010086 if (isCameraServiceDisabled()) {
87 return mCameraService;
88 }
89
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080090 sp<IServiceManager> sm = defaultServiceManager();
91 sp<IBinder> binder;
92 do {
93 binder = sm->getService(String16(kCameraServiceName));
94 if (binder != nullptr) {
95 break;
96 }
97 ALOGW("CameraService not published, waiting...");
98 usleep(kCameraServicePollDelay);
99 } while(true);
100 if (mDeathNotifier == nullptr) {
101 mDeathNotifier = new DeathNotifier(this);
102 }
103 binder->linkToDeath(mDeathNotifier);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800104 mCameraService = interface_cast<hardware::ICameraService>(binder);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800105
106 // Setup looper thread to perfrom availiability callbacks
107 if (mCbLooper == nullptr) {
108 mCbLooper = new ALooper;
109 mCbLooper->setName("C2N-mgr-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800110 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800111 /*runOnCallingThread*/false,
112 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800113 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800114 if (err != OK) {
115 ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
116 __FUNCTION__, strerror(-err), err);
117 mCbLooper.clear();
118 return nullptr;
119 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800120 if (mHandler == nullptr) {
Shuzhen Wang7e540682020-04-10 13:30:25 -0700121 mHandler = new CallbackHandler(this);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800122 }
123 mCbLooper->registerHandler(mHandler);
124 }
125
126 // register ICameraServiceListener
127 if (mCameraServiceListener == nullptr) {
128 mCameraServiceListener = new CameraServiceListener(this);
129 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800130 std::vector<hardware::CameraStatus> cameraStatuses{};
131 mCameraService->addListener(mCameraServiceListener, &cameraStatuses);
132 for (auto& c : cameraStatuses) {
133 onStatusChangedLocked(c.status, c.cameraId);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800134
135 for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) {
136 onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT,
137 c.cameraId, unavailablePhysicalId);
138 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800139 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800140
141 // setup vendor tags
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800142 sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
143 binder::Status ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800144
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800145 if (ret.isOk()) {
Emilian Peev71c73a22017-03-21 16:35:51 +0000146 if (0 < desc->getTagCount()) {
147 status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
148 if (err != OK) {
149 ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
150 __FUNCTION__, strerror(-err), err);
151 }
152 } else {
153 sp<VendorTagDescriptorCache> cache =
154 new VendorTagDescriptorCache();
155 binder::Status res =
156 mCameraService->getCameraVendorTagCache(
157 /*out*/cache.get());
158 if (res.serviceSpecificErrorCode() ==
159 hardware::ICameraService::ERROR_DISCONNECTED) {
160 // No camera module available, not an error on devices with no cameras
161 VendorTagDescriptorCache::clearGlobalVendorTagCache();
162 } else if (res.isOk()) {
163 status_t err =
164 VendorTagDescriptorCache::setAsGlobalVendorTagCache(
165 cache);
166 if (err != OK) {
167 ALOGE("%s: Failed to set vendor tag cache,"
168 "received error %s (%d)", __FUNCTION__,
169 strerror(-err), err);
170 }
171 } else {
172 VendorTagDescriptorCache::clearGlobalVendorTagCache();
173 ALOGE("%s: Failed to setup vendor tag cache: %s",
174 __FUNCTION__, res.toString8().string());
175 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800176 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800177 } else if (ret.serviceSpecificErrorCode() ==
178 hardware::ICameraService::ERROR_DEPRECATED_HAL) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800179 ALOGW("%s: Camera HAL too old; does not support vendor tags",
180 __FUNCTION__);
181 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
182 } else {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800183 ALOGE("%s: Failed to get vendor tag descriptors: %s",
184 __FUNCTION__, ret.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800185 }
186 }
187 ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
188 return mCameraService;
189}
190
191void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
192{
193 ALOGE("Camera service binderDied!");
194 sp<CameraManagerGlobal> cm = mCameraManager.promote();
195 if (cm != nullptr) {
196 AutoMutex lock(cm->mLock);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800197 for (auto& pair : cm->mDeviceStatusMap) {
198 const String8 &cameraId = pair.first;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800199 cm->onStatusChangedLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800200 CameraServiceListener::STATUS_NOT_PRESENT, cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800201 }
202 cm->mCameraService.clear();
203 // TODO: consider adding re-connect call here?
204 }
205}
206
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800207void CameraManagerGlobal::registerExtendedAvailabilityCallback(
208 const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800209 return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(callback);
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800210}
211
212void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
213 const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
214 Mutex::Autolock _l(mLock);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700215
216 drainPendingCallbacksLocked();
217
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800218 Callback cb(callback);
219 mCallbacks.erase(cb);
220}
221
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800222void CameraManagerGlobal::registerAvailabilityCallback(
223 const ACameraManager_AvailabilityCallbacks *callback) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800224 return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(callback);
225}
226
227void CameraManagerGlobal::unregisterAvailabilityCallback(
228 const ACameraManager_AvailabilityCallbacks *callback) {
229 Mutex::Autolock _l(mLock);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700230
231 drainPendingCallbacksLocked();
232
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800233 Callback cb(callback);
234 mCallbacks.erase(cb);
235}
236
Shuzhen Wang7e540682020-04-10 13:30:25 -0700237void CameraManagerGlobal::onCallbackCalled() {
238 Mutex::Autolock _l(mLock);
239 if (mPendingCallbackCnt > 0) {
240 mPendingCallbackCnt--;
241 }
242 mCallbacksCond.signal();
243}
244
245void CameraManagerGlobal::drainPendingCallbacksLocked() {
246 while (mPendingCallbackCnt > 0) {
247 auto res = mCallbacksCond.waitRelative(mLock, kCallbackDrainTimeout);
248 if (res != NO_ERROR) {
249 ALOGE("%s: Error waiting to drain callbacks: %s(%d)",
250 __FUNCTION__, strerror(-res), res);
251 break;
252 }
253 }
254}
255
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800256template<class T>
257void CameraManagerGlobal::registerAvailCallback(const T *callback) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800258 Mutex::Autolock _l(mLock);
259 Callback cb(callback);
260 auto pair = mCallbacks.insert(cb);
261 // Send initial callbacks if callback is newly registered
262 if (pair.second) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800263 for (auto& pair : mDeviceStatusMap) {
264 const String8& cameraId = pair.first;
Shuzhen Wang43858162020-01-10 13:42:15 -0800265 int32_t status = pair.second.getStatus();
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700266 // Don't send initial callbacks for camera ids which don't support
267 // camera2
268 if (!pair.second.supportsHAL3) {
269 continue;
270 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800271
272 // Camera available/unavailable callback
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800273 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800274 ACameraManager_AvailabilityCallback cbFunc = isStatusAvailable(status) ?
275 cb.mAvailable : cb.mUnavailable;
276 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
277 msg->setPointer(kContextKey, cb.mContext);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800278 msg->setString(kCameraIdKey, AString(cameraId));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700279 mPendingCallbackCnt++;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800280 msg->post();
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800281
282 // Physical camera unavailable callback
283 std::set<String8> unavailablePhysicalCameras =
284 pair.second.getUnavailablePhysicalIds();
285 for (const auto& physicalCameraId : unavailablePhysicalCameras) {
286 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
287 ACameraManager_PhysicalCameraAvailabilityCallback cbFunc =
288 cb.mPhysicalCamUnavailable;
289 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
290 msg->setPointer(kContextKey, cb.mContext);
291 msg->setString(kCameraIdKey, AString(cameraId));
292 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700293 mPendingCallbackCnt++;
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800294 msg->post();
295 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800296 }
297 }
298}
299
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700300bool CameraManagerGlobal::supportsCamera2ApiLocked(const String8 &cameraId) {
301 bool camera2Support = false;
302 auto cs = getCameraServiceLocked();
303 binder::Status serviceRet =
304 cs->supportsCameraApi(String16(cameraId),
305 hardware::ICameraService::API_VERSION_2, &camera2Support);
306 if (!serviceRet.isOk()) {
307 ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId %s",
308 __FUNCTION__, cameraId.c_str());
309 return false;
310 }
311 return camera2Support;
312}
313
Yin-Chia Yeh03f55752018-03-14 15:28:02 -0700314void CameraManagerGlobal::getCameraIdList(std::vector<String8>* cameraIds) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800315 // Ensure that we have initialized/refreshed the list of available devices
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800316 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700317 // Needed to make sure we're connected to cameraservice
318 getCameraServiceLocked();
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800319 for(auto& deviceStatus : mDeviceStatusMap) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800320 int32_t status = deviceStatus.second.getStatus();
321 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
322 status == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800323 continue;
324 }
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700325 if (!deviceStatus.second.supportsHAL3) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800326 continue;
327 }
328 cameraIds->push_back(deviceStatus.first);
329 }
330}
331
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800332bool CameraManagerGlobal::validStatus(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800333 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800334 case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
335 case hardware::ICameraServiceListener::STATUS_PRESENT:
336 case hardware::ICameraServiceListener::STATUS_ENUMERATING:
337 case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800338 return true;
339 default:
340 return false;
341 }
342}
343
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800344bool CameraManagerGlobal::isStatusAvailable(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800345 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800346 case hardware::ICameraServiceListener::STATUS_PRESENT:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800347 return true;
348 default:
349 return false;
350 }
351}
352
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800353void CameraManagerGlobal::CallbackHandler::onMessageReceived(
Shuzhen Wang7e540682020-04-10 13:30:25 -0700354 const sp<AMessage> &msg) {
355 onMessageReceivedInternal(msg);
356 if (msg->what() == kWhatSendSingleCallback ||
357 msg->what() == kWhatSendSingleAccessCallback ||
358 msg->what() == kWhatSendSinglePhysicalCameraCallback) {
359 notifyParent();
360 }
361}
362
363void CameraManagerGlobal::CallbackHandler::onMessageReceivedInternal(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800364 const sp<AMessage> &msg) {
365 switch (msg->what()) {
366 case kWhatSendSingleCallback:
367 {
368 ACameraManager_AvailabilityCallback cb;
369 void* context;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800370 AString cameraId;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800371 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
372 if (!found) {
373 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
374 return;
375 }
376 found = msg->findPointer(kContextKey, &context);
377 if (!found) {
378 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
379 return;
380 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800381 found = msg->findString(kCameraIdKey, &cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800382 if (!found) {
383 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
384 return;
385 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800386 (*cb)(context, cameraId.c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800387 break;
388 }
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800389 case kWhatSendSingleAccessCallback:
390 {
391 ACameraManager_AccessPrioritiesChangedCallback cb;
392 void* context;
393 AString cameraId;
394 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
395 if (!found) {
396 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
397 return;
398 }
399 found = msg->findPointer(kContextKey, &context);
400 if (!found) {
401 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
402 return;
403 }
404 (*cb)(context);
405 break;
406 }
Shuzhen Wang43858162020-01-10 13:42:15 -0800407 case kWhatSendSinglePhysicalCameraCallback:
408 {
409 ACameraManager_PhysicalCameraAvailabilityCallback cb;
410 void* context;
411 AString cameraId;
412 AString physicalCameraId;
413 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
414 if (!found) {
415 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
416 return;
417 }
418 if (cb == nullptr) {
419 // Physical camera callback is null
420 return;
421 }
422 found = msg->findPointer(kContextKey, &context);
423 if (!found) {
424 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
425 return;
426 }
427 found = msg->findString(kCameraIdKey, &cameraId);
428 if (!found) {
429 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
430 return;
431 }
432 found = msg->findString(kPhysicalCameraIdKey, &physicalCameraId);
433 if (!found) {
434 ALOGE("%s: Cannot find physical camera ID!", __FUNCTION__);
435 return;
436 }
437 (*cb)(context, cameraId.c_str(), physicalCameraId.c_str());
438 break;
439 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800440 default:
441 ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
442 break;
443 }
444}
445
Shuzhen Wang7e540682020-04-10 13:30:25 -0700446void CameraManagerGlobal::CallbackHandler::notifyParent() {
447 sp<CameraManagerGlobal> parent = mParent.promote();
448 if (parent != nullptr) {
449 parent->onCallbackCalled();
450 }
451}
452
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800453binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPrioritiesChanged() {
454 sp<CameraManagerGlobal> cm = mCameraManager.promote();
455 if (cm != nullptr) {
456 cm->onCameraAccessPrioritiesChanged();
457 } else {
458 ALOGE("Cannot deliver camera access priority callback. Global camera manager died");
459 }
460 return binder::Status::ok();
461}
462
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800463binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800464 int32_t status, const String16& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800465 sp<CameraManagerGlobal> cm = mCameraManager.promote();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800466 if (cm != nullptr) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800467 cm->onStatusChanged(status, String8(cameraId));
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800468 } else {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800469 ALOGE("Cannot deliver status change. Global camera manager died");
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800470 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800471 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800472}
473
Shuzhen Wang43858162020-01-10 13:42:15 -0800474binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged(
475 int32_t status, const String16& cameraId, const String16& physicalCameraId) {
476 sp<CameraManagerGlobal> cm = mCameraManager.promote();
477 if (cm != nullptr) {
478 cm->onStatusChanged(status, String8(cameraId), String8(physicalCameraId));
479 } else {
480 ALOGE("Cannot deliver physical camera status change. Global camera manager died");
481 }
482 return binder::Status::ok();
483}
484
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800485void CameraManagerGlobal::onCameraAccessPrioritiesChanged() {
486 Mutex::Autolock _l(mLock);
487 for (auto cb : mCallbacks) {
488 sp<AMessage> msg = new AMessage(kWhatSendSingleAccessCallback, mHandler);
489 ACameraManager_AccessPrioritiesChangedCallback cbFp = cb.mAccessPriorityChanged;
490 if (cbFp != nullptr) {
491 msg->setPointer(kCallbackFpKey, (void *) cbFp);
492 msg->setPointer(kContextKey, cb.mContext);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700493 mPendingCallbackCnt++;
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800494 msg->post();
495 }
496 }
497}
498
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800499void CameraManagerGlobal::onStatusChanged(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800500 int32_t status, const String8& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800501 Mutex::Autolock _l(mLock);
502 onStatusChangedLocked(status, cameraId);
503}
504
505void CameraManagerGlobal::onStatusChangedLocked(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800506 int32_t status, const String8& cameraId) {
507 if (!validStatus(status)) {
508 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
509 return;
510 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800511
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800512 bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
513 int32_t oldStatus = firstStatus ?
514 status : // first status
Shuzhen Wang43858162020-01-10 13:42:15 -0800515 mDeviceStatusMap[cameraId].getStatus();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800516
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800517 if (!firstStatus &&
518 isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
519 // No status update. No need to send callback
520 return;
521 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800522
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700523 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800524 if (firstStatus) {
525 mDeviceStatusMap.emplace(std::piecewise_construct,
526 std::forward_as_tuple(cameraId),
527 std::forward_as_tuple(status, supportsHAL3));
528 } else {
529 mDeviceStatusMap[cameraId].updateStatus(status);
530 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800531 // Iterate through all registered callbacks
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700532 if (supportsHAL3) {
533 for (auto cb : mCallbacks) {
534 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
535 ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
536 cb.mAvailable : cb.mUnavailable;
537 msg->setPointer(kCallbackFpKey, (void *) cbFp);
538 msg->setPointer(kContextKey, cb.mContext);
539 msg->setString(kCameraIdKey, AString(cameraId));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700540 mPendingCallbackCnt++;
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700541 msg->post();
542 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800543 }
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100544 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
545 mDeviceStatusMap.erase(cameraId);
546 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800547}
548
Shuzhen Wang43858162020-01-10 13:42:15 -0800549void CameraManagerGlobal::onStatusChanged(
550 int32_t status, const String8& cameraId, const String8& physicalCameraId) {
551 Mutex::Autolock _l(mLock);
552 onStatusChangedLocked(status, cameraId, physicalCameraId);
553}
554
555void CameraManagerGlobal::onStatusChangedLocked(
556 int32_t status, const String8& cameraId, const String8& physicalCameraId) {
557 if (!validStatus(status)) {
558 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
559 return;
560 }
561
562 auto logicalStatus = mDeviceStatusMap.find(cameraId);
563 if (logicalStatus == mDeviceStatusMap.end()) {
564 ALOGE("%s: Physical camera id %s status change on a non-present id %s",
565 __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str());
566 return;
567 }
568 int32_t logicalCamStatus = mDeviceStatusMap[cameraId].getStatus();
569 if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT &&
570 logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) {
571 ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
572 __FUNCTION__, physicalCameraId.string(), status, logicalCamStatus);
573 return;
574 }
575
576 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
577
578 bool updated = false;
579 if (status == hardware::ICameraServiceListener::STATUS_PRESENT) {
580 updated = mDeviceStatusMap[cameraId].removeUnavailablePhysicalId(physicalCameraId);
581 } else {
582 updated = mDeviceStatusMap[cameraId].addUnavailablePhysicalId(physicalCameraId);
583 }
584
585 // Iterate through all registered callbacks
586 if (supportsHAL3 && updated) {
587 for (auto cb : mCallbacks) {
588 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
589 ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ?
590 cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable;
591 msg->setPointer(kCallbackFpKey, (void *) cbFp);
592 msg->setPointer(kContextKey, cb.mContext);
593 msg->setString(kCameraIdKey, AString(cameraId));
594 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700595 mPendingCallbackCnt++;
Shuzhen Wang43858162020-01-10 13:42:15 -0800596 msg->post();
597 }
598 }
599}
600
601int32_t CameraManagerGlobal::StatusAndHAL3Support::getStatus() {
602 std::lock_guard<std::mutex> lock(mLock);
603 return status;
604}
605
606void CameraManagerGlobal::StatusAndHAL3Support::updateStatus(int32_t newStatus) {
607 std::lock_guard<std::mutex> lock(mLock);
608 status = newStatus;
609}
610
611bool CameraManagerGlobal::StatusAndHAL3Support::addUnavailablePhysicalId(
612 const String8& physicalCameraId) {
613 std::lock_guard<std::mutex> lock(mLock);
614 auto result = unavailablePhysicalIds.insert(physicalCameraId);
615 return result.second;
616}
617
618bool CameraManagerGlobal::StatusAndHAL3Support::removeUnavailablePhysicalId(
619 const String8& physicalCameraId) {
620 std::lock_guard<std::mutex> lock(mLock);
621 auto count = unavailablePhysicalIds.erase(physicalCameraId);
622 return count > 0;
623}
624
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800625std::set<String8> CameraManagerGlobal::StatusAndHAL3Support::getUnavailablePhysicalIds() {
626 std::lock_guard<std::mutex> lock(mLock);
627 return unavailablePhysicalIds;
628}
629
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800630} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800631} // namespace android
632
633/**
634 * ACameraManger Implementation
635 */
636camera_status_t
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800637ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
638 Mutex::Autolock _l(mLock);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800639
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800640 std::vector<String8> idList;
641 CameraManagerGlobal::getInstance().getCameraIdList(&idList);
642
643 int numCameras = idList.size();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800644 ACameraIdList *out = new ACameraIdList;
645 if (!out) {
646 ALOGE("Allocate memory for ACameraIdList failed!");
647 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
648 }
649 out->numCameras = numCameras;
Bjoern Johansson1a5954c2017-01-10 10:30:18 -0800650 out->cameraIds = new const char*[numCameras];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800651 if (!out->cameraIds) {
652 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800653 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800654 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
655 }
656 for (int i = 0; i < numCameras; i++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800657 const char* src = idList[i].string();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800658 size_t dstSize = strlen(src) + 1;
659 char* dst = new char[dstSize];
660 if (!dst) {
661 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800662 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800663 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
664 }
665 strlcpy(dst, src, dstSize);
666 out->cameraIds[i] = dst;
667 }
668 *cameraIdList = out;
669 return ACAMERA_OK;
670}
671
672void
673ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
674 if (cameraIdList != nullptr) {
675 if (cameraIdList->cameraIds != nullptr) {
676 for (int i = 0; i < cameraIdList->numCameras; i ++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800677 if (cameraIdList->cameraIds[i] != nullptr) {
678 delete[] cameraIdList->cameraIds[i];
679 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800680 }
681 delete[] cameraIdList->cameraIds;
682 }
683 delete cameraIdList;
684 }
685}
686
687camera_status_t ACameraManager::getCameraCharacteristics(
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700688 const char* cameraIdStr, sp<ACameraMetadata>* characteristics) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800689 Mutex::Autolock _l(mLock);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800690
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800691 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800692 if (cs == nullptr) {
693 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
694 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
695 }
696 CameraMetadata rawMetadata;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800697 binder::Status serviceRet = cs->getCameraCharacteristics(String16(cameraIdStr), &rawMetadata);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800698 if (!serviceRet.isOk()) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800699 switch(serviceRet.serviceSpecificErrorCode()) {
700 case hardware::ICameraService::ERROR_DISCONNECTED:
701 ALOGE("%s: Camera %s has been disconnected", __FUNCTION__, cameraIdStr);
702 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
703 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
704 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
705 return ACAMERA_ERROR_INVALID_PARAMETER;
706 default:
707 ALOGE("Get camera characteristics from camera service failed: %s",
708 serviceRet.toString8().string());
709 return ACAMERA_ERROR_UNKNOWN; // should not reach here
710 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800711 }
712
713 *characteristics = new ACameraMetadata(
714 rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
715 return ACAMERA_OK;
716}
717
718camera_status_t
719ACameraManager::openCamera(
720 const char* cameraId,
721 ACameraDevice_StateCallbacks* callback,
722 /*out*/ACameraDevice** outDevice) {
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700723 sp<ACameraMetadata> chars;
724 camera_status_t ret = getCameraCharacteristics(cameraId, &chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800725 Mutex::Autolock _l(mLock);
726 if (ret != ACAMERA_OK) {
727 ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
728 __FUNCTION__, cameraId, ret);
729 return ACAMERA_ERROR_INVALID_PARAMETER;
730 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800731
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700732 ACameraDevice* device = new ACameraDevice(cameraId, callback, chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800733
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800734 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800735 if (cs == nullptr) {
736 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
Yunlian Jiangb01d8f72016-10-04 16:34:18 -0700737 delete device;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800738 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
739 }
740
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800741 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
742 sp<hardware::camera2::ICameraDeviceUser> deviceRemote;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800743 // No way to get package name from native.
744 // Send a zero length package name and let camera service figure it out from UID
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800745 binder::Status serviceRet = cs->connectDevice(
Jooyung Hanb3f7cd22020-01-23 12:27:18 +0900746 callbacks, String16(cameraId), String16(""), {},
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800747 hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800748
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800749 if (!serviceRet.isOk()) {
750 ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().string());
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700751 // Convert serviceRet to camera_status_t
752 switch(serviceRet.serviceSpecificErrorCode()) {
753 case hardware::ICameraService::ERROR_DISCONNECTED:
754 ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
755 break;
756 case hardware::ICameraService::ERROR_CAMERA_IN_USE:
757 ret = ACAMERA_ERROR_CAMERA_IN_USE;
758 break;
759 case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
760 ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
761 break;
762 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
763 ret = ACAMERA_ERROR_INVALID_PARAMETER;
764 break;
765 case hardware::ICameraService::ERROR_DEPRECATED_HAL:
766 // Should not reach here since we filtered legacy HALs earlier
767 ret = ACAMERA_ERROR_INVALID_PARAMETER;
768 break;
769 case hardware::ICameraService::ERROR_DISABLED:
770 ret = ACAMERA_ERROR_CAMERA_DISABLED;
771 break;
772 case hardware::ICameraService::ERROR_PERMISSION_DENIED:
773 ret = ACAMERA_ERROR_PERMISSION_DENIED;
774 break;
775 case hardware::ICameraService::ERROR_INVALID_OPERATION:
776 default:
777 ret = ACAMERA_ERROR_UNKNOWN;
778 break;
779 }
780
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800781 delete device;
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700782 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800783 }
784 if (deviceRemote == nullptr) {
785 ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
786 delete device;
787 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
788 }
789 device->setRemoteDevice(deviceRemote);
790 *outDevice = device;
791 return ACAMERA_OK;
792}
793
794ACameraManager::~ACameraManager() {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800795
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800796}