1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "dcamera_host.h"
17
18 #include "anonymous_string.h"
19 #include "distributed_hardware_log.h"
20 #include "metadata_utils.h"
21 #include "dcamera.h"
22
23 namespace OHOS {
24 namespace DistributedHardware {
25 OHOS::sptr<DCameraHost> DCameraHost::instance_ = nullptr;
26 DCameraHost::AutoRelease DCameraHost::autoRelease_;
27
CameraHostImplGetInstance(void)28 extern "C" ICameraHost *CameraHostImplGetInstance(void)
29 {
30 return static_cast<ICameraHost *>(DCameraHost::GetInstance().GetRefPtr());
31 }
32
GetInstance()33 OHOS::sptr<DCameraHost> DCameraHost::GetInstance()
34 {
35 if (instance_ == nullptr) {
36 instance_ = new DCameraHost();
37 if (instance_ == nullptr) {
38 DHLOGE("Get distributed camera host instance failed.");
39 return nullptr;
40 }
41 }
42 return instance_;
43 }
44
SetCallback(const sptr<ICameraHostCallback> & callbackObj)45 int32_t DCameraHost::SetCallback(const sptr<ICameraHostCallback> &callbackObj)
46 {
47 if (callbackObj == nullptr) {
48 DHLOGE("DCameraHost::SetCallback, input camera host callback is null.");
49 return CamRetCode::INVALID_ARGUMENT;
50 }
51 dCameraHostCallback_ = callbackObj;
52 return CamRetCode::NO_ERROR;
53 }
54
GetCameraIds(std::vector<std::string> & cameraIds)55 int32_t DCameraHost::GetCameraIds(std::vector<std::string> &cameraIds)
56 {
57 auto iter = dhBaseHashDCamIdMap_.begin();
58 while (iter != dhBaseHashDCamIdMap_.end()) {
59 if (!(iter->second).empty()) {
60 cameraIds.push_back(iter->second);
61 }
62 iter++;
63 }
64 return CamRetCode::NO_ERROR;
65 }
66
GetCameraAbility(const std::string & cameraId,std::vector<uint8_t> & cameraAbility)67 int32_t DCameraHost::GetCameraAbility(const std::string &cameraId, std::vector<uint8_t> &cameraAbility)
68 {
69 if (IsCameraIdInvalid(cameraId)) {
70 DHLOGE("DCameraHost::GetCameraAbility, input cameraId is invalid.");
71 return CamRetCode::INVALID_ARGUMENT;
72 }
73
74 DHLOGE("DCameraHost::GetCameraAbility for cameraId: %s", GetAnonyString(cameraId).c_str());
75
76 auto iter = dCameraDeviceMap_.find(cameraId);
77 std::shared_ptr<CameraAbility> ability = nullptr;
78 int32_t ret = (iter->second)->GetDCameraAbility(ability);
79 if (ret != CamRetCode::NO_ERROR) {
80 DHLOGE("DCameraHost::GetCameraAbility, GetDCameraAbility failed, ret: %d.", ret);
81 return ret;
82 }
83 bool retBool = OHOS::Camera::MetadataUtils::ConvertMetadataToVec(ability, cameraAbility);
84 if (!retBool) {
85 DHLOGE("DCameraHost::GetCameraAbility, ConvertMetadataToVec failed.");
86 return CamRetCode::INVALID_ARGUMENT;
87 }
88
89 do {
90 camera_metadata_item_t item;
91 constexpr uint32_t WIDTH_OFFSET = 1;
92 constexpr uint32_t HEIGHT_OFFSET = 2;
93 constexpr uint32_t UNIT_LENGTH = 3;
94 ret = OHOS::Camera::FindCameraMetadataItem(ability->get(),
95 OHOS_ABILITY_STREAM_AVAILABLE_BASIC_CONFIGURATIONS, &item);
96 DHLOGI("FindCameraMetadataItem item=%u, count=%u, dataType=%u", item.item, item.count, item.data_type);
97 if (ret != CAM_META_SUCCESS) {
98 DHLOGE("Failed to find stream configuration in camera ability with return code %d", ret);
99 break;
100 }
101 if (item.count % UNIT_LENGTH != 0) {
102 DHLOGE("Invalid stream configuration count: %u", item.count);
103 break;
104 }
105 for (uint32_t index = 0; index < item.count; index += UNIT_LENGTH) {
106 int32_t format = item.data.i32[index];
107 int32_t width = item.data.i32[index + WIDTH_OFFSET];
108 int32_t height = item.data.i32[index + HEIGHT_OFFSET];
109 DHLOGD("format: %d, width: %d, height: %d", format, width, height);
110 }
111 } while (0);
112 return CamRetCode::NO_ERROR;
113 }
114
OpenCamera(const std::string & cameraId,const sptr<ICameraDeviceCallback> & callbackObj,sptr<ICameraDevice> & device)115 int32_t DCameraHost::OpenCamera(const std::string &cameraId, const sptr<ICameraDeviceCallback> &callbackObj,
116 sptr<ICameraDevice> &device)
117 {
118 if (IsCameraIdInvalid(cameraId) || callbackObj == nullptr) {
119 DHLOGE("DCameraHost::OpenCamera, open camera id is invalid or camera device callback is null.");
120 return CamRetCode::INVALID_ARGUMENT;
121 }
122
123 DHLOGI("DCameraHost::OpenCamera for cameraId: %s", GetAnonyString(cameraId).c_str());
124
125 auto iter = dCameraDeviceMap_.find(cameraId);
126 if (iter == dCameraDeviceMap_.end()) {
127 DHLOGE("DCameraHost::OpenCamera, dcamera device not found.");
128 return CamRetCode::INSUFFICIENT_RESOURCES;
129 }
130
131 OHOS::sptr<DCameraDevice> dcameraDevice = iter->second;
132 if (dcameraDevice == nullptr) {
133 DHLOGE("DCameraHost::OpenCamera, dcamera device is null.");
134 return INSUFFICIENT_RESOURCES;
135 }
136
137 if (dcameraDevice->IsOpened()) {
138 DHLOGE("DCameraHost::OpenCamera, dcamera device %s already opened.", GetAnonyString(cameraId).c_str());
139 return CamRetCode::CAMERA_BUSY;
140 }
141
142 CamRetCode ret = dcameraDevice->OpenDCamera(callbackObj);
143 if (ret != CamRetCode::NO_ERROR) {
144 DHLOGE("DCameraHost::OpenCamera, open camera failed.");
145 return ret;
146 }
147 device = dcameraDevice;
148
149 DHLOGI("DCameraHost::OpenCamera, open camera %s success.", GetAnonyString(cameraId).c_str());
150 return CamRetCode::NO_ERROR;
151 }
152
SetFlashlight(const std::string & cameraId,bool isEnable)153 int32_t DCameraHost::SetFlashlight(const std::string &cameraId, bool isEnable)
154 {
155 (void)cameraId;
156 (void)isEnable;
157 DHLOGI("DCameraHost::SetFlashlight, distributed camera not support.");
158
159 return CamRetCode::METHOD_NOT_SUPPORTED;
160 }
161
AddDCameraDevice(const DHBase & dhBase,const std::string & abilityInfo,const sptr<IDCameraProviderCallback> & callback)162 DCamRetCode DCameraHost::AddDCameraDevice(const DHBase &dhBase, const std::string &abilityInfo,
163 const sptr<IDCameraProviderCallback> &callback)
164 {
165 if (IsDhBaseInfoInvalid(dhBase)) {
166 DHLOGE("DCameraHost::AddDCameraDevice, devId or dhId is invalid.");
167 return DCamRetCode::INVALID_ARGUMENT;
168 }
169 DHLOGI("DCameraHost::AddDCameraDevice for {devId: %s, dhId: %s}",
170 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
171
172 if (abilityInfo.empty() || abilityInfo.length() > ABILITYINFO_MAX_LENGTH) {
173 DHLOGE("DCameraHost::AddDCameraDevice, input abilityInfo is invalid.");
174 return DCamRetCode::INVALID_ARGUMENT;
175 }
176
177 OHOS::sptr<DCameraDevice> dcameraDevice(new (std::nothrow) DCameraDevice(dhBase, abilityInfo));
178 if (dcameraDevice == nullptr) {
179 DHLOGE("DCameraHost::AddDCameraDevice, create dcamera device failed.");
180 return DCamRetCode::INVALID_ARGUMENT;
181 }
182
183 std::string dCameraId = dcameraDevice->GetDCameraId();
184 dCameraDeviceMap_[dCameraId] = dcameraDevice;
185 DCameraBase dcameraBase(dhBase.deviceId_, dhBase.dhId_);
186 dhBaseHashDCamIdMap_.emplace(dcameraBase, dCameraId);
187 dcameraDevice->SetProviderCallback(callback);
188
189 if (dCameraHostCallback_ != nullptr) {
190 dCameraHostCallback_->OnCameraEvent(dCameraId, CameraEvent::CAMERA_EVENT_DEVICE_ADD);
191 }
192
193 DHLOGI("DCameraHost::AddDCameraDevice, create dcamera device success, dCameraId: %s",
194 GetAnonyString(dCameraId).c_str());
195 return DCamRetCode::SUCCESS;
196 }
197
RemoveDCameraDevice(const DHBase & dhBase)198 DCamRetCode DCameraHost::RemoveDCameraDevice(const DHBase &dhBase)
199 {
200 DHLOGI("DCameraHost::RemoveDCameraDevice for {devId: %s, dhId: %s}",
201 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
202
203 std::string dCameraId = GetCameraIdByDHBase(dhBase);
204 if (dCameraId.empty()) {
205 DHLOGE("DCameraHost::RemoveDCameraDevice, dhBase not exist.");
206 return DCamRetCode::INVALID_ARGUMENT;
207 }
208
209 OHOS::sptr<DCameraDevice> dcameraDevice = GetDCameraDeviceByDHBase(dhBase);
210 if (dcameraDevice != nullptr) {
211 if (dcameraDevice->IsOpened()) {
212 dcameraDevice->Close();
213 }
214 dcameraDevice->SetProviderCallback(nullptr);
215 }
216
217 DCameraBase dcameraBase(dhBase.deviceId_, dhBase.dhId_);
218 dhBaseHashDCamIdMap_.erase(dcameraBase);
219 dCameraDeviceMap_.erase(dCameraId);
220
221 if (dCameraHostCallback_ != nullptr) {
222 dCameraHostCallback_->OnCameraEvent(dCameraId, CameraEvent::CAMERA_EVENT_DEVICE_RMV);
223 }
224
225 DHLOGI("DCameraHost::RemoveDCameraDevice, remove dcamera device success, dCameraId: %s",
226 GetAnonyString(dCameraId).c_str());
227 return DCamRetCode::SUCCESS;
228 }
229
IsCameraIdInvalid(const std::string & cameraId)230 bool DCameraHost::IsCameraIdInvalid(const std::string &cameraId)
231 {
232 if (cameraId.empty() || cameraId.length() > ID_MAX_SIZE) {
233 return true;
234 }
235
236 auto iter = dhBaseHashDCamIdMap_.begin();
237 while (iter != dhBaseHashDCamIdMap_.end()) {
238 if (cameraId == iter->second) {
239 return false;
240 }
241 iter++;
242 }
243 return true;
244 }
245
GetCameraIdByDHBase(const DHBase & dhBase)246 std::string DCameraHost::GetCameraIdByDHBase(const DHBase &dhBase)
247 {
248 DCameraBase dcameraBase(dhBase.deviceId_, dhBase.dhId_);
249 auto iter = dhBaseHashDCamIdMap_.find(dcameraBase);
250 if (iter == dhBaseHashDCamIdMap_.end()) {
251 return "";
252 }
253 return iter->second;
254 }
255
GetDCameraDeviceByDHBase(const DHBase & dhBase)256 OHOS::sptr<DCameraDevice> DCameraHost::GetDCameraDeviceByDHBase(const DHBase &dhBase)
257 {
258 std::string dCameraId = GetCameraIdByDHBase(dhBase);
259 if (dCameraId.empty()) {
260 DHLOGE("DCameraHost::GetDCameraDeviceByDHBase, dhBase not exist.");
261 return nullptr;
262 }
263
264 auto iter = dCameraDeviceMap_.find(dCameraId);
265 if (iter == dCameraDeviceMap_.end()) {
266 DHLOGE("DCameraHost::GetDCameraDeviceByDHBase, dcamera device not found.");
267 return nullptr;
268 }
269 return iter->second;
270 }
271
NotifyDCameraStatus(const DHBase & dhBase,int32_t result)272 void DCameraHost::NotifyDCameraStatus(const DHBase &dhBase, int32_t result)
273 {
274 std::string dCameraId = GetCameraIdByDHBase(dhBase);
275 if (dCameraId.empty()) {
276 DHLOGE("DCameraHost::NotifyDCameraStatus, dhBase not exist.");
277 return;
278 }
279 if (dCameraHostCallback_ != nullptr) {
280 dCameraHostCallback_->OnCameraStatus(dCameraId, CameraStatus::UN_AVAILABLE);
281 }
282 }
283 } // namespace DistributedHardware
284 } // namespace OHOS
285