• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 #ifndef _ACAMERA_MANAGER_H
18 #define _ACAMERA_MANAGER_H
19 
20 #include <camera/NdkCameraManager.h>
21 
22 #include <android-base/parseint.h>
23 #include <android/frameworks/cameraservice/service/2.0/ICameraService.h>
24 #include <android/frameworks/cameraservice/service/2.1/ICameraService.h>
25 #include <android/frameworks/cameraservice/service/2.2/ICameraService.h>
26 #include <android/frameworks/cameraservice/service/2.1/ICameraServiceListener.h>
27 
28 #include <CameraMetadata.h>
29 #include <utils/StrongPointer.h>
30 #include <utils/Mutex.h>
31 
32 #include <media/stagefright/foundation/ALooper.h>
33 #include <media/stagefright/foundation/AHandler.h>
34 #include <media/stagefright/foundation/AMessage.h>
35 
36 #include <set>
37 #include <map>
38 
39 namespace android {
40 namespace acam {
41 
42 using ICameraService = frameworks::cameraservice::service::V2_2::ICameraService;
43 using CameraDeviceStatus = frameworks::cameraservice::service::V2_0::CameraDeviceStatus;
44 using ICameraServiceListener = frameworks::cameraservice::service::V2_1::ICameraServiceListener;
45 using PhysicalCameraStatusAndId = frameworks::cameraservice::service::V2_1::PhysicalCameraStatusAndId;
46 using CameraStatusAndId = frameworks::cameraservice::service::V2_0::CameraStatusAndId;
47 using Status = frameworks::cameraservice::common::V2_0::Status;
48 using VendorTagSection = frameworks::cameraservice::common::V2_0::VendorTagSection;
49 using VendorTag = frameworks::cameraservice::common::V2_0::VendorTag;
50 using IBase = android::hidl::base::V1_0::IBase;
51 using android::hardware::hidl_string;
52 using hardware::Void;
53 
54 /**
55  * Per-process singleton instance of CameraManger. Shared by all ACameraManager
56  * instances. Created when first ACameraManager is created and destroyed when
57  * all ACameraManager instances are deleted.
58  *
59  * TODO: maybe CameraManagerGlobal is better suited in libcameraclient?
60  */
61 class CameraManagerGlobal final : public RefBase {
62   public:
63     static CameraManagerGlobal& getInstance();
64     sp<ICameraService> getCameraService();
65 
66     void registerAvailabilityCallback(
67             const ACameraManager_AvailabilityCallbacks *callback);
68     void unregisterAvailabilityCallback(
69             const ACameraManager_AvailabilityCallbacks *callback);
70 
71     void registerExtendedAvailabilityCallback(
72             const ACameraManager_ExtendedAvailabilityCallbacks* callback);
73     void unregisterExtendedAvailabilityCallback(
74             const ACameraManager_ExtendedAvailabilityCallbacks* callback);
75 
76     /**
77      * Return camera IDs that support camera2
78      */
79     void getCameraIdList(std::vector<hidl_string> *cameraIds);
80 
81   private:
82     sp<ICameraService> mCameraService;
83     const int          kCameraServicePollDelay = 500000; // 0.5s
84     Mutex              mLock;
85     class DeathNotifier : public android::hardware::hidl_death_recipient {
86       public:
DeathNotifier(CameraManagerGlobal * cm)87         explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {}
88       protected:
89         // IBinder::DeathRecipient implementation
90         virtual void serviceDied(uint64_t cookie, const wp<IBase> &who);
91       private:
92         const wp<CameraManagerGlobal> mCameraManager;
93     };
94     sp<DeathNotifier> mDeathNotifier;
95 
96     class CameraServiceListener final : public ICameraServiceListener {
97       public:
CameraServiceListener(CameraManagerGlobal * cm)98         explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {}
99         android::hardware::Return<void> onStatusChanged(
100             const CameraStatusAndId &statusAndId) override;
101         android::hardware::Return<void> onPhysicalCameraStatusChanged(
102             const PhysicalCameraStatusAndId &statusAndId) override;
103 
104       private:
105         const wp<CameraManagerGlobal> mCameraManager;
106     };
107     sp<CameraServiceListener> mCameraServiceListener;
108 
109     // Wrapper of ACameraManager_AvailabilityCallbacks so we can store it in std::set
110     struct Callback {
CallbackCallback111         explicit Callback(const ACameraManager_AvailabilityCallbacks *callback) :
112             mAvailable(callback->onCameraAvailable),
113             mUnavailable(callback->onCameraUnavailable),
114             mAccessPriorityChanged(nullptr),
115             mPhysicalCamAvailable(nullptr),
116             mPhysicalCamUnavailable(nullptr),
117             mContext(callback->context) {}
118 
CallbackCallback119         explicit Callback(const ACameraManager_ExtendedAvailabilityCallbacks *callback) :
120             mAvailable(callback->availabilityCallbacks.onCameraAvailable),
121             mUnavailable(callback->availabilityCallbacks.onCameraUnavailable),
122             mAccessPriorityChanged(callback->onCameraAccessPrioritiesChanged),
123             mPhysicalCamAvailable(callback->onPhysicalCameraAvailable),
124             mPhysicalCamUnavailable(callback->onPhysicalCameraUnavailable),
125             mContext(callback->availabilityCallbacks.context) {}
126 
127         bool operator == (const Callback& other) const {
128             return (mAvailable == other.mAvailable &&
129                     mUnavailable == other.mUnavailable &&
130                     mAccessPriorityChanged == other.mAccessPriorityChanged &&
131                     mPhysicalCamAvailable == other.mPhysicalCamAvailable &&
132                     mPhysicalCamUnavailable == other.mPhysicalCamUnavailable &&
133                     mContext == other.mContext);
134         }
135         bool operator != (const Callback& other) const {
136             return !(*this == other);
137         }
138         bool operator < (const Callback& other) const {
139 #pragma GCC diagnostic push
140 #pragma GCC diagnostic ignored "-Wordered-compare-function-pointers"
141             if (*this == other) return false;
142             if (mContext != other.mContext) return mContext < other.mContext;
143             if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
144             if (mAccessPriorityChanged != other.mAccessPriorityChanged)
145                     return mAccessPriorityChanged < other.mAccessPriorityChanged;
146             if (mPhysicalCamAvailable != other.mPhysicalCamAvailable)
147                     return mPhysicalCamAvailable < other.mPhysicalCamAvailable;
148             if (mPhysicalCamUnavailable != other.mPhysicalCamUnavailable)
149                     return mPhysicalCamUnavailable < other.mPhysicalCamUnavailable;
150             return mUnavailable < other.mUnavailable;
151 #pragma GCC diagnostic pop
152         }
153         bool operator > (const Callback& other) const {
154             return (*this != other && !(*this < other));
155         }
156         ACameraManager_AvailabilityCallback mAvailable;
157         ACameraManager_AvailabilityCallback mUnavailable;
158         ACameraManager_AccessPrioritiesChangedCallback mAccessPriorityChanged;
159         ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamAvailable;
160         ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamUnavailable;
161         void*                               mContext;
162     };
163 
164     android::Condition mCallbacksCond;
165     size_t mPendingCallbackCnt = 0;
166     void onCallbackCalled();
167     void drainPendingCallbacksLocked();
168 
169     std::set<Callback> mCallbacks;
170 
171     // definition of handler and message
172     enum {
173         kWhatSendSingleCallback,
174         kWhatSendSinglePhysicalCameraCallback,
175     };
176     static const char* kCameraIdKey;
177     static const char* kPhysicalCameraIdKey;
178     static const char* kCallbackFpKey;
179     static const char* kContextKey;
180     static const nsecs_t kCallbackDrainTimeout;
181     class CallbackHandler : public AHandler {
182       public:
CallbackHandler(wp<CameraManagerGlobal> parent)183         CallbackHandler(wp<CameraManagerGlobal> parent) : mParent(parent) {}
184         void onMessageReceived(const sp<AMessage> &msg) override;
185       private:
186         wp<CameraManagerGlobal> mParent;
187         void notifyParent();
188         void onMessageReceivedInternal(const sp<AMessage> &msg);
189     };
190     sp<CallbackHandler> mHandler;
191     sp<ALooper>         mCbLooper; // Looper thread where callbacks actually happen on
192 
193     void onStatusChanged(const CameraStatusAndId &statusAndId);
194     void onStatusChangedLocked(const CameraStatusAndId &statusAndId);
195     void onStatusChanged(const PhysicalCameraStatusAndId &statusAndId);
196     void onStatusChangedLocked(const PhysicalCameraStatusAndId &statusAndId);
197     bool setupVendorTags();
198 
199     // Utils for status
200     static bool validStatus(CameraDeviceStatus status);
201     static bool isStatusAvailable(CameraDeviceStatus status);
202 
203     // The sort logic must match the logic in
204     // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds
205     struct CameraIdComparator {
operatorCameraIdComparator206         bool operator()(const hidl_string& a, const hidl_string& b) const {
207             uint32_t aUint = 0, bUint = 0;
208             bool aIsUint = base::ParseUint(a.c_str(), &aUint);
209             bool bIsUint = base::ParseUint(b.c_str(), &bUint);
210 
211             // Uint device IDs first
212             if (aIsUint && bIsUint) {
213                 return aUint < bUint;
214             } else if (aIsUint) {
215                 return true;
216             } else if (bIsUint) {
217                 return false;
218             }
219             // Simple string compare if both id are not uint
220             return a < b;
221         }
222     };
223 
224     struct CameraStatus {
225       private:
226         CameraDeviceStatus status = CameraDeviceStatus::STATUS_NOT_PRESENT;
227         mutable std::mutex mLock;
228         std::set<hidl_string> unavailablePhysicalIds;
229       public:
CameraStatusCameraStatus230         CameraStatus(CameraDeviceStatus st): status(st) { };
231         CameraStatus() = default;
232 
233         bool addUnavailablePhysicalId(const hidl_string& physicalCameraId);
234         bool removeUnavailablePhysicalId(const hidl_string& physicalCameraId);
235         CameraDeviceStatus getStatus();
236         void updateStatus(CameraDeviceStatus newStatus);
237         std::set<hidl_string> getUnavailablePhysicalIds();
238     };
239 
240     template <class T>
241     void registerAvailCallback(const T *callback);
242 
243     // Map camera_id -> status
244     std::map<hidl_string, CameraStatus, CameraIdComparator> mDeviceStatusMap;
245 
246     // For the singleton instance
247     static Mutex sLock;
248     static CameraManagerGlobal* sInstance;
CameraManagerGlobal()249     CameraManagerGlobal() {};
250     ~CameraManagerGlobal();
251 };
252 
253 } // namespace acam;
254 } // namespace android;
255 
256 /**
257  * ACameraManager opaque struct definition
258  * Leave outside of android namespace because it's NDK struct
259  */
260 struct ACameraManager {
ACameraManagerACameraManager261     ACameraManager() :
262             mGlobalManager(&(android::acam::CameraManagerGlobal::getInstance())) {}
263     ~ACameraManager();
264     camera_status_t getCameraIdList(ACameraIdList** cameraIdList);
265     static void     deleteCameraIdList(ACameraIdList* cameraIdList);
266 
267     camera_status_t getCameraCharacteristics(
268             const char* cameraId, android::sp<ACameraMetadata>* characteristics);
269 
270     camera_status_t openCamera(const char* cameraId,
271                                ACameraDevice_StateCallbacks* callback,
272                                /*out*/ACameraDevice** device);
273     camera_status_t getTagFromName(const char *cameraId, const char *name, uint32_t *tag);
274 
275   private:
276     enum {
277         kCameraIdListNotInit = -1
278     };
279     android::Mutex         mLock;
280     android::sp<android::acam::CameraManagerGlobal> mGlobalManager;
281 };
282 
283 #endif //_ACAMERA_MANAGER_H
284