blob: 7a0f63bc13bc5f0e3e2d94385f808c69348df87e [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";
35const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
36const char* CameraManagerGlobal::kContextKey = "CallbackContext";
37Mutex CameraManagerGlobal::sLock;
38CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
39
40CameraManagerGlobal&
41CameraManagerGlobal::getInstance() {
42 Mutex::Autolock _l(sLock);
43 CameraManagerGlobal* instance = sInstance;
44 if (instance == nullptr) {
45 instance = new CameraManagerGlobal();
46 sInstance = instance;
47 }
48 return *instance;
49}
50
51CameraManagerGlobal::~CameraManagerGlobal() {
52 // clear sInstance so next getInstance call knows to create a new one
53 Mutex::Autolock _sl(sLock);
54 sInstance = nullptr;
55 Mutex::Autolock _l(mLock);
56 if (mCameraService != nullptr) {
57 IInterface::asBinder(mCameraService)->unlinkToDeath(mDeathNotifier);
Yin-Chia Yehead91462016-01-06 16:45:08 -080058 mCameraService->removeListener(mCameraServiceListener);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080059 }
60 mDeathNotifier.clear();
61 if (mCbLooper != nullptr) {
62 mCbLooper->unregisterHandler(mHandler->id());
63 mCbLooper->stop();
64 }
65 mCbLooper.clear();
66 mHandler.clear();
67 mCameraServiceListener.clear();
68 mCameraService.clear();
69}
70
Ivan Podogovee844a82016-09-15 11:32:41 +010071static bool isCameraServiceDisabled() {
72 char value[PROPERTY_VALUE_MAX];
73 property_get("config.disable_cameraservice", value, "0");
74 return (strncmp(value, "0", 2) != 0 && strncasecmp(value, "false", 6) != 0);
75}
76
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080077sp<hardware::ICameraService> CameraManagerGlobal::getCameraService() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080078 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -070079 return getCameraServiceLocked();
80}
81
82sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080083 if (mCameraService.get() == nullptr) {
Ivan Podogovee844a82016-09-15 11:32:41 +010084 if (isCameraServiceDisabled()) {
85 return mCameraService;
86 }
87
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080088 sp<IServiceManager> sm = defaultServiceManager();
89 sp<IBinder> binder;
90 do {
91 binder = sm->getService(String16(kCameraServiceName));
92 if (binder != nullptr) {
93 break;
94 }
95 ALOGW("CameraService not published, waiting...");
96 usleep(kCameraServicePollDelay);
97 } while(true);
98 if (mDeathNotifier == nullptr) {
99 mDeathNotifier = new DeathNotifier(this);
100 }
101 binder->linkToDeath(mDeathNotifier);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800102 mCameraService = interface_cast<hardware::ICameraService>(binder);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800103
104 // Setup looper thread to perfrom availiability callbacks
105 if (mCbLooper == nullptr) {
106 mCbLooper = new ALooper;
107 mCbLooper->setName("C2N-mgr-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800108 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800109 /*runOnCallingThread*/false,
110 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800111 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800112 if (err != OK) {
113 ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
114 __FUNCTION__, strerror(-err), err);
115 mCbLooper.clear();
116 return nullptr;
117 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800118 if (mHandler == nullptr) {
119 mHandler = new CallbackHandler();
120 }
121 mCbLooper->registerHandler(mHandler);
122 }
123
124 // register ICameraServiceListener
125 if (mCameraServiceListener == nullptr) {
126 mCameraServiceListener = new CameraServiceListener(this);
127 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800128 std::vector<hardware::CameraStatus> cameraStatuses{};
129 mCameraService->addListener(mCameraServiceListener, &cameraStatuses);
130 for (auto& c : cameraStatuses) {
131 onStatusChangedLocked(c.status, c.cameraId);
132 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800133
134 // setup vendor tags
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800135 sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
136 binder::Status ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800137
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800138 if (ret.isOk()) {
Emilian Peev71c73a22017-03-21 16:35:51 +0000139 if (0 < desc->getTagCount()) {
140 status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
141 if (err != OK) {
142 ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
143 __FUNCTION__, strerror(-err), err);
144 }
145 } else {
146 sp<VendorTagDescriptorCache> cache =
147 new VendorTagDescriptorCache();
148 binder::Status res =
149 mCameraService->getCameraVendorTagCache(
150 /*out*/cache.get());
151 if (res.serviceSpecificErrorCode() ==
152 hardware::ICameraService::ERROR_DISCONNECTED) {
153 // No camera module available, not an error on devices with no cameras
154 VendorTagDescriptorCache::clearGlobalVendorTagCache();
155 } else if (res.isOk()) {
156 status_t err =
157 VendorTagDescriptorCache::setAsGlobalVendorTagCache(
158 cache);
159 if (err != OK) {
160 ALOGE("%s: Failed to set vendor tag cache,"
161 "received error %s (%d)", __FUNCTION__,
162 strerror(-err), err);
163 }
164 } else {
165 VendorTagDescriptorCache::clearGlobalVendorTagCache();
166 ALOGE("%s: Failed to setup vendor tag cache: %s",
167 __FUNCTION__, res.toString8().string());
168 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800169 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800170 } else if (ret.serviceSpecificErrorCode() ==
171 hardware::ICameraService::ERROR_DEPRECATED_HAL) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800172 ALOGW("%s: Camera HAL too old; does not support vendor tags",
173 __FUNCTION__);
174 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
175 } else {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800176 ALOGE("%s: Failed to get vendor tag descriptors: %s",
177 __FUNCTION__, ret.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800178 }
179 }
180 ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
181 return mCameraService;
182}
183
184void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
185{
186 ALOGE("Camera service binderDied!");
187 sp<CameraManagerGlobal> cm = mCameraManager.promote();
188 if (cm != nullptr) {
189 AutoMutex lock(cm->mLock);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800190 for (auto& pair : cm->mDeviceStatusMap) {
191 const String8 &cameraId = pair.first;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800192 cm->onStatusChangedLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800193 CameraServiceListener::STATUS_NOT_PRESENT, cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800194 }
195 cm->mCameraService.clear();
196 // TODO: consider adding re-connect call here?
197 }
198}
199
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800200void CameraManagerGlobal::registerExtendedAvailabilityCallback(
201 const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
202 Mutex::Autolock _l(mLock);
203 Callback cb(callback);
204 mCallbacks.insert(cb);
205}
206
207void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
208 const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
209 Mutex::Autolock _l(mLock);
210 Callback cb(callback);
211 mCallbacks.erase(cb);
212}
213
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800214void CameraManagerGlobal::registerAvailabilityCallback(
215 const ACameraManager_AvailabilityCallbacks *callback) {
216 Mutex::Autolock _l(mLock);
217 Callback cb(callback);
218 auto pair = mCallbacks.insert(cb);
219 // Send initial callbacks if callback is newly registered
220 if (pair.second) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800221 for (auto& pair : mDeviceStatusMap) {
222 const String8& cameraId = pair.first;
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700223 int32_t status = pair.second.status;
224 // Don't send initial callbacks for camera ids which don't support
225 // camera2
226 if (!pair.second.supportsHAL3) {
227 continue;
228 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800229 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
230 ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ?
231 callback->onCameraAvailable : callback->onCameraUnavailable;
232 msg->setPointer(kCallbackFpKey, (void *) cb);
233 msg->setPointer(kContextKey, callback->context);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800234 msg->setString(kCameraIdKey, AString(cameraId));
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800235 msg->post();
236 }
237 }
238}
239
240void CameraManagerGlobal::unregisterAvailabilityCallback(
241 const ACameraManager_AvailabilityCallbacks *callback) {
242 Mutex::Autolock _l(mLock);
243 Callback cb(callback);
244 mCallbacks.erase(cb);
245}
246
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700247bool CameraManagerGlobal::supportsCamera2ApiLocked(const String8 &cameraId) {
248 bool camera2Support = false;
249 auto cs = getCameraServiceLocked();
250 binder::Status serviceRet =
251 cs->supportsCameraApi(String16(cameraId),
252 hardware::ICameraService::API_VERSION_2, &camera2Support);
253 if (!serviceRet.isOk()) {
254 ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId %s",
255 __FUNCTION__, cameraId.c_str());
256 return false;
257 }
258 return camera2Support;
259}
260
Yin-Chia Yeh03f55752018-03-14 15:28:02 -0700261void CameraManagerGlobal::getCameraIdList(std::vector<String8>* cameraIds) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800262 // Ensure that we have initialized/refreshed the list of available devices
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800263 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700264 // Needed to make sure we're connected to cameraservice
265 getCameraServiceLocked();
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800266 for(auto& deviceStatus : mDeviceStatusMap) {
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700267 if (deviceStatus.second.status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
268 deviceStatus.second.status ==
269 hardware::ICameraServiceListener::STATUS_ENUMERATING) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800270 continue;
271 }
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700272 if (!deviceStatus.second.supportsHAL3) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800273 continue;
274 }
275 cameraIds->push_back(deviceStatus.first);
276 }
277}
278
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800279bool CameraManagerGlobal::validStatus(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800280 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800281 case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
282 case hardware::ICameraServiceListener::STATUS_PRESENT:
283 case hardware::ICameraServiceListener::STATUS_ENUMERATING:
284 case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800285 return true;
286 default:
287 return false;
288 }
289}
290
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800291bool CameraManagerGlobal::isStatusAvailable(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800292 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800293 case hardware::ICameraServiceListener::STATUS_PRESENT:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800294 return true;
295 default:
296 return false;
297 }
298}
299
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800300void CameraManagerGlobal::CallbackHandler::onMessageReceived(
301 const sp<AMessage> &msg) {
302 switch (msg->what()) {
303 case kWhatSendSingleCallback:
304 {
305 ACameraManager_AvailabilityCallback cb;
306 void* context;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800307 AString cameraId;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800308 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
309 if (!found) {
310 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
311 return;
312 }
313 found = msg->findPointer(kContextKey, &context);
314 if (!found) {
315 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
316 return;
317 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800318 found = msg->findString(kCameraIdKey, &cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800319 if (!found) {
320 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
321 return;
322 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800323 (*cb)(context, cameraId.c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800324 break;
325 }
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800326 case kWhatSendSingleAccessCallback:
327 {
328 ACameraManager_AccessPrioritiesChangedCallback cb;
329 void* context;
330 AString cameraId;
331 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
332 if (!found) {
333 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
334 return;
335 }
336 found = msg->findPointer(kContextKey, &context);
337 if (!found) {
338 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
339 return;
340 }
341 (*cb)(context);
342 break;
343 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800344 default:
345 ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
346 break;
347 }
348}
349
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800350binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPrioritiesChanged() {
351 sp<CameraManagerGlobal> cm = mCameraManager.promote();
352 if (cm != nullptr) {
353 cm->onCameraAccessPrioritiesChanged();
354 } else {
355 ALOGE("Cannot deliver camera access priority callback. Global camera manager died");
356 }
357 return binder::Status::ok();
358}
359
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800360binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800361 int32_t status, const String16& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800362 sp<CameraManagerGlobal> cm = mCameraManager.promote();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800363 if (cm != nullptr) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800364 cm->onStatusChanged(status, String8(cameraId));
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800365 } else {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800366 ALOGE("Cannot deliver status change. Global camera manager died");
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800367 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800368 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800369}
370
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800371void CameraManagerGlobal::onCameraAccessPrioritiesChanged() {
372 Mutex::Autolock _l(mLock);
373 for (auto cb : mCallbacks) {
374 sp<AMessage> msg = new AMessage(kWhatSendSingleAccessCallback, mHandler);
375 ACameraManager_AccessPrioritiesChangedCallback cbFp = cb.mAccessPriorityChanged;
376 if (cbFp != nullptr) {
377 msg->setPointer(kCallbackFpKey, (void *) cbFp);
378 msg->setPointer(kContextKey, cb.mContext);
379 msg->post();
380 }
381 }
382}
383
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800384void CameraManagerGlobal::onStatusChanged(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800385 int32_t status, const String8& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800386 Mutex::Autolock _l(mLock);
387 onStatusChangedLocked(status, cameraId);
388}
389
390void CameraManagerGlobal::onStatusChangedLocked(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800391 int32_t status, const String8& cameraId) {
392 if (!validStatus(status)) {
393 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
394 return;
395 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800396
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800397 bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
398 int32_t oldStatus = firstStatus ?
399 status : // first status
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700400 mDeviceStatusMap[cameraId].status;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800401
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800402 if (!firstStatus &&
403 isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
404 // No status update. No need to send callback
405 return;
406 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800407
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700408 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800409 // Iterate through all registered callbacks
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700410 mDeviceStatusMap[cameraId] = StatusAndHAL3Support(status, supportsHAL3);
411 if (supportsHAL3) {
412 for (auto cb : mCallbacks) {
413 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
414 ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
415 cb.mAvailable : cb.mUnavailable;
416 msg->setPointer(kCallbackFpKey, (void *) cbFp);
417 msg->setPointer(kContextKey, cb.mContext);
418 msg->setString(kCameraIdKey, AString(cameraId));
419 msg->post();
420 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800421 }
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100422 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
423 mDeviceStatusMap.erase(cameraId);
424 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800425}
426
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800427} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800428} // namespace android
429
430/**
431 * ACameraManger Implementation
432 */
433camera_status_t
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800434ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
435 Mutex::Autolock _l(mLock);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800436
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800437 std::vector<String8> idList;
438 CameraManagerGlobal::getInstance().getCameraIdList(&idList);
439
440 int numCameras = idList.size();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800441 ACameraIdList *out = new ACameraIdList;
442 if (!out) {
443 ALOGE("Allocate memory for ACameraIdList failed!");
444 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
445 }
446 out->numCameras = numCameras;
Bjoern Johansson1a5954c2017-01-10 10:30:18 -0800447 out->cameraIds = new const char*[numCameras];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800448 if (!out->cameraIds) {
449 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800450 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800451 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
452 }
453 for (int i = 0; i < numCameras; i++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800454 const char* src = idList[i].string();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800455 size_t dstSize = strlen(src) + 1;
456 char* dst = new char[dstSize];
457 if (!dst) {
458 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800459 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800460 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
461 }
462 strlcpy(dst, src, dstSize);
463 out->cameraIds[i] = dst;
464 }
465 *cameraIdList = out;
466 return ACAMERA_OK;
467}
468
469void
470ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
471 if (cameraIdList != nullptr) {
472 if (cameraIdList->cameraIds != nullptr) {
473 for (int i = 0; i < cameraIdList->numCameras; i ++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800474 if (cameraIdList->cameraIds[i] != nullptr) {
475 delete[] cameraIdList->cameraIds[i];
476 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800477 }
478 delete[] cameraIdList->cameraIds;
479 }
480 delete cameraIdList;
481 }
482}
483
484camera_status_t ACameraManager::getCameraCharacteristics(
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700485 const char* cameraIdStr, sp<ACameraMetadata>* characteristics) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800486 Mutex::Autolock _l(mLock);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800487
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800488 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800489 if (cs == nullptr) {
490 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
491 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
492 }
493 CameraMetadata rawMetadata;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800494 binder::Status serviceRet = cs->getCameraCharacteristics(String16(cameraIdStr), &rawMetadata);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800495 if (!serviceRet.isOk()) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800496 switch(serviceRet.serviceSpecificErrorCode()) {
497 case hardware::ICameraService::ERROR_DISCONNECTED:
498 ALOGE("%s: Camera %s has been disconnected", __FUNCTION__, cameraIdStr);
499 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
500 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
501 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
502 return ACAMERA_ERROR_INVALID_PARAMETER;
503 default:
504 ALOGE("Get camera characteristics from camera service failed: %s",
505 serviceRet.toString8().string());
506 return ACAMERA_ERROR_UNKNOWN; // should not reach here
507 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800508 }
509
510 *characteristics = new ACameraMetadata(
511 rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
512 return ACAMERA_OK;
513}
514
515camera_status_t
516ACameraManager::openCamera(
517 const char* cameraId,
518 ACameraDevice_StateCallbacks* callback,
519 /*out*/ACameraDevice** outDevice) {
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700520 sp<ACameraMetadata> chars;
521 camera_status_t ret = getCameraCharacteristics(cameraId, &chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800522 Mutex::Autolock _l(mLock);
523 if (ret != ACAMERA_OK) {
524 ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
525 __FUNCTION__, cameraId, ret);
526 return ACAMERA_ERROR_INVALID_PARAMETER;
527 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800528
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700529 ACameraDevice* device = new ACameraDevice(cameraId, callback, chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800530
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800531 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800532 if (cs == nullptr) {
533 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
Yunlian Jiangb01d8f72016-10-04 16:34:18 -0700534 delete device;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800535 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
536 }
537
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800538 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
539 sp<hardware::camera2::ICameraDeviceUser> deviceRemote;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800540 // No way to get package name from native.
541 // Send a zero length package name and let camera service figure it out from UID
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800542 binder::Status serviceRet = cs->connectDevice(
Philip P. Moltmann9e648f62019-11-04 12:52:45 -0800543 callbacks, String16(cameraId), String16(""), std::unique_ptr<String16>(),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800544 hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800545
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800546 if (!serviceRet.isOk()) {
547 ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().string());
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700548 // Convert serviceRet to camera_status_t
549 switch(serviceRet.serviceSpecificErrorCode()) {
550 case hardware::ICameraService::ERROR_DISCONNECTED:
551 ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
552 break;
553 case hardware::ICameraService::ERROR_CAMERA_IN_USE:
554 ret = ACAMERA_ERROR_CAMERA_IN_USE;
555 break;
556 case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
557 ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
558 break;
559 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
560 ret = ACAMERA_ERROR_INVALID_PARAMETER;
561 break;
562 case hardware::ICameraService::ERROR_DEPRECATED_HAL:
563 // Should not reach here since we filtered legacy HALs earlier
564 ret = ACAMERA_ERROR_INVALID_PARAMETER;
565 break;
566 case hardware::ICameraService::ERROR_DISABLED:
567 ret = ACAMERA_ERROR_CAMERA_DISABLED;
568 break;
569 case hardware::ICameraService::ERROR_PERMISSION_DENIED:
570 ret = ACAMERA_ERROR_PERMISSION_DENIED;
571 break;
572 case hardware::ICameraService::ERROR_INVALID_OPERATION:
573 default:
574 ret = ACAMERA_ERROR_UNKNOWN;
575 break;
576 }
577
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800578 delete device;
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700579 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800580 }
581 if (deviceRemote == nullptr) {
582 ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
583 delete device;
584 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
585 }
586 device->setRemoteDevice(deviceRemote);
587 *outDevice = device;
588 return ACAMERA_OK;
589}
590
591ACameraManager::~ACameraManager() {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800592
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800593}