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
31namespace android {
32// Static member definitions
33const char* CameraManagerGlobal::kCameraIdKey   = "CameraId";
34const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
35const char* CameraManagerGlobal::kContextKey    = "CallbackContext";
36Mutex                CameraManagerGlobal::sLock;
37CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
38
39CameraManagerGlobal&
40CameraManagerGlobal::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
50CameraManagerGlobal::~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
70static 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
76sp<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
179void 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
195void 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
217void CameraManagerGlobal::unregisterAvailabilityCallback(
218        const ACameraManager_AvailabilityCallbacks *callback) {
219    Mutex::Autolock _l(mLock);
220    Callback cb(callback);
221    mCallbacks.erase(cb);
222}
223
224void 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
244bool 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
256bool 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
265void 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
297binder::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
308void CameraManagerGlobal::onStatusChanged(
309        int32_t status, const String8& cameraId) {
310    Mutex::Autolock _l(mLock);
311    onStatusChangedLocked(status, cameraId);
312}
313
314void 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 */
350camera_status_t
351ACameraManager::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
386void
387ACameraManager::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
401camera_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
432camera_status_t
433ACameraManager::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
510ACameraManager::~ACameraManager() {
511
512}
513