blob: d8bf6b1dbfc2e989415bf75b8a64aec71bfc7034 [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 int kCameraServicePollDelay = 500000; // 0.5s
103 const char* kCameraServiceName = "media.camera";
104 Mutex mLock;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800105
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200106 template <class T>
107 void registerAvailCallback(const DeviceContext& deviceContext, const T* callback);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800108
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800109 class DeathNotifier : public IBinder::DeathRecipient {
110 public:
Chih-Hung Hsiehd19d9942016-08-29 14:21:14 -0700111 explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800112 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
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800120 class CameraServiceListener final : public hardware::BnCameraServiceListener {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800121 public:
Chih-Hung Hsiehd19d9942016-08-29 14:21:14 -0700122 explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {}
Biswarup Pal37a75182024-01-16 15:53:35 +0000123 virtual binder::Status onStatusChanged(int32_t status, const std::string& cameraId,
124 int32_t deviceId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800125 virtual binder::Status onPhysicalCameraStatusChanged(int32_t status,
Biswarup Pal37a75182024-01-16 15:53:35 +0000126 const std::string& cameraId, const std::string& physicalCameraId, int32_t deviceId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800127
128 // Torch API not implemented yet
Biswarup Pal37a75182024-01-16 15:53:35 +0000129 virtual binder::Status onTorchStatusChanged(int32_t, const std::string&, int32_t) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800130 return binder::Status::ok();
131 }
Biswarup Pal37a75182024-01-16 15:53:35 +0000132 virtual binder::Status onTorchStrengthLevelChanged(const std::string&, int32_t, int32_t) {
Rucha Katakwar38284522021-11-10 11:25:21 -0800133 return binder::Status::ok();
134 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800135
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800136 virtual binder::Status onCameraAccessPrioritiesChanged();
Biswarup Pal37a75182024-01-16 15:53:35 +0000137 virtual binder::Status onCameraOpened(const std::string&, const std::string&, int32_t) {
Shuzhen Wang695044d2020-03-06 09:02:23 -0800138 return binder::Status::ok();
139 }
Biswarup Pal37a75182024-01-16 15:53:35 +0000140 virtual binder::Status onCameraClosed(const std::string&, int32_t) {
Shuzhen Wang695044d2020-03-06 09:02:23 -0800141 return binder::Status::ok();
142 }
Emilian Peev53722fa2019-02-22 17:47:20 -0800143
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800144 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 {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200151 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) {}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800160
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200161 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) {}
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800170
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800171 bool operator == (const Callback& other) const {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200172 return (mAvailable == other.mAvailable && mUnavailable == other.mUnavailable &&
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800173 mAccessPriorityChanged == other.mAccessPriorityChanged &&
Shuzhen Wang43858162020-01-10 13:42:15 -0800174 mPhysicalCamAvailable == other.mPhysicalCamAvailable &&
175 mPhysicalCamUnavailable == other.mPhysicalCamUnavailable &&
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200176 mContext == other.mContext &&
177 mDeviceContext.deviceId == other.mDeviceContext.deviceId &&
178 mDeviceContext.policy == other.mDeviceContext.policy);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800179 }
180 bool operator != (const Callback& other) const {
181 return !(*this == other);
182 }
183 bool operator < (const Callback& other) const {
Yi Kong8cb642f2021-08-31 14:08:27 +0800184#pragma GCC diagnostic push
185#pragma GCC diagnostic ignored "-Wordered-compare-function-pointers"
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800186 if (*this == other) return false;
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200187 if (mDeviceContext.deviceId != other.mDeviceContext.deviceId) {
188 return mDeviceContext.deviceId < other.mDeviceContext.deviceId;
189 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800190 if (mContext != other.mContext) return mContext < other.mContext;
Shuzhen Wang43858162020-01-10 13:42:15 -0800191 if (mPhysicalCamAvailable != other.mPhysicalCamAvailable) {
192 return mPhysicalCamAvailable < other.mPhysicalCamAvailable;
193 }
194 if (mPhysicalCamUnavailable != other.mPhysicalCamUnavailable) {
195 return mPhysicalCamUnavailable < other.mPhysicalCamUnavailable;
196 }
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800197 if (mAccessPriorityChanged != other.mAccessPriorityChanged) {
198 return mAccessPriorityChanged < other.mAccessPriorityChanged;
199 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800200 if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
201 return mUnavailable < other.mUnavailable;
Yi Kong8cb642f2021-08-31 14:08:27 +0800202#pragma GCC diagnostic pop
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800203 }
204 bool operator > (const Callback& other) const {
205 return (*this != other && !(*this < other));
206 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200207 DeviceContext mDeviceContext;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800208 ACameraManager_AvailabilityCallback mAvailable;
209 ACameraManager_AvailabilityCallback mUnavailable;
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800210 ACameraManager_AccessPrioritiesChangedCallback mAccessPriorityChanged;
Shuzhen Wang43858162020-01-10 13:42:15 -0800211 ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamAvailable;
212 ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamUnavailable;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800213 void* mContext;
214 };
Shuzhen Wang7e540682020-04-10 13:30:25 -0700215
216 android::Condition mCallbacksCond;
217 size_t mPendingCallbackCnt = 0;
218 void onCallbackCalled();
219 void drainPendingCallbacksLocked();
220
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800221 std::set<Callback> mCallbacks;
222
223 // definition of handler and message
224 enum {
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800225 kWhatSendSingleCallback,
226 kWhatSendSingleAccessCallback,
Shuzhen Wang43858162020-01-10 13:42:15 -0800227 kWhatSendSinglePhysicalCameraCallback,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800228 };
229 static const char* kCameraIdKey;
Shuzhen Wang43858162020-01-10 13:42:15 -0800230 static const char* kPhysicalCameraIdKey;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800231 static const char* kCallbackFpKey;
232 static const char* kContextKey;
Shuzhen Wang7e540682020-04-10 13:30:25 -0700233 static const nsecs_t kCallbackDrainTimeout;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800234 class CallbackHandler : public AHandler {
235 public:
Shuzhen Wang7e540682020-04-10 13:30:25 -0700236 CallbackHandler(wp<CameraManagerGlobal> parent) : mParent(parent) {}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800237 void onMessageReceived(const sp<AMessage> &msg) override;
Shuzhen Wang7e540682020-04-10 13:30:25 -0700238
239 private:
240 wp<CameraManagerGlobal> mParent;
241 void notifyParent();
242 void onMessageReceivedInternal(const sp<AMessage> &msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800243 };
244 sp<CallbackHandler> mHandler;
245 sp<ALooper> mCbLooper; // Looper thread where callbacks actually happen on
246
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700247 sp<hardware::ICameraService> getCameraServiceLocked();
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800248 void onCameraAccessPrioritiesChanged();
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200249 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);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800255 // Utils for status
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800256 static bool validStatus(int32_t status);
257 static bool isStatusAvailable(int32_t status);
Austin Borger1c1bee02023-06-01 16:51:35 -0700258 bool supportsCamera2ApiLocked(const std::string &cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800259
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700260 struct StatusAndHAL3Support {
Shuzhen Wang43858162020-01-10 13:42:15 -0800261 private:
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700262 int32_t status = hardware::ICameraServiceListener::STATUS_NOT_PRESENT;
Shuzhen Wang43858162020-01-10 13:42:15 -0800263 mutable std::mutex mLock;
Austin Borger1c1bee02023-06-01 16:51:35 -0700264 std::set<std::string> unavailablePhysicalIds;
Shuzhen Wang43858162020-01-10 13:42:15 -0800265 public:
266 const bool supportsHAL3 = false;
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700267 StatusAndHAL3Support(int32_t st, bool HAL3support):
268 status(st), supportsHAL3(HAL3support) { };
269 StatusAndHAL3Support() = default;
Shuzhen Wang43858162020-01-10 13:42:15 -0800270
Austin Borger1c1bee02023-06-01 16:51:35 -0700271 bool addUnavailablePhysicalId(const std::string& physicalCameraId);
272 bool removeUnavailablePhysicalId(const std::string& physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800273 int32_t getStatus();
274 void updateStatus(int32_t newStatus);
Austin Borger1c1bee02023-06-01 16:51:35 -0700275 std::set<std::string> getUnavailablePhysicalIds();
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700276 };
277
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200278 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;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800307
308 // For the singleton instance
309 static Mutex sLock;
Avichal Rakeshf099b232022-10-27 15:44:50 -0700310 static wp<CameraManagerGlobal> sInstance;
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200311 CameraManagerGlobal() {}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800312 ~CameraManagerGlobal();
313};
314
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800315} // namespace acam;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800316} // namespace android;
317
318/**
319 * ACameraManager opaque struct definition
320 * Leave outside of android namespace because it's NDK struct
321 */
322struct ACameraManager {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200323 ACameraManager() : mGlobalManager(android::acam::CameraManagerGlobal::getInstance()) {}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800324 camera_status_t getCameraIdList(ACameraIdList** cameraIdList);
325 static void deleteCameraIdList(ACameraIdList* cameraIdList);
326
327 camera_status_t getCameraCharacteristics(
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700328 const char* cameraId, android::sp<ACameraMetadata>* characteristics);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800329 camera_status_t openCamera(const char* cameraId,
330 ACameraDevice_StateCallbacks* callback,
331 /*out*/ACameraDevice** device);
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200332 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);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800338
339 private:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800340 enum {
341 kCameraIdListNotInit = -1
342 };
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800343 android::Mutex mLock;
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800344 android::sp<android::acam::CameraManagerGlobal> mGlobalManager;
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200345 const android::acam::DeviceContext mDeviceContext;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800346};
347
348#endif //_ACAMERA_MANAGER_H