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