xref: /aosp_15_r20/frameworks/av/services/camera/virtualcamera/VirtualCameraProvider.cc (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
2  * Copyright 2023 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 // #define LOG_NDEBUG 0
18 #define LOG_TAG "VirtualCameraProvider"
19 #include "VirtualCameraProvider.h"
20 
21 #include <atomic>
22 #include <memory>
23 #include <mutex>
24 #include <tuple>
25 #include <utility>
26 
27 #include "VirtualCameraDevice.h"
28 #include "aidl/android/hardware/camera/common/Status.h"
29 #include "log/log.h"
30 #include "util/Util.h"
31 
32 namespace android {
33 namespace companion {
34 namespace virtualcamera {
35 
36 using ::aidl::android::companion::virtualcamera::VirtualCameraConfiguration;
37 using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
38 using ::aidl::android::hardware::camera::common::Status;
39 using ::aidl::android::hardware::camera::common::VendorTagSection;
40 using ::aidl::android::hardware::camera::device::ICameraDevice;
41 using ::aidl::android::hardware::camera::provider::CameraIdAndStreamCombination;
42 using ::aidl::android::hardware::camera::provider::ConcurrentCameraIdCombination;
43 using ::aidl::android::hardware::camera::provider::ICameraProviderCallback;
44 
setCallback(const std::shared_ptr<ICameraProviderCallback> & in_callback)45 ndk::ScopedAStatus VirtualCameraProvider::setCallback(
46     const std::shared_ptr<ICameraProviderCallback>& in_callback) {
47   ALOGV("%s", __func__);
48 
49   if (in_callback == nullptr) {
50     return cameraStatus(Status::ILLEGAL_ARGUMENT);
51   }
52 
53   {
54     const std::lock_guard<std::mutex> lock(mLock);
55     mCameraProviderCallback = in_callback;
56 
57     for (const auto& [cameraName, _] : mCameras) {
58       auto ret = mCameraProviderCallback->cameraDeviceStatusChange(
59           cameraName, CameraDeviceStatus::PRESENT);
60       if (!ret.isOk()) {
61         ALOGE("Failed to announce camera status change: %s",
62               ret.getDescription().c_str());
63       }
64     }
65   }
66   return ndk::ScopedAStatus::ok();
67 }
68 
getVendorTags(std::vector<VendorTagSection> * _aidl_return)69 ndk::ScopedAStatus VirtualCameraProvider::getVendorTags(
70     std::vector<VendorTagSection>* _aidl_return) {
71   ALOGV("%s", __func__);
72 
73   if (_aidl_return == nullptr) {
74     return cameraStatus(Status::ILLEGAL_ARGUMENT);
75   }
76 
77   // No vendor tags supported.
78   _aidl_return->clear();
79   return ndk::ScopedAStatus::ok();
80 }
81 
getCameraIdList(std::vector<std::string> * _aidl_return)82 ndk::ScopedAStatus VirtualCameraProvider::getCameraIdList(
83     std::vector<std::string>* _aidl_return) {
84   ALOGV("%s", __func__);
85 
86   if (_aidl_return == nullptr) {
87     return cameraStatus(Status::ILLEGAL_ARGUMENT);
88   }
89 
90   {
91     const std::lock_guard<std::mutex> lock(mLock);
92     _aidl_return->clear();
93     _aidl_return->reserve(mCameras.size());
94     for (const auto& [cameraName, _] : mCameras) {
95       _aidl_return->emplace_back(cameraName);
96     }
97   }
98   return ndk::ScopedAStatus::ok();
99 }
100 
getCameraDeviceInterface(const std::string & in_cameraDeviceName,std::shared_ptr<ICameraDevice> * _aidl_return)101 ndk::ScopedAStatus VirtualCameraProvider::getCameraDeviceInterface(
102     const std::string& in_cameraDeviceName,
103     std::shared_ptr<ICameraDevice>* _aidl_return) {
104   ALOGV("%s cameraDeviceName %s", __func__, in_cameraDeviceName.c_str());
105 
106   if (_aidl_return == nullptr) {
107     return cameraStatus(Status::ILLEGAL_ARGUMENT);
108   }
109 
110   {
111     const std::lock_guard<std::mutex> lock(mLock);
112     const auto it = mCameras.find(in_cameraDeviceName);
113     *_aidl_return = (it == mCameras.end()) ? nullptr : it->second;
114   }
115 
116   return ndk::ScopedAStatus::ok();
117 }
118 
notifyDeviceStateChange(int64_t in_deviceState)119 ndk::ScopedAStatus VirtualCameraProvider::notifyDeviceStateChange(
120     int64_t in_deviceState) {
121   ALOGV("%s", __func__);
122   (void)in_deviceState;
123   return ndk::ScopedAStatus::ok();
124 }
125 
getConcurrentCameraIds(std::vector<ConcurrentCameraIdCombination> * _aidl_return)126 ndk::ScopedAStatus VirtualCameraProvider::getConcurrentCameraIds(
127     std::vector<ConcurrentCameraIdCombination>* _aidl_return) {
128   ALOGV("%s", __func__);
129   if (_aidl_return == nullptr) {
130     return cameraStatus(Status::ILLEGAL_ARGUMENT);
131   }
132 
133   // No support for any concurrent combination.
134   _aidl_return->clear();
135   return ndk::ScopedAStatus::ok();
136 }
137 
isConcurrentStreamCombinationSupported(const std::vector<CameraIdAndStreamCombination> & in_configs,bool * _aidl_return)138 ndk::ScopedAStatus VirtualCameraProvider::isConcurrentStreamCombinationSupported(
139     const std::vector<CameraIdAndStreamCombination>& in_configs,
140     bool* _aidl_return) {
141   ALOGV("%s", __func__);
142   (void)in_configs;
143   if (_aidl_return == nullptr) {
144     return cameraStatus(Status::ILLEGAL_ARGUMENT);
145   }
146 
147   // No support for any stream combination at the moment.
148   *_aidl_return = false;
149   return ndk::ScopedAStatus::ok();
150 }
151 
createCamera(const VirtualCameraConfiguration & configuration,const std::string & cameraId,const int32_t deviceId)152 std::shared_ptr<VirtualCameraDevice> VirtualCameraProvider::createCamera(
153     const VirtualCameraConfiguration& configuration,
154     const std::string& cameraId, const int32_t deviceId) {
155   if (cameraId.empty()) {
156     ALOGE("%s: Cannot create camera with empty cameraId", __func__);
157     return nullptr;
158   }
159 
160   auto camera = ndk::SharedRefBase::make<VirtualCameraDevice>(
161       cameraId, configuration, deviceId);
162   std::shared_ptr<ICameraProviderCallback> callback;
163   {
164     const std::lock_guard<std::mutex> lock(mLock);
165     if (mCameras.find(camera->getCameraName()) != mCameras.end()) {
166       ALOGE("Camera with identical name already exists.");
167       return nullptr;
168     }
169     mCameras.emplace(std::piecewise_construct,
170                      std::forward_as_tuple(camera->getCameraName()),
171                      std::forward_as_tuple(camera));
172     callback = mCameraProviderCallback;
173   }
174 
175   if (callback != nullptr) {
176     auto ret = callback->cameraDeviceStatusChange(camera->getCameraName(),
177                                                   CameraDeviceStatus::PRESENT);
178     if (!ret.isOk()) {
179       ALOGE("Failed to announce camera %s status change (PRESENT): %s",
180             camera->getCameraName().c_str(), ret.getDescription().c_str());
181     }
182   }
183   return camera;
184 }
185 
getCamera(const std::string & cameraName)186 std::shared_ptr<VirtualCameraDevice> VirtualCameraProvider::getCamera(
187     const std::string& cameraName) {
188   const std::lock_guard<std::mutex> lock(mLock);
189   auto it = mCameras.find(cameraName);
190   return it == mCameras.end() ? nullptr : it->second;
191 }
192 
removeCamera(const std::string & name)193 bool VirtualCameraProvider::removeCamera(const std::string& name) {
194   std::shared_ptr<ICameraProviderCallback> callback;
195   {
196     const std::lock_guard<std::mutex> lock(mLock);
197     auto it = mCameras.find(name);
198     if (it == mCameras.end()) {
199       ALOGE("Cannot remove camera %s: no such camera", name.c_str());
200       return false;
201     }
202     // TODO(b/301023410) Gracefully shut down camera.
203     mCameras.erase(it);
204     callback = mCameraProviderCallback;
205   }
206 
207   if (callback != nullptr) {
208     auto ret = callback->cameraDeviceStatusChange(
209         name, CameraDeviceStatus::NOT_PRESENT);
210     if (!ret.isOk()) {
211       ALOGE("Failed to announce camera %s status change (NOT_PRESENT): %s",
212             name.c_str(), ret.getDescription().c_str());
213     }
214   }
215 
216   return true;
217 }
218 
219 }  // namespace virtualcamera
220 }  // namespace companion
221 }  // namespace android
222