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