• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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