xref: /aosp_15_r20/frameworks/av/camera/ndk/impl/ACameraManager.h (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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 char*                  kCameraServiceName      = "media.camera";
103     Mutex                        mLock;
104 
105     template <class T>
106     void registerAvailCallback(const DeviceContext& deviceContext, const T* callback);
107 
108     bool setupVendorTags(sp<hardware::ICameraService> &cameraService);
109 
110     class DeathNotifier : public IBinder::DeathRecipient {
111       public:
DeathNotifier(CameraManagerGlobal * cm)112         explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {}
113       protected:
114         // IBinder::DeathRecipient implementation
115         virtual void binderDied(const wp<IBinder>& who);
116       private:
117         const wp<CameraManagerGlobal> mCameraManager;
118     };
119     sp<DeathNotifier> mDeathNotifier;
120 
121     class CameraServiceListener final : public hardware::BnCameraServiceListener {
122       public:
CameraServiceListener(CameraManagerGlobal * cm)123         explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {}
124         virtual binder::Status onStatusChanged(int32_t status, const std::string& cameraId,
125                 int32_t deviceId);
126         virtual binder::Status onPhysicalCameraStatusChanged(int32_t status,
127                 const std::string& cameraId, const std::string& physicalCameraId, int32_t deviceId);
128 
129         // Torch API not implemented yet
onTorchStatusChanged(int32_t,const std::string &,int32_t)130         virtual binder::Status onTorchStatusChanged(int32_t, const std::string&, int32_t) {
131             return binder::Status::ok();
132         }
onTorchStrengthLevelChanged(const std::string &,int32_t,int32_t)133         virtual binder::Status onTorchStrengthLevelChanged(const std::string&, int32_t, int32_t) {
134             return binder::Status::ok();
135         }
136 
137         virtual binder::Status onCameraAccessPrioritiesChanged();
onCameraOpened(const std::string &,const std::string &,int32_t)138         virtual binder::Status onCameraOpened(const std::string&, const std::string&, int32_t) {
139             return binder::Status::ok();
140         }
onCameraOpenedInSharedMode(const std::string &,const std::string &,int32_t,bool)141         virtual binder::Status onCameraOpenedInSharedMode(const std::string&, const std::string&,
142                 int32_t, bool)  {
143             return binder::Status::ok();
144         }
onCameraClosed(const std::string &,int32_t)145         virtual binder::Status onCameraClosed(const std::string&, int32_t) {
146             return binder::Status::ok();
147         }
148 
149       private:
150         const wp<CameraManagerGlobal> mCameraManager;
151     };
152     sp<CameraServiceListener> mCameraServiceListener;
153 
154     // Wrapper of ACameraManager_AvailabilityCallbacks so we can store it in std::set
155     struct Callback {
CallbackCallback156         explicit Callback(const DeviceContext& deviceContext,
157                  const ACameraManager_AvailabilityCallbacks* callback)
158             : mDeviceContext(deviceContext),
159               mAvailable(callback->onCameraAvailable),
160               mUnavailable(callback->onCameraUnavailable),
161               mAccessPriorityChanged(nullptr),
162               mPhysicalCamAvailable(nullptr),
163               mPhysicalCamUnavailable(nullptr),
164               mContext(callback->context) {}
165 
CallbackCallback166         explicit Callback(const DeviceContext& deviceContext,
167                  const ACameraManager_ExtendedAvailabilityCallbacks* callback)
168             : mDeviceContext(deviceContext),
169               mAvailable(callback->availabilityCallbacks.onCameraAvailable),
170               mUnavailable(callback->availabilityCallbacks.onCameraUnavailable),
171               mAccessPriorityChanged(callback->onCameraAccessPrioritiesChanged),
172               mPhysicalCamAvailable(callback->onPhysicalCameraAvailable),
173               mPhysicalCamUnavailable(callback->onPhysicalCameraUnavailable),
174               mContext(callback->availabilityCallbacks.context) {}
175 
176         bool operator == (const Callback& other) const {
177             return (mAvailable == other.mAvailable && mUnavailable == other.mUnavailable &&
178                     mAccessPriorityChanged == other.mAccessPriorityChanged &&
179                     mPhysicalCamAvailable == other.mPhysicalCamAvailable &&
180                     mPhysicalCamUnavailable == other.mPhysicalCamUnavailable &&
181                     mContext == other.mContext &&
182                     mDeviceContext.deviceId == other.mDeviceContext.deviceId &&
183                     mDeviceContext.policy == other.mDeviceContext.policy);
184         }
185         bool operator != (const Callback& other) const {
186             return !(*this == other);
187         }
188         bool operator < (const Callback& other) const {
189 #pragma GCC diagnostic push
190 #pragma GCC diagnostic ignored "-Wordered-compare-function-pointers"
191             if (*this == other) return false;
192             if (mDeviceContext.deviceId != other.mDeviceContext.deviceId) {
193                 return mDeviceContext.deviceId < other.mDeviceContext.deviceId;
194             }
195             if (mContext != other.mContext) return mContext < other.mContext;
196             if (mPhysicalCamAvailable != other.mPhysicalCamAvailable) {
197                 return mPhysicalCamAvailable < other.mPhysicalCamAvailable;
198             }
199             if (mPhysicalCamUnavailable != other.mPhysicalCamUnavailable) {
200                 return mPhysicalCamUnavailable < other.mPhysicalCamUnavailable;
201             }
202             if (mAccessPriorityChanged != other.mAccessPriorityChanged) {
203                 return mAccessPriorityChanged < other.mAccessPriorityChanged;
204             }
205             if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
206             return mUnavailable < other.mUnavailable;
207 #pragma GCC diagnostic pop
208         }
209         bool operator > (const Callback& other) const {
210             return (*this != other && !(*this < other));
211         }
212         DeviceContext mDeviceContext;
213         ACameraManager_AvailabilityCallback mAvailable;
214         ACameraManager_AvailabilityCallback mUnavailable;
215         ACameraManager_AccessPrioritiesChangedCallback mAccessPriorityChanged;
216         ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamAvailable;
217         ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamUnavailable;
218         void*                               mContext;
219     };
220 
221     android::Condition mCallbacksCond;
222     size_t mPendingCallbackCnt = 0;
223     void onCallbackCalled();
224     void drainPendingCallbacksLocked();
225 
226     std::set<Callback> mCallbacks;
227 
228     // definition of handler and message
229     enum {
230         kWhatSendSingleCallback,
231         kWhatSendSingleAccessCallback,
232         kWhatSendSinglePhysicalCameraCallback,
233     };
234     static const char* kCameraIdKey;
235     static const char* kPhysicalCameraIdKey;
236     static const char* kCallbackFpKey;
237     static const char* kContextKey;
238     static const nsecs_t kCallbackDrainTimeout;
239     class CallbackHandler : public AHandler {
240       public:
CallbackHandler(wp<CameraManagerGlobal> parent)241         CallbackHandler(wp<CameraManagerGlobal> parent) : mParent(parent) {}
242         void onMessageReceived(const sp<AMessage> &msg) override;
243 
244       private:
245         wp<CameraManagerGlobal> mParent;
246         void notifyParent();
247         void onMessageReceivedInternal(const sp<AMessage> &msg);
248     };
249     sp<CallbackHandler> mHandler;
250     sp<ALooper>         mCbLooper; // Looper thread where callbacks actually happen on
251 
252     sp<hardware::ICameraService> getCameraServiceLocked();
253     void onCameraAccessPrioritiesChanged();
254     void onStatusChanged(int32_t status, int deviceId, const std::string& cameraId);
255     void onStatusChangedLocked(int32_t status, int deviceId, const std::string& cameraId);
256     void onStatusChanged(int32_t status, int deviceId, const std::string& cameraId,
257                          const std::string& physicalCameraId);
258     void onStatusChangedLocked(int32_t status, int deviceId, const std::string& cameraId,
259                                const std::string& physicalCameraId);
260     // Utils for status
261     static bool validStatus(int32_t status);
262     static bool isStatusAvailable(int32_t status);
263     bool supportsCamera2ApiLocked(const std::string &cameraId);
264 
265     struct StatusAndHAL3Support {
266       private:
267         int32_t status = hardware::ICameraServiceListener::STATUS_NOT_PRESENT;
268         mutable std::mutex mLock;
269         std::set<std::string> unavailablePhysicalIds;
270       public:
271         const bool supportsHAL3 = false;
StatusAndHAL3SupportStatusAndHAL3Support272         StatusAndHAL3Support(int32_t st, bool HAL3support):
273                 status(st), supportsHAL3(HAL3support) { };
274         StatusAndHAL3Support() = default;
275 
276         bool addUnavailablePhysicalId(const std::string& physicalCameraId);
277         bool removeUnavailablePhysicalId(const std::string& physicalCameraId);
278         int32_t getStatus();
279         void updateStatus(int32_t newStatus);
280         std::set<std::string> getUnavailablePhysicalIds();
281     };
282 
283     struct DeviceStatusMapKey {
284         int deviceId;
285         std::string cameraId;
286 
287         bool operator<(const DeviceStatusMapKey& other) const {
288             if (deviceId != other.deviceId) {
289                 return deviceId < other.deviceId;
290             }
291 
292             // The sort logic must match the logic in
293             // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds
294             uint32_t cameraIdUint = 0, otherCameraIdUint = 0;
295             bool cameraIdIsUint = base::ParseUint(cameraId.c_str(), &cameraIdUint);
296             bool otherCameraIdIsUint = base::ParseUint(other.cameraId.c_str(), &otherCameraIdUint);
297 
298             // Uint device IDs first
299             if (cameraIdIsUint && otherCameraIdIsUint) {
300                 return cameraIdUint < otherCameraIdUint;
301             } else if (cameraIdIsUint) {
302                 return true;
303             } else if (otherCameraIdIsUint) {
304                 return false;
305             }
306             // Simple string compare if both id are not uint
307             return cameraIdIsUint < otherCameraIdIsUint;
308         }
309     };
310 
311     std::map<DeviceStatusMapKey, StatusAndHAL3Support> mDeviceStatusMap;
312 
313     // For the singleton instance
314     static Mutex sLock;
315     static wp<CameraManagerGlobal> sInstance;
CameraManagerGlobal()316     CameraManagerGlobal() {}
317     ~CameraManagerGlobal();
318 };
319 
320 } // namespace acam;
321 } // namespace android;
322 
323 /**
324  * ACameraManager opaque struct definition
325  * Leave outside of android namespace because it's NDK struct
326  */
327 struct ACameraManager {
ACameraManagerACameraManager328     ACameraManager() : mGlobalManager(android::acam::CameraManagerGlobal::getInstance()) {}
329     camera_status_t getCameraIdList(ACameraIdList** cameraIdList);
330     static void     deleteCameraIdList(ACameraIdList* cameraIdList);
331 
332     camera_status_t getCameraCharacteristics(
333             const char* cameraId, android::sp<ACameraMetadata>* characteristics);
334     camera_status_t openCamera(const char* cameraId, bool sharedMode,
335                                ACameraDevice_StateCallbacks* callback,
336                                /*out*/ACameraDevice** device, /*out*/bool* primaryClient);
337     void registerAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback);
338     void unregisterAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback);
339     void registerExtendedAvailabilityCallback(
340             const ACameraManager_ExtendedAvailabilityCallbacks* callback);
341     void unregisterExtendedAvailabilityCallback(
342             const ACameraManager_ExtendedAvailabilityCallbacks* callback);
343     camera_status_t isCameraDeviceSharingSupported(
344             const char* cameraId, bool* isSharingSupported);
345   private:
346     enum {
347         kCameraIdListNotInit = -1
348     };
349     android::Mutex         mLock;
350     android::sp<android::acam::CameraManagerGlobal> mGlobalManager;
351     const android::acam::DeviceContext mDeviceContext;
352 };
353 
354 #endif //_ACAMERA_MANAGER_H
355