blob: f4124efb7c192d965eaac4d31824c554ec25396d [file] [log] [blame]
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001/*
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
Colin Cross7e8d4ba2017-05-04 16:17:42 -070020#include <camera/NdkCameraManager.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080021
Yin-Chia Yeh03f55752018-03-14 15:28:02 -070022#include <android-base/parseint.h>
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +020023#include <android/companion/virtualnative/IVirtualDeviceManagerNative.h>
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080024#include <android/hardware/ICameraService.h>
25#include <android/hardware/BnCameraServiceListener.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080026#include <camera/CameraMetadata.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080027#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
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080038namespace android {
Jayant Chowdhary6df26072018-11-06 23:55:12 -080039namespace acam {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080040
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +020041enum 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 */
56struct 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
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080071/**
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 *
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -080076 * TODO: maybe CameraManagerGlobal is better suited in libcameraclient?
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080077 */
78class CameraManagerGlobal final : public RefBase {
79 public:
Avichal Rakeshf099b232022-10-27 15:44:50 -070080 static sp<CameraManagerGlobal> getInstance();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080081 sp<hardware::ICameraService> getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080082
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +020083 void registerAvailabilityCallback(const DeviceContext& context,
84 const ACameraManager_AvailabilityCallbacks* callback);
85 void unregisterAvailabilityCallback(const DeviceContext& context,
86 const ACameraManager_AvailabilityCallbacks* callback);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080087
Emilian Peevc6f2ab32019-03-04 11:18:59 -080088 void registerExtendedAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +020089 const DeviceContext& context,
Emilian Peevc6f2ab32019-03-04 11:18:59 -080090 const ACameraManager_ExtendedAvailabilityCallbacks* callback);
91 void unregisterExtendedAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +020092 const DeviceContext& context,
Emilian Peevc6f2ab32019-03-04 11:18:59 -080093 const ACameraManager_ExtendedAvailabilityCallbacks* callback);
94
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -080095 /**
96 * Return camera IDs that support camera2
97 */
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +020098 void getCameraIdList(const DeviceContext& deviceContext, std::vector<std::string>* cameraIds);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -080099
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800100 private:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800101 sp<hardware::ICameraService> mCameraService;
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700102 const char* kCameraServiceName = "media.camera";
103 Mutex mLock;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800104
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200105 template <class T>
106 void registerAvailCallback(const DeviceContext& deviceContext, const T* callback);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800107
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800108 class DeathNotifier : public IBinder::DeathRecipient {
109 public:
Chih-Hung Hsiehd19d9942016-08-29 14:21:14 -0700110 explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800111 protected:
112 // IBinder::DeathRecipient implementation
113 virtual void binderDied(const wp<IBinder>& who);
114 private:
115 const wp<CameraManagerGlobal> mCameraManager;
116 };
117 sp<DeathNotifier> mDeathNotifier;
118
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800119 class CameraServiceListener final : public hardware::BnCameraServiceListener {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800120 public:
Chih-Hung Hsiehd19d9942016-08-29 14:21:14 -0700121 explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {}
Biswarup Pal37a75182024-01-16 15:53:35 +0000122 virtual binder::Status onStatusChanged(int32_t status, const std::string& cameraId,
123 int32_t deviceId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800124 virtual binder::Status onPhysicalCameraStatusChanged(int32_t status,
Biswarup Pal37a75182024-01-16 15:53:35 +0000125 const std::string& cameraId, const std::string& physicalCameraId, int32_t deviceId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800126
127 // Torch API not implemented yet
Biswarup Pal37a75182024-01-16 15:53:35 +0000128 virtual binder::Status onTorchStatusChanged(int32_t, const std::string&, int32_t) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800129 return binder::Status::ok();
130 }
Biswarup Pal37a75182024-01-16 15:53:35 +0000131 virtual binder::Status onTorchStrengthLevelChanged(const std::string&, int32_t, int32_t) {
Rucha Katakwar38284522021-11-10 11:25:21 -0800132 return binder::Status::ok();
133 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800134
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800135 virtual binder::Status onCameraAccessPrioritiesChanged();
Biswarup Pal37a75182024-01-16 15:53:35 +0000136 virtual binder::Status onCameraOpened(const std::string&, const std::string&, int32_t) {
Shuzhen Wang695044d2020-03-06 09:02:23 -0800137 return binder::Status::ok();
138 }
Biswarup Pal37a75182024-01-16 15:53:35 +0000139 virtual binder::Status onCameraClosed(const std::string&, int32_t) {
Shuzhen Wang695044d2020-03-06 09:02:23 -0800140 return binder::Status::ok();
141 }
Emilian Peev53722fa2019-02-22 17:47:20 -0800142
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800143 private:
144 const wp<CameraManagerGlobal> mCameraManager;
145 };
146 sp<CameraServiceListener> mCameraServiceListener;
147
148 // Wrapper of ACameraManager_AvailabilityCallbacks so we can store it in std::set
149 struct Callback {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200150 explicit Callback(const DeviceContext& deviceContext,
151 const ACameraManager_AvailabilityCallbacks* callback)
152 : mDeviceContext(deviceContext),
153 mAvailable(callback->onCameraAvailable),
154 mUnavailable(callback->onCameraUnavailable),
155 mAccessPriorityChanged(nullptr),
156 mPhysicalCamAvailable(nullptr),
157 mPhysicalCamUnavailable(nullptr),
158 mContext(callback->context) {}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800159
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200160 explicit Callback(const DeviceContext& deviceContext,
161 const ACameraManager_ExtendedAvailabilityCallbacks* callback)
162 : mDeviceContext(deviceContext),
163 mAvailable(callback->availabilityCallbacks.onCameraAvailable),
164 mUnavailable(callback->availabilityCallbacks.onCameraUnavailable),
165 mAccessPriorityChanged(callback->onCameraAccessPrioritiesChanged),
166 mPhysicalCamAvailable(callback->onPhysicalCameraAvailable),
167 mPhysicalCamUnavailable(callback->onPhysicalCameraUnavailable),
168 mContext(callback->availabilityCallbacks.context) {}
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800169
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800170 bool operator == (const Callback& other) const {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200171 return (mAvailable == other.mAvailable && mUnavailable == other.mUnavailable &&
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800172 mAccessPriorityChanged == other.mAccessPriorityChanged &&
Shuzhen Wang43858162020-01-10 13:42:15 -0800173 mPhysicalCamAvailable == other.mPhysicalCamAvailable &&
174 mPhysicalCamUnavailable == other.mPhysicalCamUnavailable &&
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200175 mContext == other.mContext &&
176 mDeviceContext.deviceId == other.mDeviceContext.deviceId &&
177 mDeviceContext.policy == other.mDeviceContext.policy);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800178 }
179 bool operator != (const Callback& other) const {
180 return !(*this == other);
181 }
182 bool operator < (const Callback& other) const {
Yi Kong8cb642f2021-08-31 14:08:27 +0800183#pragma GCC diagnostic push
184#pragma GCC diagnostic ignored "-Wordered-compare-function-pointers"
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800185 if (*this == other) return false;
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200186 if (mDeviceContext.deviceId != other.mDeviceContext.deviceId) {
187 return mDeviceContext.deviceId < other.mDeviceContext.deviceId;
188 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800189 if (mContext != other.mContext) return mContext < other.mContext;
Shuzhen Wang43858162020-01-10 13:42:15 -0800190 if (mPhysicalCamAvailable != other.mPhysicalCamAvailable) {
191 return mPhysicalCamAvailable < other.mPhysicalCamAvailable;
192 }
193 if (mPhysicalCamUnavailable != other.mPhysicalCamUnavailable) {
194 return mPhysicalCamUnavailable < other.mPhysicalCamUnavailable;
195 }
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800196 if (mAccessPriorityChanged != other.mAccessPriorityChanged) {
197 return mAccessPriorityChanged < other.mAccessPriorityChanged;
198 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800199 if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
200 return mUnavailable < other.mUnavailable;
Yi Kong8cb642f2021-08-31 14:08:27 +0800201#pragma GCC diagnostic pop
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800202 }
203 bool operator > (const Callback& other) const {
204 return (*this != other && !(*this < other));
205 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200206 DeviceContext mDeviceContext;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800207 ACameraManager_AvailabilityCallback mAvailable;
208 ACameraManager_AvailabilityCallback mUnavailable;
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800209 ACameraManager_AccessPrioritiesChangedCallback mAccessPriorityChanged;
Shuzhen Wang43858162020-01-10 13:42:15 -0800210 ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamAvailable;
211 ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamUnavailable;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800212 void* mContext;
213 };
Shuzhen Wang7e540682020-04-10 13:30:25 -0700214
215 android::Condition mCallbacksCond;
216 size_t mPendingCallbackCnt = 0;
217 void onCallbackCalled();
218 void drainPendingCallbacksLocked();
219
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800220 std::set<Callback> mCallbacks;
221
222 // definition of handler and message
223 enum {
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800224 kWhatSendSingleCallback,
225 kWhatSendSingleAccessCallback,
Shuzhen Wang43858162020-01-10 13:42:15 -0800226 kWhatSendSinglePhysicalCameraCallback,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800227 };
228 static const char* kCameraIdKey;
Shuzhen Wang43858162020-01-10 13:42:15 -0800229 static const char* kPhysicalCameraIdKey;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800230 static const char* kCallbackFpKey;
231 static const char* kContextKey;
Shuzhen Wang7e540682020-04-10 13:30:25 -0700232 static const nsecs_t kCallbackDrainTimeout;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800233 class CallbackHandler : public AHandler {
234 public:
Shuzhen Wang7e540682020-04-10 13:30:25 -0700235 CallbackHandler(wp<CameraManagerGlobal> parent) : mParent(parent) {}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800236 void onMessageReceived(const sp<AMessage> &msg) override;
Shuzhen Wang7e540682020-04-10 13:30:25 -0700237
238 private:
239 wp<CameraManagerGlobal> mParent;
240 void notifyParent();
241 void onMessageReceivedInternal(const sp<AMessage> &msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800242 };
243 sp<CallbackHandler> mHandler;
244 sp<ALooper> mCbLooper; // Looper thread where callbacks actually happen on
245
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700246 sp<hardware::ICameraService> getCameraServiceLocked();
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800247 void onCameraAccessPrioritiesChanged();
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200248 void onStatusChanged(int32_t status, int deviceId, const std::string& cameraId);
249 void onStatusChangedLocked(int32_t status, int deviceId, const std::string& cameraId);
250 void onStatusChanged(int32_t status, int deviceId, const std::string& cameraId,
251 const std::string& physicalCameraId);
252 void onStatusChangedLocked(int32_t status, int deviceId, const std::string& cameraId,
253 const std::string& physicalCameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800254 // Utils for status
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800255 static bool validStatus(int32_t status);
256 static bool isStatusAvailable(int32_t status);
Austin Borger1c1bee02023-06-01 16:51:35 -0700257 bool supportsCamera2ApiLocked(const std::string &cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800258
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700259 struct StatusAndHAL3Support {
Shuzhen Wang43858162020-01-10 13:42:15 -0800260 private:
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700261 int32_t status = hardware::ICameraServiceListener::STATUS_NOT_PRESENT;
Shuzhen Wang43858162020-01-10 13:42:15 -0800262 mutable std::mutex mLock;
Austin Borger1c1bee02023-06-01 16:51:35 -0700263 std::set<std::string> unavailablePhysicalIds;
Shuzhen Wang43858162020-01-10 13:42:15 -0800264 public:
265 const bool supportsHAL3 = false;
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700266 StatusAndHAL3Support(int32_t st, bool HAL3support):
267 status(st), supportsHAL3(HAL3support) { };
268 StatusAndHAL3Support() = default;
Shuzhen Wang43858162020-01-10 13:42:15 -0800269
Austin Borger1c1bee02023-06-01 16:51:35 -0700270 bool addUnavailablePhysicalId(const std::string& physicalCameraId);
271 bool removeUnavailablePhysicalId(const std::string& physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800272 int32_t getStatus();
273 void updateStatus(int32_t newStatus);
Austin Borger1c1bee02023-06-01 16:51:35 -0700274 std::set<std::string> getUnavailablePhysicalIds();
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700275 };
276
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200277 struct DeviceStatusMapKey {
278 int deviceId;
279 std::string cameraId;
280
281 bool operator<(const DeviceStatusMapKey& other) const {
282 if (deviceId != other.deviceId) {
283 return deviceId < other.deviceId;
284 }
285
286 // The sort logic must match the logic in
287 // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds
288 uint32_t cameraIdUint = 0, otherCameraIdUint = 0;
289 bool cameraIdIsUint = base::ParseUint(cameraId.c_str(), &cameraIdUint);
290 bool otherCameraIdIsUint = base::ParseUint(other.cameraId.c_str(), &otherCameraIdUint);
291
292 // Uint device IDs first
293 if (cameraIdIsUint && otherCameraIdIsUint) {
294 return cameraIdUint < otherCameraIdUint;
295 } else if (cameraIdIsUint) {
296 return true;
297 } else if (otherCameraIdIsUint) {
298 return false;
299 }
300 // Simple string compare if both id are not uint
301 return cameraIdIsUint < otherCameraIdIsUint;
302 }
303 };
304
305 std::map<DeviceStatusMapKey, StatusAndHAL3Support> mDeviceStatusMap;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800306
307 // For the singleton instance
308 static Mutex sLock;
Avichal Rakeshf099b232022-10-27 15:44:50 -0700309 static wp<CameraManagerGlobal> sInstance;
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200310 CameraManagerGlobal() {}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800311 ~CameraManagerGlobal();
312};
313
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800314} // namespace acam;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800315} // namespace android;
316
317/**
318 * ACameraManager opaque struct definition
319 * Leave outside of android namespace because it's NDK struct
320 */
321struct ACameraManager {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200322 ACameraManager() : mGlobalManager(android::acam::CameraManagerGlobal::getInstance()) {}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800323 camera_status_t getCameraIdList(ACameraIdList** cameraIdList);
324 static void deleteCameraIdList(ACameraIdList* cameraIdList);
325
326 camera_status_t getCameraCharacteristics(
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700327 const char* cameraId, android::sp<ACameraMetadata>* characteristics);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800328 camera_status_t openCamera(const char* cameraId,
329 ACameraDevice_StateCallbacks* callback,
330 /*out*/ACameraDevice** device);
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200331 void registerAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback);
332 void unregisterAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback);
333 void registerExtendedAvailabilityCallback(
334 const ACameraManager_ExtendedAvailabilityCallbacks* callback);
335 void unregisterExtendedAvailabilityCallback(
336 const ACameraManager_ExtendedAvailabilityCallbacks* callback);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800337
338 private:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800339 enum {
340 kCameraIdListNotInit = -1
341 };
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800342 android::Mutex mLock;
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800343 android::sp<android::acam::CameraManagerGlobal> mGlobalManager;
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200344 const android::acam::DeviceContext mDeviceContext;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800345};
346
347#endif //_ACAMERA_MANAGER_H