blob: 4014fd2cb28cfd54fba732ce62ed975210c67127 [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>
25#include <stdlib.h>
26#include <camera/VendorTagDescriptor.h>
27
28using namespace android;
29
30//constants shared between ACameraManager and CameraManagerGlobal
31namespace {
32 const int kMaxCameraIdLen = 32;
33}
34
35namespace android {
36// Static member definitions
37const char* CameraManagerGlobal::kCameraIdKey = "CameraId";
38const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
39const char* CameraManagerGlobal::kContextKey = "CallbackContext";
40Mutex CameraManagerGlobal::sLock;
41CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
42
43CameraManagerGlobal&
44CameraManagerGlobal::getInstance() {
45 Mutex::Autolock _l(sLock);
46 CameraManagerGlobal* instance = sInstance;
47 if (instance == nullptr) {
48 instance = new CameraManagerGlobal();
49 sInstance = instance;
50 }
51 return *instance;
52}
53
54CameraManagerGlobal::~CameraManagerGlobal() {
55 // clear sInstance so next getInstance call knows to create a new one
56 Mutex::Autolock _sl(sLock);
57 sInstance = nullptr;
58 Mutex::Autolock _l(mLock);
59 if (mCameraService != nullptr) {
60 IInterface::asBinder(mCameraService)->unlinkToDeath(mDeathNotifier);
61 }
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
73sp<ICameraService> CameraManagerGlobal::getCameraService() {
74 Mutex::Autolock _l(mLock);
75 if (mCameraService.get() == nullptr) {
76 sp<IServiceManager> sm = defaultServiceManager();
77 sp<IBinder> binder;
78 do {
79 binder = sm->getService(String16(kCameraServiceName));
80 if (binder != nullptr) {
81 break;
82 }
83 ALOGW("CameraService not published, waiting...");
84 usleep(kCameraServicePollDelay);
85 } while(true);
86 if (mDeathNotifier == nullptr) {
87 mDeathNotifier = new DeathNotifier(this);
88 }
89 binder->linkToDeath(mDeathNotifier);
90 mCameraService = interface_cast<ICameraService>(binder);
91
92 // Setup looper thread to perfrom availiability callbacks
93 if (mCbLooper == nullptr) {
94 mCbLooper = new ALooper;
95 mCbLooper->setName("C2N-mgr-looper");
96 status_t ret = mCbLooper->start(
97 /*runOnCallingThread*/false,
98 /*canCallJava*/ true,
99 PRIORITY_FOREGROUND);
100 if (mHandler == nullptr) {
101 mHandler = new CallbackHandler();
102 }
103 mCbLooper->registerHandler(mHandler);
104 }
105
106 // register ICameraServiceListener
107 if (mCameraServiceListener == nullptr) {
108 mCameraServiceListener = new CameraServiceListener(this);
109 }
110 mCameraService->addListener(mCameraServiceListener);
111
112 // setup vendor tags
113 sp<VendorTagDescriptor> desc;
114 status_t ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc);
115
116 if (ret == OK) {
117 ret = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
118 if (ret != OK) {
119 ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
120 __FUNCTION__, strerror(-ret), ret);
121 }
122 } else if (ret == -EOPNOTSUPP) {
123 ALOGW("%s: Camera HAL too old; does not support vendor tags",
124 __FUNCTION__);
125 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
126 } else {
127 ALOGE("%s: Failed to get vendor tag descriptors, received error %s (%d)",
128 __FUNCTION__, strerror(-ret), ret);
129 }
130 }
131 ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
132 return mCameraService;
133}
134
135void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
136{
137 ALOGE("Camera service binderDied!");
138 sp<CameraManagerGlobal> cm = mCameraManager.promote();
139 if (cm != nullptr) {
140 AutoMutex lock(cm->mLock);
141 for (auto pair : cm->mDeviceStatusMap) {
142 int32_t cameraId = pair.first;
143 cm->onStatusChangedLocked(
144 ICameraServiceListener::STATUS_NOT_PRESENT, cameraId);
145 }
146 cm->mCameraService.clear();
147 // TODO: consider adding re-connect call here?
148 }
149}
150
151void CameraManagerGlobal::registerAvailabilityCallback(
152 const ACameraManager_AvailabilityCallbacks *callback) {
153 Mutex::Autolock _l(mLock);
154 Callback cb(callback);
155 auto pair = mCallbacks.insert(cb);
156 // Send initial callbacks if callback is newly registered
157 if (pair.second) {
158 for (auto pair : mDeviceStatusMap) {
159 int32_t cameraId = pair.first;
160 Status status = pair.second;
161
162 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
163 ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ?
164 callback->onCameraAvailable : callback->onCameraUnavailable;
165 msg->setPointer(kCallbackFpKey, (void *) cb);
166 msg->setPointer(kContextKey, callback->context);
167 msg->setInt32(kCameraIdKey, cameraId);
168 msg->post();
169 }
170 }
171}
172
173void CameraManagerGlobal::unregisterAvailabilityCallback(
174 const ACameraManager_AvailabilityCallbacks *callback) {
175 Mutex::Autolock _l(mLock);
176 Callback cb(callback);
177 mCallbacks.erase(cb);
178}
179
180bool CameraManagerGlobal::validStatus(Status status) {
181 switch (status) {
182 case ICameraServiceListener::STATUS_NOT_PRESENT:
183 case ICameraServiceListener::STATUS_PRESENT:
184 case ICameraServiceListener::STATUS_ENUMERATING:
185 case ICameraServiceListener::STATUS_NOT_AVAILABLE:
186 return true;
187 default:
188 return false;
189 }
190}
191
192bool CameraManagerGlobal::isStatusAvailable(Status status) {
193 switch (status) {
194 case ICameraServiceListener::STATUS_PRESENT:
195 return true;
196 default:
197 return false;
198 }
199}
200
201void CameraManagerGlobal::CallbackHandler::sendSingleCallback(
202 int32_t cameraId, void* context,
203 ACameraManager_AvailabilityCallback cb) const {
204 char cameraIdStr[kMaxCameraIdLen];
205 snprintf(cameraIdStr, sizeof(cameraIdStr), "%d", cameraId);
206 (*cb)(context, cameraIdStr);
207}
208
209void CameraManagerGlobal::CallbackHandler::onMessageReceived(
210 const sp<AMessage> &msg) {
211 switch (msg->what()) {
212 case kWhatSendSingleCallback:
213 {
214 ACameraManager_AvailabilityCallback cb;
215 void* context;
216 int32_t cameraId;
217 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
218 if (!found) {
219 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
220 return;
221 }
222 found = msg->findPointer(kContextKey, &context);
223 if (!found) {
224 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
225 return;
226 }
227 found = msg->findInt32(kCameraIdKey, &cameraId);
228 if (!found) {
229 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
230 return;
231 }
232 sendSingleCallback(cameraId, context, cb);
233 break;
234 }
235 default:
236 ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
237 break;
238 }
239}
240
241void CameraManagerGlobal::CameraServiceListener::onStatusChanged(
242 Status status, int32_t cameraId) {
243 sp<CameraManagerGlobal> cm = mCameraManager.promote();
244 if (cm == nullptr) {
245 ALOGE("Cannot deliver status change. Camera service died");
246 return;
247 }
248 cm->onStatusChanged(status, cameraId);
249}
250
251void CameraManagerGlobal::onStatusChanged(
252 Status status, int32_t cameraId) {
253 Mutex::Autolock _l(mLock);
254 onStatusChangedLocked(status, cameraId);
255}
256
257void CameraManagerGlobal::onStatusChangedLocked(
258 Status status, int32_t cameraId) {
259 if (!validStatus(status)) {
260 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
261 return;
262 }
263
264 bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
265 Status oldStatus = firstStatus ?
266 status : // first status
267 mDeviceStatusMap[cameraId];
268
269 if (!firstStatus &&
270 isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
271 // No status update. No need to send callback
272 return;
273 }
274
275 // Iterate through all registered callbacks
276 mDeviceStatusMap[cameraId] = status;
277 for (auto cb : mCallbacks) {
278 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
279 ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
280 cb.mAvailable : cb.mUnavailable;
281 msg->setPointer(kCallbackFpKey, (void *) cbFp);
282 msg->setPointer(kContextKey, cb.mContext);
283 msg->setInt32(kCameraIdKey, cameraId);
284 msg->post();
285 }
286}
287
288} // namespace android
289
290/**
291 * ACameraManger Implementation
292 */
293camera_status_t
294ACameraManager::getOrCreateCameraIdListLocked(ACameraIdList** cameraIdList) {
295 if (mCachedCameraIdList.numCameras == kCameraIdListNotInit) {
296 int numCameras = 0;
297 Vector<char *> cameraIds;
298 sp<ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
299 if (cs == nullptr) {
300 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
301 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
302 }
303 // Get number of cameras
304 int numAllCameras = cs->getNumberOfCameras(ICameraService::CAMERA_TYPE_ALL);
305 // Filter API2 compatible cameras and push to cameraIds
306 for (int i = 0; i < numAllCameras; i++) {
307 // TODO: Only suppot HALs that supports API2 directly now
308 status_t camera2Support = cs->supportsCameraApi(i, ICameraService::API_VERSION_2);
309 char buf[kMaxCameraIdLen];
310 if (camera2Support == OK) {
311 numCameras++;
312 mCameraIds.insert(i);
313 snprintf(buf, sizeof(buf), "%d", i);
314 size_t cameraIdSize = strlen(buf) + 1;
315 char *cameraId = new char[cameraIdSize];
316 if (!cameraId) {
317 ALOGE("Allocate memory for ACameraIdList failed!");
318 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
319 }
320 strlcpy(cameraId, buf, cameraIdSize);
321 cameraIds.push(cameraId);
322 }
323 }
324 mCachedCameraIdList.numCameras = numCameras;
325 mCachedCameraIdList.cameraIds = new const char*[numCameras];
326 if (!mCachedCameraIdList.cameraIds) {
327 ALOGE("Allocate memory for ACameraIdList failed!");
328 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
329 }
330 for (int i = 0; i < numCameras; i++) {
331 mCachedCameraIdList.cameraIds[i] = cameraIds[i];
332 }
333 }
334 *cameraIdList = &mCachedCameraIdList;
335 return ACAMERA_OK;
336}
337
338camera_status_t
339ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
340 Mutex::Autolock _l(mLock);
341 ACameraIdList* cachedList;
342 camera_status_t ret = getOrCreateCameraIdListLocked(&cachedList);
343 if (ret != ACAMERA_OK) {
344 ALOGE("Get camera ID list failed! err: %d", ret);
345 return ret;
346 }
347
348 int numCameras = cachedList->numCameras;
349 ACameraIdList *out = new ACameraIdList;
350 if (!out) {
351 ALOGE("Allocate memory for ACameraIdList failed!");
352 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
353 }
354 out->numCameras = numCameras;
355 out->cameraIds = new const char*[numCameras];
356 if (!out->cameraIds) {
357 ALOGE("Allocate memory for ACameraIdList failed!");
358 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
359 }
360 for (int i = 0; i < numCameras; i++) {
361 const char* src = cachedList->cameraIds[i];
362 size_t dstSize = strlen(src) + 1;
363 char* dst = new char[dstSize];
364 if (!dst) {
365 ALOGE("Allocate memory for ACameraIdList failed!");
366 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
367 }
368 strlcpy(dst, src, dstSize);
369 out->cameraIds[i] = dst;
370 }
371 *cameraIdList = out;
372 return ACAMERA_OK;
373}
374
375void
376ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
377 if (cameraIdList != nullptr) {
378 if (cameraIdList->cameraIds != nullptr) {
379 for (int i = 0; i < cameraIdList->numCameras; i ++) {
380 delete[] cameraIdList->cameraIds[i];
381 }
382 delete[] cameraIdList->cameraIds;
383 }
384 delete cameraIdList;
385 }
386}
387
388camera_status_t ACameraManager::getCameraCharacteristics(
389 const char *cameraIdStr, ACameraMetadata **characteristics) {
390 Mutex::Autolock _l(mLock);
391 ACameraIdList* cachedList;
392 // Make sure mCameraIds is initialized
393 camera_status_t ret = getOrCreateCameraIdListLocked(&cachedList);
394 if (ret != ACAMERA_OK) {
395 ALOGE("%s: Get camera ID list failed! err: %d", __FUNCTION__, ret);
396 return ret;
397 }
398 int cameraId = atoi(cameraIdStr);
399 if (mCameraIds.count(cameraId) == 0) {
400 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
401 return ACAMERA_ERROR_INVALID_PARAMETER;
402 }
403 sp<ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
404 if (cs == nullptr) {
405 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
406 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
407 }
408 CameraMetadata rawMetadata;
409 status_t serviceRet = cs->getCameraCharacteristics(cameraId, &rawMetadata);
410 if (serviceRet != OK) {
411 ALOGE("Get camera characteristics from camera service failed! Err %d", ret);
412 return ACAMERA_ERROR_UNKNOWN; // should not reach here
413 }
414
415 *characteristics = new ACameraMetadata(
416 rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
417 return ACAMERA_OK;
418}
419
420camera_status_t
421ACameraManager::openCamera(
422 const char* cameraId,
423 ACameraDevice_StateCallbacks* callback,
424 /*out*/ACameraDevice** outDevice) {
425 ACameraMetadata* rawChars;
426 camera_status_t ret = getCameraCharacteristics(cameraId, &rawChars);
427 Mutex::Autolock _l(mLock);
428 if (ret != ACAMERA_OK) {
429 ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
430 __FUNCTION__, cameraId, ret);
431 return ACAMERA_ERROR_INVALID_PARAMETER;
432 }
433 std::unique_ptr<ACameraMetadata> chars(rawChars);
434 rawChars = nullptr;
435
436 ACameraDevice* device = new ACameraDevice(cameraId, callback, std::move(chars));
437
438 sp<ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
439 if (cs == nullptr) {
440 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
441 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
442 }
443
444 int id = atoi(cameraId);
445 sp<ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
446 sp<ICameraDeviceUser> deviceRemote;
447 // No way to get package name from native.
448 // Send a zero length package name and let camera service figure it out from UID
449 status_t serviceRet = cs->connectDevice(
450 callbacks, id, String16(""),
451 ICameraService::USE_CALLING_UID, /*out*/deviceRemote);
452
453 if (serviceRet != OK) {
454 ALOGE("%s: connect camera device failed! err %d", __FUNCTION__, serviceRet);
455 // TODO: generate better error message here
456 delete device;
457 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
458 }
459 if (deviceRemote == nullptr) {
460 ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
461 delete device;
462 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
463 }
464 device->setRemoteDevice(deviceRemote);
465 *outDevice = device;
466 return ACAMERA_OK;
467}
468
469ACameraManager::~ACameraManager() {
470 Mutex::Autolock _l(mLock);
471 if (mCachedCameraIdList.numCameras != kCameraIdListNotInit) {
472 for (int i = 0; i < mCachedCameraIdList.numCameras; i++) {
473 delete[] mCachedCameraIdList.cameraIds[i];
474 }
475 delete[] mCachedCameraIdList.cameraIds;
476 }
477}
478