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             if (*this == other) return false;
140             if (mContext != other.mContext) return mContext < other.mContext;
141             if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
142             if (mAccessPriorityChanged != other.mAccessPriorityChanged)
143                     return mAccessPriorityChanged < other.mAccessPriorityChanged;
144             if (mPhysicalCamAvailable != other.mPhysicalCamAvailable)
145                     return mPhysicalCamAvailable < other.mPhysicalCamAvailable;
146             if (mPhysicalCamUnavailable != other.mPhysicalCamUnavailable)
147                     return mPhysicalCamUnavailable < other.mPhysicalCamUnavailable;
148             return mUnavailable < other.mUnavailable;
149         }
150         bool operator > (const Callback& other) const {
151             return (*this != other && !(*this < other));
152         }
153         ACameraManager_AvailabilityCallback mAvailable;
154         ACameraManager_AvailabilityCallback mUnavailable;
155         ACameraManager_AccessPrioritiesChangedCallback mAccessPriorityChanged;
156         ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamAvailable;
157         ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamUnavailable;
158         void*                               mContext;
159     };
160 
161     android::Condition mCallbacksCond;
162     size_t mPendingCallbackCnt = 0;
163     void onCallbackCalled();
164     void drainPendingCallbacksLocked();
165 
166     std::set<Callback> mCallbacks;
167 
168     // definition of handler and message
169     enum {
170         kWhatSendSingleCallback,
171         kWhatSendSinglePhysicalCameraCallback,
172     };
173     static const char* kCameraIdKey;
174     static const char* kPhysicalCameraIdKey;
175     static const char* kCallbackFpKey;
176     static const char* kContextKey;
177     static const nsecs_t kCallbackDrainTimeout;
178     class CallbackHandler : public AHandler {
179       public:
CallbackHandler(wp<CameraManagerGlobal> parent)180         CallbackHandler(wp<CameraManagerGlobal> parent) : mParent(parent) {}
181         void onMessageReceived(const sp<AMessage> &msg) override;
182       private:
183         wp<CameraManagerGlobal> mParent;
184         void notifyParent();
185         void onMessageReceivedInternal(const sp<AMessage> &msg);
186     };
187     sp<CallbackHandler> mHandler;
188     sp<ALooper>         mCbLooper; // Looper thread where callbacks actually happen on
189 
190     void onStatusChanged(const CameraStatusAndId &statusAndId);
191     void onStatusChangedLocked(const CameraStatusAndId &statusAndId);
192     void onStatusChanged(const PhysicalCameraStatusAndId &statusAndId);
193     void onStatusChangedLocked(const PhysicalCameraStatusAndId &statusAndId);
194     bool setupVendorTags();
195 
196     // Utils for status
197     static bool validStatus(CameraDeviceStatus status);
198     static bool isStatusAvailable(CameraDeviceStatus status);
199 
200     // The sort logic must match the logic in
201     // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds
202     struct CameraIdComparator {
operatorCameraIdComparator203         bool operator()(const hidl_string& a, const hidl_string& b) const {
204             uint32_t aUint = 0, bUint = 0;
205             bool aIsUint = base::ParseUint(a.c_str(), &aUint);
206             bool bIsUint = base::ParseUint(b.c_str(), &bUint);
207 
208             // Uint device IDs first
209             if (aIsUint && bIsUint) {
210                 return aUint < bUint;
211             } else if (aIsUint) {
212                 return true;
213             } else if (bIsUint) {
214                 return false;
215             }
216             // Simple string compare if both id are not uint
217             return a < b;
218         }
219     };
220 
221     struct CameraStatus {
222       private:
223         CameraDeviceStatus status = CameraDeviceStatus::STATUS_NOT_PRESENT;
224         mutable std::mutex mLock;
225         std::set<hidl_string> unavailablePhysicalIds;
226       public:
CameraStatusCameraStatus227         CameraStatus(CameraDeviceStatus st): status(st) { };
228         CameraStatus() = default;
229 
230         bool addUnavailablePhysicalId(const hidl_string& physicalCameraId);
231         bool removeUnavailablePhysicalId(const hidl_string& physicalCameraId);
232         CameraDeviceStatus getStatus();
233         void updateStatus(CameraDeviceStatus newStatus);
234         std::set<hidl_string> getUnavailablePhysicalIds();
235     };
236 
237     template <class T>
238     void registerAvailCallback(const T *callback);
239 
240     // Map camera_id -> status
241     std::map<hidl_string, CameraStatus, CameraIdComparator> mDeviceStatusMap;
242 
243     // For the singleton instance
244     static Mutex sLock;
245     static CameraManagerGlobal* sInstance;
CameraManagerGlobal()246     CameraManagerGlobal() {};
247     ~CameraManagerGlobal();
248 };
249 
250 } // namespace acam;
251 } // namespace android;
252 
253 /**
254  * ACameraManager opaque struct definition
255  * Leave outside of android namespace because it's NDK struct
256  */
257 struct ACameraManager {
ACameraManagerACameraManager258     ACameraManager() :
259             mGlobalManager(&(android::acam::CameraManagerGlobal::getInstance())) {}
260     ~ACameraManager();
261     camera_status_t getCameraIdList(ACameraIdList** cameraIdList);
262     static void     deleteCameraIdList(ACameraIdList* cameraIdList);
263 
264     camera_status_t getCameraCharacteristics(
265             const char* cameraId, android::sp<ACameraMetadata>* characteristics);
266 
267     camera_status_t openCamera(const char* cameraId,
268                                ACameraDevice_StateCallbacks* callback,
269                                /*out*/ACameraDevice** device);
270     camera_status_t getTagFromName(const char *cameraId, const char *name, uint32_t *tag);
271 
272   private:
273     enum {
274         kCameraIdListNotInit = -1
275     };
276     android::Mutex         mLock;
277     android::sp<android::acam::CameraManagerGlobal> mGlobalManager;
278 };
279 
280 #endif //_ACAMERA_MANAGER_H
281