blob: 4870265770e085744fc9e1b1f22c05e1a6383795 [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";
38Mutex CameraManagerGlobal::sLock;
39CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
40
41CameraManagerGlobal&
42CameraManagerGlobal::getInstance() {
43 Mutex::Autolock _l(sLock);
44 CameraManagerGlobal* instance = sInstance;
45 if (instance == nullptr) {
46 instance = new CameraManagerGlobal();
47 sInstance = instance;
48 }
49 return *instance;
50}
51
52CameraManagerGlobal::~CameraManagerGlobal() {
53 // clear sInstance so next getInstance call knows to create a new one
54 Mutex::Autolock _sl(sLock);
55 sInstance = nullptr;
56 Mutex::Autolock _l(mLock);
57 if (mCameraService != nullptr) {
58 IInterface::asBinder(mCameraService)->unlinkToDeath(mDeathNotifier);
Yin-Chia Yehead91462016-01-06 16:45:08 -080059 mCameraService->removeListener(mCameraServiceListener);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080060 }
61 mDeathNotifier.clear();
62 if (mCbLooper != nullptr) {
63 mCbLooper->unregisterHandler(mHandler->id());
64 mCbLooper->stop();
65 }
66 mCbLooper.clear();
67 mHandler.clear();
68 mCameraServiceListener.clear();
69 mCameraService.clear();
70}
71
Ivan Podogovee844a82016-09-15 11:32:41 +010072static bool isCameraServiceDisabled() {
73 char value[PROPERTY_VALUE_MAX];
74 property_get("config.disable_cameraservice", value, "0");
75 return (strncmp(value, "0", 2) != 0 && strncasecmp(value, "false", 6) != 0);
76}
77
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080078sp<hardware::ICameraService> CameraManagerGlobal::getCameraService() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080079 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -070080 return getCameraServiceLocked();
81}
82
83sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080084 if (mCameraService.get() == nullptr) {
Ivan Podogovee844a82016-09-15 11:32:41 +010085 if (isCameraServiceDisabled()) {
86 return mCameraService;
87 }
88
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080089 sp<IServiceManager> sm = defaultServiceManager();
90 sp<IBinder> binder;
91 do {
92 binder = sm->getService(String16(kCameraServiceName));
93 if (binder != nullptr) {
94 break;
95 }
96 ALOGW("CameraService not published, waiting...");
97 usleep(kCameraServicePollDelay);
98 } while(true);
99 if (mDeathNotifier == nullptr) {
100 mDeathNotifier = new DeathNotifier(this);
101 }
102 binder->linkToDeath(mDeathNotifier);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800103 mCameraService = interface_cast<hardware::ICameraService>(binder);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800104
105 // Setup looper thread to perfrom availiability callbacks
106 if (mCbLooper == nullptr) {
107 mCbLooper = new ALooper;
108 mCbLooper->setName("C2N-mgr-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800109 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800110 /*runOnCallingThread*/false,
111 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800112 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800113 if (err != OK) {
114 ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
115 __FUNCTION__, strerror(-err), err);
116 mCbLooper.clear();
117 return nullptr;
118 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800119 if (mHandler == nullptr) {
120 mHandler = new CallbackHandler();
121 }
122 mCbLooper->registerHandler(mHandler);
123 }
124
125 // register ICameraServiceListener
126 if (mCameraServiceListener == nullptr) {
127 mCameraServiceListener = new CameraServiceListener(this);
128 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800129 std::vector<hardware::CameraStatus> cameraStatuses{};
130 mCameraService->addListener(mCameraServiceListener, &cameraStatuses);
131 for (auto& c : cameraStatuses) {
132 onStatusChangedLocked(c.status, c.cameraId);
133 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800134
135 // setup vendor tags
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800136 sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
137 binder::Status ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800138
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800139 if (ret.isOk()) {
Emilian Peev71c73a22017-03-21 16:35:51 +0000140 if (0 < desc->getTagCount()) {
141 status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
142 if (err != OK) {
143 ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
144 __FUNCTION__, strerror(-err), err);
145 }
146 } else {
147 sp<VendorTagDescriptorCache> cache =
148 new VendorTagDescriptorCache();
149 binder::Status res =
150 mCameraService->getCameraVendorTagCache(
151 /*out*/cache.get());
152 if (res.serviceSpecificErrorCode() ==
153 hardware::ICameraService::ERROR_DISCONNECTED) {
154 // No camera module available, not an error on devices with no cameras
155 VendorTagDescriptorCache::clearGlobalVendorTagCache();
156 } else if (res.isOk()) {
157 status_t err =
158 VendorTagDescriptorCache::setAsGlobalVendorTagCache(
159 cache);
160 if (err != OK) {
161 ALOGE("%s: Failed to set vendor tag cache,"
162 "received error %s (%d)", __FUNCTION__,
163 strerror(-err), err);
164 }
165 } else {
166 VendorTagDescriptorCache::clearGlobalVendorTagCache();
167 ALOGE("%s: Failed to setup vendor tag cache: %s",
168 __FUNCTION__, res.toString8().string());
169 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800170 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800171 } else if (ret.serviceSpecificErrorCode() ==
172 hardware::ICameraService::ERROR_DEPRECATED_HAL) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800173 ALOGW("%s: Camera HAL too old; does not support vendor tags",
174 __FUNCTION__);
175 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
176 } else {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800177 ALOGE("%s: Failed to get vendor tag descriptors: %s",
178 __FUNCTION__, ret.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800179 }
180 }
181 ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
182 return mCameraService;
183}
184
185void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
186{
187 ALOGE("Camera service binderDied!");
188 sp<CameraManagerGlobal> cm = mCameraManager.promote();
189 if (cm != nullptr) {
190 AutoMutex lock(cm->mLock);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800191 for (auto& pair : cm->mDeviceStatusMap) {
192 const String8 &cameraId = pair.first;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800193 cm->onStatusChangedLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800194 CameraServiceListener::STATUS_NOT_PRESENT, cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800195 }
196 cm->mCameraService.clear();
197 // TODO: consider adding re-connect call here?
198 }
199}
200
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800201void CameraManagerGlobal::registerExtendedAvailabilityCallback(
202 const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
203 Mutex::Autolock _l(mLock);
204 Callback cb(callback);
205 mCallbacks.insert(cb);
206}
207
208void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
209 const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
210 Mutex::Autolock _l(mLock);
211 Callback cb(callback);
212 mCallbacks.erase(cb);
213}
214
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800215void CameraManagerGlobal::registerAvailabilityCallback(
216 const ACameraManager_AvailabilityCallbacks *callback) {
217 Mutex::Autolock _l(mLock);
218 Callback cb(callback);
219 auto pair = mCallbacks.insert(cb);
220 // Send initial callbacks if callback is newly registered
221 if (pair.second) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800222 for (auto& pair : mDeviceStatusMap) {
223 const String8& cameraId = pair.first;
Shuzhen Wang43858162020-01-10 13:42:15 -0800224 int32_t status = pair.second.getStatus();
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700225 // Don't send initial callbacks for camera ids which don't support
226 // camera2
227 if (!pair.second.supportsHAL3) {
228 continue;
229 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800230 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
231 ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ?
232 callback->onCameraAvailable : callback->onCameraUnavailable;
233 msg->setPointer(kCallbackFpKey, (void *) cb);
234 msg->setPointer(kContextKey, callback->context);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800235 msg->setString(kCameraIdKey, AString(cameraId));
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800236 msg->post();
237 }
238 }
239}
240
241void CameraManagerGlobal::unregisterAvailabilityCallback(
242 const ACameraManager_AvailabilityCallbacks *callback) {
243 Mutex::Autolock _l(mLock);
244 Callback cb(callback);
245 mCallbacks.erase(cb);
246}
247
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700248bool CameraManagerGlobal::supportsCamera2ApiLocked(const String8 &cameraId) {
249 bool camera2Support = false;
250 auto cs = getCameraServiceLocked();
251 binder::Status serviceRet =
252 cs->supportsCameraApi(String16(cameraId),
253 hardware::ICameraService::API_VERSION_2, &camera2Support);
254 if (!serviceRet.isOk()) {
255 ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId %s",
256 __FUNCTION__, cameraId.c_str());
257 return false;
258 }
259 return camera2Support;
260}
261
Yin-Chia Yeh03f55752018-03-14 15:28:02 -0700262void CameraManagerGlobal::getCameraIdList(std::vector<String8>* cameraIds) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800263 // Ensure that we have initialized/refreshed the list of available devices
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800264 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700265 // Needed to make sure we're connected to cameraservice
266 getCameraServiceLocked();
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800267 for(auto& deviceStatus : mDeviceStatusMap) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800268 int32_t status = deviceStatus.second.getStatus();
269 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
270 status == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800271 continue;
272 }
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700273 if (!deviceStatus.second.supportsHAL3) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800274 continue;
275 }
276 cameraIds->push_back(deviceStatus.first);
277 }
278}
279
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800280bool CameraManagerGlobal::validStatus(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800281 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800282 case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
283 case hardware::ICameraServiceListener::STATUS_PRESENT:
284 case hardware::ICameraServiceListener::STATUS_ENUMERATING:
285 case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800286 return true;
287 default:
288 return false;
289 }
290}
291
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800292bool CameraManagerGlobal::isStatusAvailable(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800293 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800294 case hardware::ICameraServiceListener::STATUS_PRESENT:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800295 return true;
296 default:
297 return false;
298 }
299}
300
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800301void CameraManagerGlobal::CallbackHandler::onMessageReceived(
302 const sp<AMessage> &msg) {
303 switch (msg->what()) {
304 case kWhatSendSingleCallback:
305 {
306 ACameraManager_AvailabilityCallback cb;
307 void* context;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800308 AString cameraId;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800309 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
310 if (!found) {
311 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
312 return;
313 }
314 found = msg->findPointer(kContextKey, &context);
315 if (!found) {
316 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
317 return;
318 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800319 found = msg->findString(kCameraIdKey, &cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800320 if (!found) {
321 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
322 return;
323 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800324 (*cb)(context, cameraId.c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800325 break;
326 }
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800327 case kWhatSendSingleAccessCallback:
328 {
329 ACameraManager_AccessPrioritiesChangedCallback cb;
330 void* context;
331 AString cameraId;
332 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
333 if (!found) {
334 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
335 return;
336 }
337 found = msg->findPointer(kContextKey, &context);
338 if (!found) {
339 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
340 return;
341 }
342 (*cb)(context);
343 break;
344 }
Shuzhen Wang43858162020-01-10 13:42:15 -0800345 case kWhatSendSinglePhysicalCameraCallback:
346 {
347 ACameraManager_PhysicalCameraAvailabilityCallback cb;
348 void* context;
349 AString cameraId;
350 AString physicalCameraId;
351 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
352 if (!found) {
353 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
354 return;
355 }
356 if (cb == nullptr) {
357 // Physical camera callback is null
358 return;
359 }
360 found = msg->findPointer(kContextKey, &context);
361 if (!found) {
362 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
363 return;
364 }
365 found = msg->findString(kCameraIdKey, &cameraId);
366 if (!found) {
367 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
368 return;
369 }
370 found = msg->findString(kPhysicalCameraIdKey, &physicalCameraId);
371 if (!found) {
372 ALOGE("%s: Cannot find physical camera ID!", __FUNCTION__);
373 return;
374 }
375 (*cb)(context, cameraId.c_str(), physicalCameraId.c_str());
376 break;
377 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800378 default:
379 ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
380 break;
381 }
382}
383
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800384binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPrioritiesChanged() {
385 sp<CameraManagerGlobal> cm = mCameraManager.promote();
386 if (cm != nullptr) {
387 cm->onCameraAccessPrioritiesChanged();
388 } else {
389 ALOGE("Cannot deliver camera access priority callback. Global camera manager died");
390 }
391 return binder::Status::ok();
392}
393
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800394binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800395 int32_t status, const String16& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800396 sp<CameraManagerGlobal> cm = mCameraManager.promote();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800397 if (cm != nullptr) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800398 cm->onStatusChanged(status, String8(cameraId));
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800399 } else {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800400 ALOGE("Cannot deliver status change. Global camera manager died");
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800401 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800402 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800403}
404
Shuzhen Wang43858162020-01-10 13:42:15 -0800405binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged(
406 int32_t status, const String16& cameraId, const String16& physicalCameraId) {
407 sp<CameraManagerGlobal> cm = mCameraManager.promote();
408 if (cm != nullptr) {
409 cm->onStatusChanged(status, String8(cameraId), String8(physicalCameraId));
410 } else {
411 ALOGE("Cannot deliver physical camera status change. Global camera manager died");
412 }
413 return binder::Status::ok();
414}
415
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800416void CameraManagerGlobal::onCameraAccessPrioritiesChanged() {
417 Mutex::Autolock _l(mLock);
418 for (auto cb : mCallbacks) {
419 sp<AMessage> msg = new AMessage(kWhatSendSingleAccessCallback, mHandler);
420 ACameraManager_AccessPrioritiesChangedCallback cbFp = cb.mAccessPriorityChanged;
421 if (cbFp != nullptr) {
422 msg->setPointer(kCallbackFpKey, (void *) cbFp);
423 msg->setPointer(kContextKey, cb.mContext);
424 msg->post();
425 }
426 }
427}
428
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800429void CameraManagerGlobal::onStatusChanged(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800430 int32_t status, const String8& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800431 Mutex::Autolock _l(mLock);
432 onStatusChangedLocked(status, cameraId);
433}
434
435void CameraManagerGlobal::onStatusChangedLocked(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800436 int32_t status, const String8& cameraId) {
437 if (!validStatus(status)) {
438 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
439 return;
440 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800441
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800442 bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
443 int32_t oldStatus = firstStatus ?
444 status : // first status
Shuzhen Wang43858162020-01-10 13:42:15 -0800445 mDeviceStatusMap[cameraId].getStatus();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800446
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800447 if (!firstStatus &&
448 isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
449 // No status update. No need to send callback
450 return;
451 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800452
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700453 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800454 if (firstStatus) {
455 mDeviceStatusMap.emplace(std::piecewise_construct,
456 std::forward_as_tuple(cameraId),
457 std::forward_as_tuple(status, supportsHAL3));
458 } else {
459 mDeviceStatusMap[cameraId].updateStatus(status);
460 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800461 // Iterate through all registered callbacks
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700462 if (supportsHAL3) {
463 for (auto cb : mCallbacks) {
464 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
465 ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
466 cb.mAvailable : cb.mUnavailable;
467 msg->setPointer(kCallbackFpKey, (void *) cbFp);
468 msg->setPointer(kContextKey, cb.mContext);
469 msg->setString(kCameraIdKey, AString(cameraId));
470 msg->post();
471 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800472 }
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100473 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
474 mDeviceStatusMap.erase(cameraId);
475 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800476}
477
Shuzhen Wang43858162020-01-10 13:42:15 -0800478void CameraManagerGlobal::onStatusChanged(
479 int32_t status, const String8& cameraId, const String8& physicalCameraId) {
480 Mutex::Autolock _l(mLock);
481 onStatusChangedLocked(status, cameraId, physicalCameraId);
482}
483
484void CameraManagerGlobal::onStatusChangedLocked(
485 int32_t status, const String8& cameraId, const String8& physicalCameraId) {
486 if (!validStatus(status)) {
487 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
488 return;
489 }
490
491 auto logicalStatus = mDeviceStatusMap.find(cameraId);
492 if (logicalStatus == mDeviceStatusMap.end()) {
493 ALOGE("%s: Physical camera id %s status change on a non-present id %s",
494 __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str());
495 return;
496 }
497 int32_t logicalCamStatus = mDeviceStatusMap[cameraId].getStatus();
498 if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT &&
499 logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) {
500 ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
501 __FUNCTION__, physicalCameraId.string(), status, logicalCamStatus);
502 return;
503 }
504
505 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
506
507 bool updated = false;
508 if (status == hardware::ICameraServiceListener::STATUS_PRESENT) {
509 updated = mDeviceStatusMap[cameraId].removeUnavailablePhysicalId(physicalCameraId);
510 } else {
511 updated = mDeviceStatusMap[cameraId].addUnavailablePhysicalId(physicalCameraId);
512 }
513
514 // Iterate through all registered callbacks
515 if (supportsHAL3 && updated) {
516 for (auto cb : mCallbacks) {
517 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
518 ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ?
519 cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable;
520 msg->setPointer(kCallbackFpKey, (void *) cbFp);
521 msg->setPointer(kContextKey, cb.mContext);
522 msg->setString(kCameraIdKey, AString(cameraId));
523 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
524 msg->post();
525 }
526 }
527}
528
529int32_t CameraManagerGlobal::StatusAndHAL3Support::getStatus() {
530 std::lock_guard<std::mutex> lock(mLock);
531 return status;
532}
533
534void CameraManagerGlobal::StatusAndHAL3Support::updateStatus(int32_t newStatus) {
535 std::lock_guard<std::mutex> lock(mLock);
536 status = newStatus;
537}
538
539bool CameraManagerGlobal::StatusAndHAL3Support::addUnavailablePhysicalId(
540 const String8& physicalCameraId) {
541 std::lock_guard<std::mutex> lock(mLock);
542 auto result = unavailablePhysicalIds.insert(physicalCameraId);
543 return result.second;
544}
545
546bool CameraManagerGlobal::StatusAndHAL3Support::removeUnavailablePhysicalId(
547 const String8& physicalCameraId) {
548 std::lock_guard<std::mutex> lock(mLock);
549 auto count = unavailablePhysicalIds.erase(physicalCameraId);
550 return count > 0;
551}
552
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800553} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800554} // namespace android
555
556/**
557 * ACameraManger Implementation
558 */
559camera_status_t
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800560ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
561 Mutex::Autolock _l(mLock);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800562
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800563 std::vector<String8> idList;
564 CameraManagerGlobal::getInstance().getCameraIdList(&idList);
565
566 int numCameras = idList.size();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800567 ACameraIdList *out = new ACameraIdList;
568 if (!out) {
569 ALOGE("Allocate memory for ACameraIdList failed!");
570 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
571 }
572 out->numCameras = numCameras;
Bjoern Johansson1a5954c2017-01-10 10:30:18 -0800573 out->cameraIds = new const char*[numCameras];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800574 if (!out->cameraIds) {
575 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800576 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800577 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
578 }
579 for (int i = 0; i < numCameras; i++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800580 const char* src = idList[i].string();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800581 size_t dstSize = strlen(src) + 1;
582 char* dst = new char[dstSize];
583 if (!dst) {
584 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800585 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800586 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
587 }
588 strlcpy(dst, src, dstSize);
589 out->cameraIds[i] = dst;
590 }
591 *cameraIdList = out;
592 return ACAMERA_OK;
593}
594
595void
596ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
597 if (cameraIdList != nullptr) {
598 if (cameraIdList->cameraIds != nullptr) {
599 for (int i = 0; i < cameraIdList->numCameras; i ++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800600 if (cameraIdList->cameraIds[i] != nullptr) {
601 delete[] cameraIdList->cameraIds[i];
602 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800603 }
604 delete[] cameraIdList->cameraIds;
605 }
606 delete cameraIdList;
607 }
608}
609
610camera_status_t ACameraManager::getCameraCharacteristics(
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700611 const char* cameraIdStr, sp<ACameraMetadata>* characteristics) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800612 Mutex::Autolock _l(mLock);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800613
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800614 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800615 if (cs == nullptr) {
616 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
617 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
618 }
619 CameraMetadata rawMetadata;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800620 binder::Status serviceRet = cs->getCameraCharacteristics(String16(cameraIdStr), &rawMetadata);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800621 if (!serviceRet.isOk()) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800622 switch(serviceRet.serviceSpecificErrorCode()) {
623 case hardware::ICameraService::ERROR_DISCONNECTED:
624 ALOGE("%s: Camera %s has been disconnected", __FUNCTION__, cameraIdStr);
625 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
626 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
627 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
628 return ACAMERA_ERROR_INVALID_PARAMETER;
629 default:
630 ALOGE("Get camera characteristics from camera service failed: %s",
631 serviceRet.toString8().string());
632 return ACAMERA_ERROR_UNKNOWN; // should not reach here
633 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800634 }
635
636 *characteristics = new ACameraMetadata(
637 rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
638 return ACAMERA_OK;
639}
640
641camera_status_t
642ACameraManager::openCamera(
643 const char* cameraId,
644 ACameraDevice_StateCallbacks* callback,
645 /*out*/ACameraDevice** outDevice) {
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700646 sp<ACameraMetadata> chars;
647 camera_status_t ret = getCameraCharacteristics(cameraId, &chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800648 Mutex::Autolock _l(mLock);
649 if (ret != ACAMERA_OK) {
650 ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
651 __FUNCTION__, cameraId, ret);
652 return ACAMERA_ERROR_INVALID_PARAMETER;
653 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800654
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700655 ACameraDevice* device = new ACameraDevice(cameraId, callback, chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800656
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800657 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800658 if (cs == nullptr) {
659 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
Yunlian Jiangb01d8f72016-10-04 16:34:18 -0700660 delete device;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800661 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
662 }
663
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800664 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
665 sp<hardware::camera2::ICameraDeviceUser> deviceRemote;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800666 // No way to get package name from native.
667 // Send a zero length package name and let camera service figure it out from UID
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800668 binder::Status serviceRet = cs->connectDevice(
Philip P. Moltmann9e648f62019-11-04 12:52:45 -0800669 callbacks, String16(cameraId), String16(""), std::unique_ptr<String16>(),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800670 hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800671
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800672 if (!serviceRet.isOk()) {
673 ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().string());
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700674 // Convert serviceRet to camera_status_t
675 switch(serviceRet.serviceSpecificErrorCode()) {
676 case hardware::ICameraService::ERROR_DISCONNECTED:
677 ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
678 break;
679 case hardware::ICameraService::ERROR_CAMERA_IN_USE:
680 ret = ACAMERA_ERROR_CAMERA_IN_USE;
681 break;
682 case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
683 ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
684 break;
685 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
686 ret = ACAMERA_ERROR_INVALID_PARAMETER;
687 break;
688 case hardware::ICameraService::ERROR_DEPRECATED_HAL:
689 // Should not reach here since we filtered legacy HALs earlier
690 ret = ACAMERA_ERROR_INVALID_PARAMETER;
691 break;
692 case hardware::ICameraService::ERROR_DISABLED:
693 ret = ACAMERA_ERROR_CAMERA_DISABLED;
694 break;
695 case hardware::ICameraService::ERROR_PERMISSION_DENIED:
696 ret = ACAMERA_ERROR_PERMISSION_DENIED;
697 break;
698 case hardware::ICameraService::ERROR_INVALID_OPERATION:
699 default:
700 ret = ACAMERA_ERROR_UNKNOWN;
701 break;
702 }
703
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800704 delete device;
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700705 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800706 }
707 if (deviceRemote == nullptr) {
708 ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
709 delete device;
710 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
711 }
712 device->setRemoteDevice(deviceRemote);
713 *outDevice = device;
714 return ACAMERA_OK;
715}
716
717ACameraManager::~ACameraManager() {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800718
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800719}