blob: cb7a4ffd365d5599956b54750c5c14503eccbdc6 [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
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000108 bool setupVendorTags(sp<hardware::ICameraService> &cameraService);
109
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800110 class DeathNotifier : public IBinder::DeathRecipient {
111 public:
Chih-Hung Hsiehd19d9942016-08-29 14:21:14 -0700112 explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800113 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
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800121 class CameraServiceListener final : public hardware::BnCameraServiceListener {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800122 public:
Chih-Hung Hsiehd19d9942016-08-29 14:21:14 -0700123 explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {}
Biswarup Pal37a75182024-01-16 15:53:35 +0000124 virtual binder::Status onStatusChanged(int32_t status, const std::string& cameraId,
125 int32_t deviceId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800126 virtual binder::Status onPhysicalCameraStatusChanged(int32_t status,
Biswarup Pal37a75182024-01-16 15:53:35 +0000127 const std::string& cameraId, const std::string& physicalCameraId, int32_t deviceId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800128
129 // Torch API not implemented yet
Biswarup Pal37a75182024-01-16 15:53:35 +0000130 virtual binder::Status onTorchStatusChanged(int32_t, const std::string&, int32_t) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800131 return binder::Status::ok();
132 }
Biswarup Pal37a75182024-01-16 15:53:35 +0000133 virtual binder::Status onTorchStrengthLevelChanged(const std::string&, int32_t, int32_t) {
Rucha Katakwar38284522021-11-10 11:25:21 -0800134 return binder::Status::ok();
135 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800136
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800137 virtual binder::Status onCameraAccessPrioritiesChanged();
Biswarup Pal37a75182024-01-16 15:53:35 +0000138 virtual binder::Status onCameraOpened(const std::string&, const std::string&, int32_t) {
Shuzhen Wang695044d2020-03-06 09:02:23 -0800139 return binder::Status::ok();
140 }
Biswarup Pal37a75182024-01-16 15:53:35 +0000141 virtual binder::Status onCameraClosed(const std::string&, int32_t) {
Shuzhen Wang695044d2020-03-06 09:02:23 -0800142 return binder::Status::ok();
143 }
Emilian Peev53722fa2019-02-22 17:47:20 -0800144
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800145 private:
146 const wp<CameraManagerGlobal> mCameraManager;
147 };
148 sp<CameraServiceListener> mCameraServiceListener;
149
150 // Wrapper of ACameraManager_AvailabilityCallbacks so we can store it in std::set
151 struct Callback {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200152 explicit Callback(const DeviceContext& deviceContext,
153 const ACameraManager_AvailabilityCallbacks* callback)
154 : mDeviceContext(deviceContext),
155 mAvailable(callback->onCameraAvailable),
156 mUnavailable(callback->onCameraUnavailable),
157 mAccessPriorityChanged(nullptr),
158 mPhysicalCamAvailable(nullptr),
159 mPhysicalCamUnavailable(nullptr),
160 mContext(callback->context) {}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800161
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200162 explicit Callback(const DeviceContext& deviceContext,
163 const ACameraManager_ExtendedAvailabilityCallbacks* callback)
164 : mDeviceContext(deviceContext),
165 mAvailable(callback->availabilityCallbacks.onCameraAvailable),
166 mUnavailable(callback->availabilityCallbacks.onCameraUnavailable),
167 mAccessPriorityChanged(callback->onCameraAccessPrioritiesChanged),
168 mPhysicalCamAvailable(callback->onPhysicalCameraAvailable),
169 mPhysicalCamUnavailable(callback->onPhysicalCameraUnavailable),
170 mContext(callback->availabilityCallbacks.context) {}
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800171
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800172 bool operator == (const Callback& other) const {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200173 return (mAvailable == other.mAvailable && mUnavailable == other.mUnavailable &&
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800174 mAccessPriorityChanged == other.mAccessPriorityChanged &&
Shuzhen Wang43858162020-01-10 13:42:15 -0800175 mPhysicalCamAvailable == other.mPhysicalCamAvailable &&
176 mPhysicalCamUnavailable == other.mPhysicalCamUnavailable &&
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200177 mContext == other.mContext &&
178 mDeviceContext.deviceId == other.mDeviceContext.deviceId &&
179 mDeviceContext.policy == other.mDeviceContext.policy);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800180 }
181 bool operator != (const Callback& other) const {
182 return !(*this == other);
183 }
184 bool operator < (const Callback& other) const {
Yi Kong8cb642f2021-08-31 14:08:27 +0800185#pragma GCC diagnostic push
186#pragma GCC diagnostic ignored "-Wordered-compare-function-pointers"
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800187 if (*this == other) return false;
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200188 if (mDeviceContext.deviceId != other.mDeviceContext.deviceId) {
189 return mDeviceContext.deviceId < other.mDeviceContext.deviceId;
190 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800191 if (mContext != other.mContext) return mContext < other.mContext;
Shuzhen Wang43858162020-01-10 13:42:15 -0800192 if (mPhysicalCamAvailable != other.mPhysicalCamAvailable) {
193 return mPhysicalCamAvailable < other.mPhysicalCamAvailable;
194 }
195 if (mPhysicalCamUnavailable != other.mPhysicalCamUnavailable) {
196 return mPhysicalCamUnavailable < other.mPhysicalCamUnavailable;
197 }
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800198 if (mAccessPriorityChanged != other.mAccessPriorityChanged) {
199 return mAccessPriorityChanged < other.mAccessPriorityChanged;
200 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800201 if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
202 return mUnavailable < other.mUnavailable;
Yi Kong8cb642f2021-08-31 14:08:27 +0800203#pragma GCC diagnostic pop
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800204 }
205 bool operator > (const Callback& other) const {
206 return (*this != other && !(*this < other));
207 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200208 DeviceContext mDeviceContext;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800209 ACameraManager_AvailabilityCallback mAvailable;
210 ACameraManager_AvailabilityCallback mUnavailable;
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800211 ACameraManager_AccessPrioritiesChangedCallback mAccessPriorityChanged;
Shuzhen Wang43858162020-01-10 13:42:15 -0800212 ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamAvailable;
213 ACameraManager_PhysicalCameraAvailabilityCallback mPhysicalCamUnavailable;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800214 void* mContext;
215 };
Shuzhen Wang7e540682020-04-10 13:30:25 -0700216
217 android::Condition mCallbacksCond;
218 size_t mPendingCallbackCnt = 0;
219 void onCallbackCalled();
220 void drainPendingCallbacksLocked();
221
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800222 std::set<Callback> mCallbacks;
223
224 // definition of handler and message
225 enum {
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800226 kWhatSendSingleCallback,
227 kWhatSendSingleAccessCallback,
Shuzhen Wang43858162020-01-10 13:42:15 -0800228 kWhatSendSinglePhysicalCameraCallback,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800229 };
230 static const char* kCameraIdKey;
Shuzhen Wang43858162020-01-10 13:42:15 -0800231 static const char* kPhysicalCameraIdKey;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800232 static const char* kCallbackFpKey;
233 static const char* kContextKey;
Shuzhen Wang7e540682020-04-10 13:30:25 -0700234 static const nsecs_t kCallbackDrainTimeout;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800235 class CallbackHandler : public AHandler {
236 public:
Shuzhen Wang7e540682020-04-10 13:30:25 -0700237 CallbackHandler(wp<CameraManagerGlobal> parent) : mParent(parent) {}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800238 void onMessageReceived(const sp<AMessage> &msg) override;
Shuzhen Wang7e540682020-04-10 13:30:25 -0700239
240 private:
241 wp<CameraManagerGlobal> mParent;
242 void notifyParent();
243 void onMessageReceivedInternal(const sp<AMessage> &msg);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800244 };
245 sp<CallbackHandler> mHandler;
246 sp<ALooper> mCbLooper; // Looper thread where callbacks actually happen on
247
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700248 sp<hardware::ICameraService> getCameraServiceLocked();
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800249 void onCameraAccessPrioritiesChanged();
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200250 void onStatusChanged(int32_t status, int deviceId, const std::string& cameraId);
251 void onStatusChangedLocked(int32_t status, int deviceId, const std::string& cameraId);
252 void onStatusChanged(int32_t status, int deviceId, const std::string& cameraId,
253 const std::string& physicalCameraId);
254 void onStatusChangedLocked(int32_t status, int deviceId, const std::string& cameraId,
255 const std::string& physicalCameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800256 // Utils for status
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800257 static bool validStatus(int32_t status);
258 static bool isStatusAvailable(int32_t status);
Austin Borger1c1bee02023-06-01 16:51:35 -0700259 bool supportsCamera2ApiLocked(const std::string &cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800260
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700261 struct StatusAndHAL3Support {
Shuzhen Wang43858162020-01-10 13:42:15 -0800262 private:
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700263 int32_t status = hardware::ICameraServiceListener::STATUS_NOT_PRESENT;
Shuzhen Wang43858162020-01-10 13:42:15 -0800264 mutable std::mutex mLock;
Austin Borger1c1bee02023-06-01 16:51:35 -0700265 std::set<std::string> unavailablePhysicalIds;
Shuzhen Wang43858162020-01-10 13:42:15 -0800266 public:
267 const bool supportsHAL3 = false;
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700268 StatusAndHAL3Support(int32_t st, bool HAL3support):
269 status(st), supportsHAL3(HAL3support) { };
270 StatusAndHAL3Support() = default;
Shuzhen Wang43858162020-01-10 13:42:15 -0800271
Austin Borger1c1bee02023-06-01 16:51:35 -0700272 bool addUnavailablePhysicalId(const std::string& physicalCameraId);
273 bool removeUnavailablePhysicalId(const std::string& physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800274 int32_t getStatus();
275 void updateStatus(int32_t newStatus);
Austin Borger1c1bee02023-06-01 16:51:35 -0700276 std::set<std::string> getUnavailablePhysicalIds();
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700277 };
278
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200279 struct DeviceStatusMapKey {
280 int deviceId;
281 std::string cameraId;
282
283 bool operator<(const DeviceStatusMapKey& other) const {
284 if (deviceId != other.deviceId) {
285 return deviceId < other.deviceId;
286 }
287
288 // The sort logic must match the logic in
289 // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds
290 uint32_t cameraIdUint = 0, otherCameraIdUint = 0;
291 bool cameraIdIsUint = base::ParseUint(cameraId.c_str(), &cameraIdUint);
292 bool otherCameraIdIsUint = base::ParseUint(other.cameraId.c_str(), &otherCameraIdUint);
293
294 // Uint device IDs first
295 if (cameraIdIsUint && otherCameraIdIsUint) {
296 return cameraIdUint < otherCameraIdUint;
297 } else if (cameraIdIsUint) {
298 return true;
299 } else if (otherCameraIdIsUint) {
300 return false;
301 }
302 // Simple string compare if both id are not uint
303 return cameraIdIsUint < otherCameraIdIsUint;
304 }
305 };
306
307 std::map<DeviceStatusMapKey, StatusAndHAL3Support> mDeviceStatusMap;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800308
309 // For the singleton instance
310 static Mutex sLock;
Avichal Rakeshf099b232022-10-27 15:44:50 -0700311 static wp<CameraManagerGlobal> sInstance;
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200312 CameraManagerGlobal() {}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800313 ~CameraManagerGlobal();
314};
315
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800316} // namespace acam;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800317} // namespace android;
318
319/**
320 * ACameraManager opaque struct definition
321 * Leave outside of android namespace because it's NDK struct
322 */
323struct ACameraManager {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200324 ACameraManager() : mGlobalManager(android::acam::CameraManagerGlobal::getInstance()) {}
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800325 camera_status_t getCameraIdList(ACameraIdList** cameraIdList);
326 static void deleteCameraIdList(ACameraIdList* cameraIdList);
327
328 camera_status_t getCameraCharacteristics(
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700329 const char* cameraId, android::sp<ACameraMetadata>* characteristics);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800330 camera_status_t openCamera(const char* cameraId,
331 ACameraDevice_StateCallbacks* callback,
332 /*out*/ACameraDevice** device);
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200333 void registerAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback);
334 void unregisterAvailabilityCallback(const ACameraManager_AvailabilityCallbacks* callback);
335 void registerExtendedAvailabilityCallback(
336 const ACameraManager_ExtendedAvailabilityCallbacks* callback);
337 void unregisterExtendedAvailabilityCallback(
338 const ACameraManager_ExtendedAvailabilityCallbacks* callback);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800339
340 private:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800341 enum {
342 kCameraIdListNotInit = -1
343 };
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800344 android::Mutex mLock;
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800345 android::sp<android::acam::CameraManagerGlobal> mGlobalManager;
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200346 const android::acam::DeviceContext mDeviceContext;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800347};
348
349#endif //_ACAMERA_MANAGER_H