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 #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/companion/virtualnative/IVirtualDeviceManagerNative.h>
24 #include <android/hardware/ICameraService.h>
25 #include <android/hardware/BnCameraServiceListener.h>
26 #include <camera/CameraMetadata.h>
27 #include <binder/IServiceManager.h>
28 #include <utils/StrongPointer.h>
29 #include <utils/Mutex.h>
30 
31 #include <media/stagefright/foundation/ALooper.h>
32 #include <media/stagefright/foundation/AHandler.h>
33 #include <media/stagefright/foundation/AMessage.h>
34 
35 #include <set>
36 #include <map>
37 
38 namespace android {
39 namespace acam {
40 
41 enum class DevicePolicy {
42   DEVICE_POLICY_DEFAULT =
43     ::android::companion::virtualnative::IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT,
44   DEVICE_POLICY_CUSTOM =
45     ::android::companion::virtualnative::IVirtualDeviceManagerNative::DEVICE_POLICY_CUSTOM
46 };
47 
48 /**
49  * Device context within which are cameras accessed.
50  *
51  * When constructed, the device id is set to id of virtual device corresponding to
52  * caller's UID (or default device id if current app process is not running on virtual device).
53  *
54  * See getDeviceId() in Context.java for more context (no pun intented).
55  */
56 struct DeviceContext {
57     DeviceContext();
58 
59     // Id of virtual device asociated with this context (or DEFAULT_DEVICE_ID = 0 in case
60     // caller UID is not running on virtual device).
61     int deviceId;
62     // Device policy corresponding to VirtualDeviceParams.POLICY_TYPE_CAMERA:
63     //
64     // Can be either:
65     // * (0) DEVICE_POLICY_DEFAULT - virtual devices have access to default device cameras.
66     // * (1) DEVICE_POLICY_CUSTOM - virtual devices do not have access to default device cameras
67     //                              and can only access virtual cameras owned by the same device.
68     DevicePolicy policy;
69 };
70 
71 /**
72  * Per-process singleton instance of CameraManger. Shared by all ACameraManager
73  * instances. Created when first ACameraManager is created and destroyed when
74  * all ACameraManager instances are deleted.
75  *
76  * TODO: maybe CameraManagerGlobal is better suited in libcameraclient?
77  */
78 class CameraManagerGlobal final : public RefBase {
79   public:
80     static sp<CameraManagerGlobal> getInstance();
81     sp<hardware::ICameraService> getCameraService();
82 
83     void registerAvailabilityCallback(const DeviceContext& context,
84                                       const ACameraManager_AvailabilityCallbacks* callback);
85     void unregisterAvailabilityCallback(const DeviceContext& context,
86                                         const ACameraManager_AvailabilityCallbacks* callback);
87 
88     void registerExtendedAvailabilityCallback(
89             const DeviceContext& context,
90             const ACameraManager_ExtendedAvailabilityCallbacks* callback);
91     void unregisterExtendedAvailabilityCallback(
92             const DeviceContext& context,
93             const ACameraManager_ExtendedAvailabilityCallbacks* callback);
94 
95     /**
96      * Return camera IDs that support camera2
97      */
98     void getCameraIdList(const DeviceContext& deviceContext, std::vector<std::string>* cameraIds);
99 
100   private:
101     sp<hardware::ICameraService> mCameraService;
102     const int                    kCameraServicePollDelay = 500000; // 0.5s
103     const char*                  kCameraServiceName      = "media.camera";
104     Mutex                        mLock;
105 
106     template <class T>
107     void registerAvailCallback(const DeviceContext& deviceContext, const T* callback);
108 
109     class DeathNotifier : public IBinder::DeathRecipient {
110       public:
DeathNotifier(CameraManagerGlobal * cm)111         explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {}
112       protected:
113         // IBinder::DeathRecipient implementation
114         virtual void binderDied(const wp<IBinder>& who);
115       private:
116         const wp<CameraManagerGlobal> mCameraManager;
117     };
118     sp<DeathNotifier> mDeathNotifier;
119 
120     class CameraServiceListener final : public hardware::BnCameraServiceListener {
121       public:
CameraServiceListener(CameraManagerGlobal * cm)122         explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {}
123         virtual binder::Status onStatusChanged(int32_t status, const std::string& cameraId,
124                 int32_t deviceId);
125         virtual binder::Status onPhysicalCameraStatusChanged(int32_t status,
126                 const std::string& cameraId, const std::string& physicalCameraId, int32_t deviceId);
127 
128         // Torch API not implemented yet
onTorchStatusChanged(int32_t,const std::string &,int32_t)129         virtual binder::Status onTorchStatusChanged(int32_t, const std::string&, int32_t) {
130             return binder::Status::ok();
131         }
onTorchStrengthLevelChanged(const std::string &,int32_t,int32_t)132         virtual binder::Status onTorchStrengthLevelChanged(const std::string&, int32_t, int32_t) {
133             return binder::Status::ok();
134         }
135 
136         virtual binder::Status onCameraAccessPrioritiesChanged();
onCameraOpened(const std::string &,const std::string &,int32_t)137         virtual binder::Status onCameraOpened(const std::string&, const std::string&, int32_t) {
138             return binder::Status::ok();
139         }
onCameraClosed(const std::string &,int32_t)140         virtual binder::Status onCameraClosed(const std::string&, int32_t) {
141             return binder::Status::ok();
142         }
143 
144       private:
145         const wp<CameraManagerGlobal> mCameraManager;
146     };
147     sp<CameraServiceListener> mCameraServiceListener;
148 
149     // Wrapper of ACameraManager_AvailabilityCallbacks so we can store it in std::set
150     struct Callback {
CallbackCallback151         explicit Callback(const DeviceContext& deviceContext,
152                  const ACameraManager_AvailabilityCallbacks* callback)
153             : mDeviceContext(deviceContext),
154               mAvailable(callback->onCameraAvailable),
155               mUnavailable(callback->onCameraUnavailable),
156               mAccessPriorityChanged(nullptr),
157               mPhysicalCamAvailable(nullptr),
158               mPhysicalCamUnavailable(nullptr),
159               mContext(callback->context) {}
160 
CallbackCallback161         explicit Callback(const DeviceContext& deviceContext,
162                  const ACameraManager_ExtendedAvailabilityCallbacks* callback)
163             : mDeviceContext(deviceContext),
164               mAvailable(callback->availabilityCallbacks.onCameraAvailable),
165               mUnavailable(callback->availabilityCallbacks.onCameraUnavailable),
166               mAccessPriorityChanged(callback->onCameraAccessPrioritiesChanged),
167               mPhysicalCamAvailable(callback->onPhysicalCameraAvailable),
168               mPhysicalCamUnavailable(callback->onPhysicalCameraUnavailable),
169               mContext(callback->availabilityCallbacks.context) {}
170 
171         bool operator == (const Callback& other) const {
172             return (mAvailable == other.mAvailable && mUnavailable == other.mUnavailable &&
173                     mAccessPriorityChanged == other.mAccessPriorityChanged &&
174                     mPhysicalCamAvailable == other.mPhysicalCamAvailable &&
175                     mPhysicalCamUnavailable == other.mPhysicalCamUnavailable &&
176                     mContext == other.mContext &&
177                     mDeviceContext.deviceId == other.mDeviceContext.deviceId &&
178                     mDeviceContext.policy == other.mDeviceContext.policy);
179         }
180         bool operator != (const Callback& other) const {
181             return !(*this == other);
182         }
183         bool operator < (const Callback& other) const {
184 #pragma GCC diagnostic push
185 #pragma GCC diagnostic ignored "-Wordered-compare-function-pointers"
186             if (*this == other) return false;
187             if (mDeviceContext.deviceId != other.mDeviceContext.deviceId) {
188                 return mDeviceContext.deviceId < other.mDeviceContext.deviceId;
189             }
190             if (mContext != other.mContext) return mContext < other.mContext;
191             if (mPhysicalCamAvailable != other.mPhysicalCamAvailable) {
192                 return mPhysicalCamAvailable < other.mPhysicalCamAvailable;
193             }
194             if (mPhysicalCamUnavailable != other.mPhysicalCamUnavailable) {
195                 return mPhysicalCamUnavailable < other.mPhysicalCamUnavailable;
196             }
197             if (mAccessPriorityChanged != other.mAccessPriorityChanged) {
198                 return mAccessPriorityChanged < other.mAccessPriorityChanged;
199             }
200             if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
201             return mUnavailable < other.mUnavailable;
202 #pragma GCC diagnostic pop
203         }
204         bool operator > (const Callback& other) const {
205             return (*this != other && !(*this < other));
206         }
207         DeviceContext mDeviceContext;
208         ACameraManager_AvailabilityCallback mAvailable;
209         ACameraManager_AvailabilityCallback mUnavailable;
210         ACameraManager_AccessPrioritiesChangedCallback mAccessPriorityChanged;
211         ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamAvailable;
212         ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamUnavailable;
213         void*                               mContext;
214     };
215 
216     android::Condition mCallbacksCond;
217     size_t mPendingCallbackCnt = 0;
218     void onCallbackCalled();
219     void drainPendingCallbacksLocked();
220 
221     std::set<Callback> mCallbacks;
222 
223     // definition of handler and message
224     enum {
225         kWhatSendSingleCallback,
226         kWhatSendSingleAccessCallback,
227         kWhatSendSinglePhysicalCameraCallback,
228     };
229     static const char* kCameraIdKey;
230     static const char* kPhysicalCameraIdKey;
231     static const char* kCallbackFpKey;
232     static const char* kContextKey;
233     static const nsecs_t kCallbackDrainTimeout;
234     class CallbackHandler : public AHandler {
235       public:
CallbackHandler(wp<CameraManagerGlobal> parent)236         CallbackHandler(wp<CameraManagerGlobal> parent) : mParent(parent) {}
237         void onMessageReceived(const sp<AMessage> &msg) override;
238 
239       private:
240         wp<CameraManagerGlobal> mParent;
241         void notifyParent();
242         void onMessageReceivedInternal(const sp<AMessage> &msg);
243     };
244     sp<CallbackHandler> mHandler;
245     sp<ALooper>         mCbLooper; // Looper thread where callbacks actually happen on
246 
247     sp<hardware::ICameraService> getCameraServiceLocked();
248     void onCameraAccessPrioritiesChanged();
249     void onStatusChanged(int32_t status, int deviceId, const std::string& cameraId);
250     void onStatusChangedLocked(int32_t status, int deviceId, const std::string& cameraId);
251     void onStatusChanged(int32_t status, int deviceId, const std::string& cameraId,
252                          const std::string& physicalCameraId);
253     void onStatusChangedLocked(int32_t status, int deviceId, const std::string& cameraId,
254                                const std::string& physicalCameraId);
255     // Utils for status
256     static bool validStatus(int32_t status);
257     static bool isStatusAvailable(int32_t status);
258     bool supportsCamera2ApiLocked(const std::string &cameraId);
259 
260     struct StatusAndHAL3Support {
261       private:
262         int32_t status = hardware::ICameraServiceListener::STATUS_NOT_PRESENT;
263         mutable std::mutex mLock;
264         std::set<std::string> unavailablePhysicalIds;
265       public:
266         const bool supportsHAL3 = false;
StatusAndHAL3SupportStatusAndHAL3Support267         StatusAndHAL3Support(int32_t st, bool HAL3support):
268                 status(st), supportsHAL3(HAL3support) { };
269         StatusAndHAL3Support() = default;
270 
271         bool addUnavailablePhysicalId(const std::string& physicalCameraId);
272         bool removeUnavailablePhysicalId(const std::string& physicalCameraId);
273         int32_t getStatus();
274         void updateStatus(int32_t newStatus);
275         std::set<std::string> getUnavailablePhysicalIds();
276     };
277 
278     struct DeviceStatusMapKey {
279         int deviceId;
280         std::string cameraId;
281 
282         bool operator<(const DeviceStatusMapKey& other) const {
283             if (deviceId != other.deviceId) {
284                 return deviceId < other.deviceId;
285             }
286 
287             // The sort logic must match the logic in
288             // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds
289             uint32_t cameraIdUint = 0, otherCameraIdUint = 0;
290             bool cameraIdIsUint = base::ParseUint(cameraId.c_str(), &cameraIdUint);
291             bool otherCameraIdIsUint = base::ParseUint(other.cameraId.c_str(), &otherCameraIdUint);
292 
293             // Uint device IDs first
294             if (cameraIdIsUint && otherCameraIdIsUint) {
295                 return cameraIdUint < otherCameraIdUint;
296             } else if (cameraIdIsUint) {
297                 return true;
298             } else if (otherCameraIdIsUint) {
299                 return false;
300             }
301             // Simple string compare if both id are not uint
302             return cameraIdIsUint < otherCameraIdIsUint;
303         }
304     };
305 
306     std::map<DeviceStatusMapKey, StatusAndHAL3Support> mDeviceStatusMap;
307 
308     // For the singleton instance
309     static Mutex sLock;
310     static wp<CameraManagerGlobal> sInstance;
CameraManagerGlobal()311     CameraManagerGlobal() {}
312     ~CameraManagerGlobal();
313 };
314 
315 } // namespace acam;
316 } // namespace android;
317 
318 /**
319  * ACameraManager opaque struct definition
320  * Leave outside of android namespace because it's NDK struct
321  */
322 struct ACameraManager {
ACameraManagerACameraManager323     ACameraManager() : mGlobalManager(android::acam::CameraManagerGlobal::getInstance()) {}
324     camera_status_t getCameraIdList(ACameraIdList** cameraIdList);
325     static void     deleteCameraIdList(ACameraIdList* cameraIdList);
326 
327     camera_status_t getCameraCharacteristics(
328             const char* cameraId, android::sp<ACameraMetadata>* characteristics);
329     camera_status_t openCamera(const char* cameraId,
330                                ACameraDevice_StateCallbacks* callback,
331                                /*out*/ACameraDevice** device);
332     void registerAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback);
333     void unregisterAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback);
334     void registerExtendedAvailabilityCallback(
335             const ACameraManager_ExtendedAvailabilityCallbacks* callback);
336     void unregisterExtendedAvailabilityCallback(
337             const ACameraManager_ExtendedAvailabilityCallbacks* callback);
338 
339   private:
340     enum {
341         kCameraIdListNotInit = -1
342     };
343     android::Mutex         mLock;
344     android::sp<android::acam::CameraManagerGlobal> mGlobalManager;
345     const android::acam::DeviceContext mDeviceContext;
346 };
347 
348 #endif //_ACAMERA_MANAGER_H
349