1 /*
2 * Copyright (c) 2021-2024 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 <cstdlib>
19 #include "iservice_registry.h"
20 #include "iproxy_broker.h"
21 #include "iservmgr_hdi.h"
22
23 #include "anonymous_string.h"
24 #include "distributed_hardware_log.h"
25 #include "metadata_utils.h"
26 #include "dcamera.h"
27
28 namespace OHOS {
29 namespace DistributedHardware {
30 OHOS::sptr<DCameraHost> DCameraHost::instance_ = nullptr;
31 DCameraHost::AutoRelease DCameraHost::autoRelease_;
32
CameraHostImplGetInstance(void)33 extern "C" ICameraHost *CameraHostImplGetInstance(void)
34 {
35 return static_cast<ICameraHost *>(DCameraHost::GetInstance().GetRefPtr());
36 }
37
GetInstance()38 OHOS::sptr<DCameraHost> DCameraHost::GetInstance()
39 {
40 if (instance_ == nullptr) {
41 instance_ = new DCameraHost();
42 if (instance_ == nullptr) {
43 DHLOGE("Get distributed camera host instance failed.");
44 return nullptr;
45 }
46 }
47 return instance_;
48 }
49
SetCallback(const sptr<ICameraHostCallback> & callbackObj)50 int32_t DCameraHost::SetCallback(const sptr<ICameraHostCallback> &callbackObj)
51 {
52 if (callbackObj == nullptr) {
53 DHLOGE("DCameraHost::SetCallback, input camera host callback is null.");
54 return CamRetCode::INVALID_ARGUMENT;
55 }
56 dCameraHostCallback_ = callbackObj;
57 dCameraHostRecipient_ = new DCameraHostRecipient();
58 return CamRetCode::NO_ERROR;
59 }
60
GetCameraIds(std::vector<std::string> & cameraIds)61 int32_t DCameraHost::GetCameraIds(std::vector<std::string> &cameraIds)
62 {
63 auto iter = dhBaseHashDCamIdMap_.begin();
64 while (iter != dhBaseHashDCamIdMap_.end()) {
65 if (!(iter->second).empty()) {
66 cameraIds.push_back(iter->second);
67 }
68 iter++;
69 }
70 return CamRetCode::NO_ERROR;
71 }
72
GetCameraAbility(const std::string & cameraId,std::vector<uint8_t> & cameraAbility)73 int32_t DCameraHost::GetCameraAbility(const std::string &cameraId, std::vector<uint8_t> &cameraAbility)
74 {
75 if (IsCameraIdInvalid(cameraId)) {
76 DHLOGE("DCameraHost::GetCameraAbility, input cameraId is invalid.");
77 return CamRetCode::INVALID_ARGUMENT;
78 }
79
80 DHLOGE("DCameraHost::GetCameraAbility for cameraId: %s", GetAnonyString(cameraId).c_str());
81
82 auto iter = dCameraDeviceMap_.find(cameraId);
83 std::shared_ptr<CameraAbility> ability = nullptr;
84 int32_t ret = (iter->second)->GetDCameraAbility(ability);
85 if (ret != CamRetCode::NO_ERROR) {
86 DHLOGE("DCameraHost::GetCameraAbility, GetDCameraAbility failed, ret: %d.", ret);
87 return ret;
88 }
89 bool retBool = OHOS::Camera::MetadataUtils::ConvertMetadataToVec(ability, cameraAbility);
90 if (!retBool) {
91 DHLOGE("DCameraHost::GetCameraAbility, ConvertMetadataToVec failed.");
92 return CamRetCode::INVALID_ARGUMENT;
93 }
94
95 do {
96 camera_metadata_item_t item;
97 constexpr uint32_t WIDTH_OFFSET = 1;
98 constexpr uint32_t HEIGHT_OFFSET = 2;
99 constexpr uint32_t UNIT_LENGTH = 3;
100 ret = OHOS::Camera::FindCameraMetadataItem(ability->get(),
101 OHOS_ABILITY_STREAM_AVAILABLE_BASIC_CONFIGURATIONS, &item);
102 DHLOGI("FindCameraMetadataItem item=%u, count=%u, dataType=%u", item.item, item.count, item.data_type);
103 if (ret != CAM_META_SUCCESS) {
104 DHLOGE("Failed to find stream configuration in camera ability with return code %d", ret);
105 break;
106 }
107 if (item.count % UNIT_LENGTH != 0) {
108 DHLOGE("Invalid stream configuration count: %u", item.count);
109 break;
110 }
111 for (uint32_t index = 0; index < item.count; index += UNIT_LENGTH) {
112 int32_t format = item.data.i32[index];
113 int32_t width = item.data.i32[index + WIDTH_OFFSET];
114 int32_t height = item.data.i32[index + HEIGHT_OFFSET];
115 DHLOGD("format: %d, width: %d, height: %d", format, width, height);
116 }
117 } while (0);
118 return CamRetCode::NO_ERROR;
119 }
120
OpenCamera(const std::string & cameraId,const sptr<ICameraDeviceCallback> & callbackObj,sptr<ICameraDevice> & device)121 int32_t DCameraHost::OpenCamera(const std::string &cameraId, const sptr<ICameraDeviceCallback> &callbackObj,
122 sptr<ICameraDevice> &device)
123 {
124 if (IsCameraIdInvalid(cameraId) || callbackObj == nullptr) {
125 DHLOGE("DCameraHost::OpenCamera, open camera id is invalid or camera device callback is null.");
126 return CamRetCode::INVALID_ARGUMENT;
127 }
128
129 DHLOGI("DCameraHost::OpenCamera for cameraId: %s", GetAnonyString(cameraId).c_str());
130
131 auto iter = dCameraDeviceMap_.find(cameraId);
132 if (iter == dCameraDeviceMap_.end()) {
133 DHLOGE("DCameraHost::OpenCamera, dcamera device not found.");
134 return CamRetCode::INSUFFICIENT_RESOURCES;
135 }
136
137 OHOS::sptr<DCameraDevice> dcameraDevice = iter->second;
138 if (dcameraDevice == nullptr) {
139 DHLOGE("DCameraHost::OpenCamera, dcamera device is null.");
140 return INSUFFICIENT_RESOURCES;
141 }
142
143 if (dcameraDevice->IsOpened()) {
144 DHLOGE("DCameraHost::OpenCamera, dcamera device %s already opened.", GetAnonyString(cameraId).c_str());
145 return CamRetCode::CAMERA_BUSY;
146 }
147
148 CamRetCode ret = dcameraDevice->OpenDCamera(callbackObj);
149 if (ret != CamRetCode::NO_ERROR) {
150 DHLOGE("DCameraHost::OpenCamera, open camera failed.");
151 return ret;
152 }
153 device = dcameraDevice;
154
155 DHLOGI("DCameraHost::OpenCamera, open camera %s success.", GetAnonyString(cameraId).c_str());
156 return CamRetCode::NO_ERROR;
157 }
158
SetFlashlight(const std::string & cameraId,bool isEnable)159 int32_t DCameraHost::SetFlashlight(const std::string &cameraId, bool isEnable)
160 {
161 (void)cameraId;
162 (void)isEnable;
163 DHLOGI("DCameraHost::SetFlashlight, distributed camera not support.");
164
165 return CamRetCode::METHOD_NOT_SUPPORTED;
166 }
167
AddDCameraDevice(const DHBase & dhBase,const std::string & sinkAbilityInfo,const std::string & sourceAbilityInfo,const sptr<IDCameraProviderCallback> & callback)168 DCamRetCode DCameraHost::AddDCameraDevice(const DHBase &dhBase, const std::string& sinkAbilityInfo,
169 const std::string &sourceAbilityInfo, const sptr<IDCameraProviderCallback> &callback)
170 {
171 if (IsDhBaseInfoInvalid(dhBase)) {
172 DHLOGE("DCameraHost::AddDCameraDevice, devId or dhId is invalid.");
173 return DCamRetCode::INVALID_ARGUMENT;
174 }
175 DHLOGI("DCameraHost::AddDCameraDevice for {devId: %s, dhId: %s}",
176 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
177
178 if (sinkAbilityInfo.empty() || sinkAbilityInfo.length() > ABILITYINFO_MAX_LENGTH) {
179 DHLOGE("DCameraHost::AddDCameraDevice, input sinkAbilityInfo is invalid.");
180 return DCamRetCode::INVALID_ARGUMENT;
181 }
182
183 if (sourceAbilityInfo.empty() || sourceAbilityInfo.length() > ABILITYINFO_MAX_LENGTH) {
184 DHLOGE("DCameraHost::AddDCameraDevice, input sourceAbilityInfo is invalid.");
185 return DCamRetCode::INVALID_ARGUMENT;
186 }
187 OHOS::sptr<DCameraDevice> dcameraDevice(new (std::nothrow) DCameraDevice(dhBase, sinkAbilityInfo,
188 sourceAbilityInfo));
189 if (dcameraDevice == nullptr) {
190 DHLOGE("DCameraHost::AddDCameraDevice, create dcamera device failed.");
191 return DCamRetCode::INVALID_ARGUMENT;
192 }
193
194 std::string dCameraId = dcameraDevice->GetDCameraId();
195 dCameraDeviceMap_[dCameraId] = dcameraDevice;
196 DCameraBase dcameraBase(dhBase.deviceId_, dhBase.dhId_);
197 dhBaseHashDCamIdMap_.emplace(dcameraBase, dCameraId);
198 if (callback == nullptr) {
199 DHLOGE("DCameraHost::SetProviderCallback failed, callback is null");
200 return DCamRetCode::INVALID_ARGUMENT;
201 }
202 dcameraDevice->SetProviderCallback(callback);
203
204 if (dCameraHostCallback_ != nullptr) {
205 dCameraHostCallback_->OnCameraEvent(dCameraId, CameraEvent::CAMERA_EVENT_DEVICE_ADD);
206 }
207 sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<IDCameraProviderCallback>(callback);
208 if (remote != nullptr) {
209 remote->AddDeathRecipient(dCameraHostRecipient_);
210 }
211 DHLOGI("DCameraHost::AddDCameraDevice, create dcamera device success, dCameraId: %s",
212 GetAnonyString(dCameraId).c_str());
213 return DCamRetCode::SUCCESS;
214 }
215
RemoveDCameraDevice(const DHBase & dhBase)216 DCamRetCode DCameraHost::RemoveDCameraDevice(const DHBase &dhBase)
217 {
218 DHLOGI("DCameraHost::RemoveDCameraDevice for {devId: %s, dhId: %s}",
219 GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
220
221 std::string dCameraId = GetCameraIdByDHBase(dhBase);
222 if (dCameraId.empty()) {
223 DHLOGE("DCameraHost::RemoveDCameraDevice, dhBase not exist.");
224 return DCamRetCode::INVALID_ARGUMENT;
225 }
226
227 OHOS::sptr<DCameraDevice> dcameraDevice = GetDCameraDeviceByDHBase(dhBase);
228 if (dcameraDevice != nullptr) {
229 if (dcameraDevice->IsOpened()) {
230 dcameraDevice->Close();
231 }
232 dcameraDevice->SetProviderCallback(nullptr);
233 }
234 sptr<IDCameraProviderCallback> callback = dcameraDevice->GetProviderCallback();
235 if (callback != nullptr) {
236 sptr<IRemoteObject> remoteObj = OHOS::HDI::hdi_objcast<IDCameraProviderCallback>(callback);
237 remoteObj->RemoveDeathRecipient(dCameraHostRecipient_);
238 }
239 DCameraBase dcameraBase(dhBase.deviceId_, dhBase.dhId_);
240 dhBaseHashDCamIdMap_.erase(dcameraBase);
241 dCameraDeviceMap_.erase(dCameraId);
242
243 if (dCameraHostCallback_ != nullptr) {
244 dCameraHostCallback_->OnCameraEvent(dCameraId, CameraEvent::CAMERA_EVENT_DEVICE_RMV);
245 }
246
247 DHLOGI("DCameraHost::RemoveDCameraDevice, remove dcamera device success, dCameraId: %s",
248 GetAnonyString(dCameraId).c_str());
249 return DCamRetCode::SUCCESS;
250 }
251
IsCameraIdInvalid(const std::string & cameraId)252 bool DCameraHost::IsCameraIdInvalid(const std::string &cameraId)
253 {
254 if (cameraId.empty() || cameraId.length() > ID_MAX_SIZE) {
255 return true;
256 }
257
258 auto iter = dhBaseHashDCamIdMap_.begin();
259 while (iter != dhBaseHashDCamIdMap_.end()) {
260 if (cameraId == iter->second) {
261 return false;
262 }
263 iter++;
264 }
265 return true;
266 }
267
GetCameraIdByDHBase(const DHBase & dhBase)268 std::string DCameraHost::GetCameraIdByDHBase(const DHBase &dhBase)
269 {
270 DCameraBase dcameraBase(dhBase.deviceId_, dhBase.dhId_);
271 auto iter = dhBaseHashDCamIdMap_.find(dcameraBase);
272 if (iter == dhBaseHashDCamIdMap_.end()) {
273 return "";
274 }
275 return iter->second;
276 }
277
GetDCameraDeviceByDHBase(const DHBase & dhBase)278 OHOS::sptr<DCameraDevice> DCameraHost::GetDCameraDeviceByDHBase(const DHBase &dhBase)
279 {
280 std::string dCameraId = GetCameraIdByDHBase(dhBase);
281 if (dCameraId.empty()) {
282 DHLOGE("DCameraHost::GetDCameraDeviceByDHBase, dhBase not exist.");
283 return nullptr;
284 }
285
286 auto iter = dCameraDeviceMap_.find(dCameraId);
287 if (iter == dCameraDeviceMap_.end()) {
288 DHLOGE("DCameraHost::GetDCameraDeviceByDHBase, dcamera device not found.");
289 return nullptr;
290 }
291 return iter->second;
292 }
293
NotifyDCameraStatus(const DHBase & dhBase,int32_t result)294 void DCameraHost::NotifyDCameraStatus(const DHBase &dhBase, int32_t result)
295 {
296 std::string dCameraId = GetCameraIdByDHBase(dhBase);
297 if (dCameraId.empty()) {
298 DHLOGE("DCameraHost::NotifyDCameraStatus, dhBase not exist.");
299 return;
300 }
301 if (dCameraHostCallback_ != nullptr) {
302 dCameraHostCallback_->OnCameraStatus(dCameraId, CameraStatus::UN_AVAILABLE);
303 }
304 }
305
OnRemoteDied(const wptr<IRemoteObject> & remote)306 void DCameraHost::DCameraHostRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
307 {
308 DHLOGE("Exit the current process.");
309 _Exit(0);
310 }
311 } // namespace DistributedHardware
312 } // namespace OHOS
313