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