10dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh/* 20dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * Copyright (C) 2015 The Android Open Source Project 30dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * 40dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * Licensed under the Apache License, Version 2.0 (the "License"); 50dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * you may not use this file except in compliance with the License. 60dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * You may obtain a copy of the License at 70dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * 80dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * http://www.apache.org/licenses/LICENSE-2.0 90dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * 100dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * Unless required by applicable law or agreed to in writing, software 110dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * distributed under the License is distributed on an "AS IS" BASIS, 120dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * See the License for the specific language governing permissions and 140dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * limitations under the License. 150dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh */ 160dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 170dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#ifndef _ACAMERA_MANAGER_H 180dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#define _ACAMERA_MANAGER_H 190dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 200dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include "NdkCameraManager.h" 210dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 22d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#include <android/hardware/ICameraService.h> 23d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#include <android/hardware/BnCameraServiceListener.h> 240dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <camera/CameraMetadata.h> 250dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <binder/IServiceManager.h> 260dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <utils/StrongPointer.h> 270dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <utils/Mutex.h> 280dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 290dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <media/stagefright/foundation/ALooper.h> 300dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <media/stagefright/foundation/AHandler.h> 310dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <media/stagefright/foundation/AMessage.h> 320dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 330dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <set> 340dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <map> 350dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 360dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehnamespace android { 370dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 380dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh/** 390dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * Per-process singleton instance of CameraManger. Shared by all ACameraManager 400dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * instances. Created when first ACameraManager is created and destroyed when 410dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * all ACameraManager instances are deleted. 420dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * 43f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala * TODO: maybe CameraManagerGlobal is better suited in libcameraclient? 440dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh */ 450dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehclass CameraManagerGlobal final : public RefBase { 460dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh public: 470dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh static CameraManagerGlobal& getInstance(); 48d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala sp<hardware::ICameraService> getCameraService(); 490dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 500dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh void registerAvailabilityCallback( 510dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh const ACameraManager_AvailabilityCallbacks *callback); 520dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh void unregisterAvailabilityCallback( 530dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh const ACameraManager_AvailabilityCallbacks *callback); 540dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 55f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala /** 56f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala * Return camera IDs that support camera2 57f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala */ 58f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala void getCameraIdList(std::vector<String8> *cameraIds); 59f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala 600dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh private: 61d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala sp<hardware::ICameraService> mCameraService; 620dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh const int kCameraServicePollDelay = 500000; // 0.5s 630dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh const char* kCameraServiceName = "media.camera"; 640dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh Mutex mLock; 650dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 660dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh class DeathNotifier : public IBinder::DeathRecipient { 670dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh public: 68d19d994770a04f02c204affd29985c5aeaa58baaChih-Hung Hsieh explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {} 690dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh protected: 700dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh // IBinder::DeathRecipient implementation 710dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh virtual void binderDied(const wp<IBinder>& who); 720dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh private: 730dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh const wp<CameraManagerGlobal> mCameraManager; 740dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh }; 750dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh sp<DeathNotifier> mDeathNotifier; 760dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 77d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala class CameraServiceListener final : public hardware::BnCameraServiceListener { 780dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh public: 79d19d994770a04f02c204affd29985c5aeaa58baaChih-Hung Hsieh explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {} 80f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala virtual binder::Status onStatusChanged(int32_t status, const String16& cameraId); 810dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 820dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh // Torch API not implemented yet 83d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala virtual binder::Status onTorchStatusChanged(int32_t, const String16&) { 84d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala return binder::Status::ok(); 85d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala } 86d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala 870dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh private: 880dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh const wp<CameraManagerGlobal> mCameraManager; 890dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh }; 900dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh sp<CameraServiceListener> mCameraServiceListener; 910dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 920dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh // Wrapper of ACameraManager_AvailabilityCallbacks so we can store it in std::set 930dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh struct Callback { 94d19d994770a04f02c204affd29985c5aeaa58baaChih-Hung Hsieh explicit Callback(const ACameraManager_AvailabilityCallbacks *callback) : 950dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh mAvailable(callback->onCameraAvailable), 960dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh mUnavailable(callback->onCameraUnavailable), 970dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh mContext(callback->context) {} 980dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 990dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh bool operator == (const Callback& other) const { 1000dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh return (mAvailable == other.mAvailable && 1010dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh mUnavailable == other.mUnavailable && 1020dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh mContext == other.mContext); 1030dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh } 1040dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh bool operator != (const Callback& other) const { 1050dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh return !(*this == other); 1060dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh } 1070dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh bool operator < (const Callback& other) const { 1080dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh if (*this == other) return false; 1090dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh if (mContext != other.mContext) return mContext < other.mContext; 1100dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable; 1110dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh return mUnavailable < other.mUnavailable; 1120dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh } 1130dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh bool operator > (const Callback& other) const { 1140dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh return (*this != other && !(*this < other)); 1150dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh } 1160dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh ACameraManager_AvailabilityCallback mAvailable; 1170dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh ACameraManager_AvailabilityCallback mUnavailable; 1180dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh void* mContext; 1190dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh }; 1200dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh std::set<Callback> mCallbacks; 1210dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 1220dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh // definition of handler and message 1230dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh enum { 1240dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh kWhatSendSingleCallback 1250dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh }; 1260dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh static const char* kCameraIdKey; 1270dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh static const char* kCallbackFpKey; 1280dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh static const char* kContextKey; 1290dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh class CallbackHandler : public AHandler { 1300dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh public: 1310dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh CallbackHandler() {} 1320dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh void onMessageReceived(const sp<AMessage> &msg) override; 1330dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh }; 1340dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh sp<CallbackHandler> mHandler; 1350dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh sp<ALooper> mCbLooper; // Looper thread where callbacks actually happen on 1360dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 137f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala void onStatusChanged(int32_t status, const String8& cameraId); 138f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala void onStatusChangedLocked(int32_t status, const String8& cameraId); 1390dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh // Utils for status 140d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala static bool validStatus(int32_t status); 141d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala static bool isStatusAvailable(int32_t status); 1420dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 1430dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh // Map camera_id -> status 144f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala std::map<String8, int32_t> mDeviceStatusMap; 1450dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 1460dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh // For the singleton instance 1470dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh static Mutex sLock; 1480dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh static CameraManagerGlobal* sInstance; 1490dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh CameraManagerGlobal() {}; 1500dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh ~CameraManagerGlobal(); 1510dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}; 1520dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 1530dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh} // namespace android; 1540dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 1550dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh/** 1560dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * ACameraManager opaque struct definition 1570dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * Leave outside of android namespace because it's NDK struct 1580dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh */ 1590dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehstruct ACameraManager { 1600dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh ACameraManager() : 161d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala mGlobalManager(&(android::CameraManagerGlobal::getInstance())) {} 1620dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh ~ACameraManager(); 1630dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh camera_status_t getCameraIdList(ACameraIdList** cameraIdList); 1640dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh static void deleteCameraIdList(ACameraIdList* cameraIdList); 1650dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 1660dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh camera_status_t getCameraCharacteristics( 1670dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh const char *cameraId, ACameraMetadata **characteristics); 1680dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh camera_status_t openCamera(const char* cameraId, 1690dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh ACameraDevice_StateCallbacks* callback, 1700dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh /*out*/ACameraDevice** device); 1710dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 1720dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh private: 1730dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh enum { 1740dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh kCameraIdListNotInit = -1 1750dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh }; 176d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala android::Mutex mLock; 177d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala android::sp<android::CameraManagerGlobal> mGlobalManager; 1780dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}; 1790dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 1800dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#endif //_ACAMERA_MANAGER_H 181