• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "discovery_manager.h"
17 
18 #include <dlfcn.h>
19 #include "softbus_common.h"
20 
21 #include "dm_anonymous.h"
22 #include "dm_constants.h"
23 #include "parameter.h"
24 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
25 #include "multiple_user_connector.h"
26 #endif
27 
28 namespace OHOS {
29 namespace DistributedHardware {
30 const int32_t DISCOVERY_TIMEOUT = 120;
31 const uint16_t DM_INVALID_FLAG_ID = 0;
32 constexpr const char* LNN_DISC_CAPABILITY = "capability";
33 const std::string TYPE_MINE = "findDeviceMode";
34 const int32_t DECIMALISM = 10;
35 
36 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
37 static std::mutex comDependencyLoadLock;
38 constexpr const char* LIB_DM_COMDENPENDENCY_NAME = "libdevicemanagerdependency.z.so";
39 bool DiscoveryManager::isSoLoaded_ = false;
40 IDeviceProfileConnector* DiscoveryManager::dpConnector_ = nullptr;
41 void* DiscoveryManager::dpConnectorHandle_ = nullptr;
42 #endif
43 
DiscoveryManager(std::shared_ptr<SoftbusListener> softbusListener,std::shared_ptr<IDeviceManagerServiceListener> listener)44 DiscoveryManager::DiscoveryManager(std::shared_ptr<SoftbusListener> softbusListener,
45     std::shared_ptr<IDeviceManagerServiceListener> listener) : softbusListener_(softbusListener), listener_(listener)
46 {
47     LOGI("DiscoveryManager constructor.");
48 }
49 
~DiscoveryManager()50 DiscoveryManager::~DiscoveryManager()
51 {
52 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
53     CloseCommonDependencyObj();
54 #endif
55     LOGI("DiscoveryManager destructor.");
56 }
57 
EnableDiscoveryListener(const std::string & pkgName,const std::map<std::string,std::string> & discoverParam,const std::map<std::string,std::string> & filterOptions)58 int32_t DiscoveryManager::EnableDiscoveryListener(const std::string &pkgName,
59     const std::map<std::string, std::string> &discoverParam, const std::map<std::string, std::string> &filterOptions)
60 {
61     LOGI("DiscoveryManager::EnableDiscoveryListener begin for pkgName = %{public}s.", pkgName.c_str());
62     if (pkgName.empty()) {
63         LOGE("Invalid parameter, pkgName is empty.");
64         return ERR_DM_INPUT_PARA_INVALID;
65     }
66     std::string pkgNameTemp = AddMultiUserIdentify(pkgName);
67     DmSubscribeInfo dmSubInfo;
68     dmSubInfo.subscribeId = DM_INVALID_FLAG_ID;
69     dmSubInfo.mode = DmDiscoverMode::DM_DISCOVER_MODE_PASSIVE;
70     dmSubInfo.freq = DmExchangeFreq::DM_LOW;
71     dmSubInfo.isSameAccount = false;
72     dmSubInfo.isWakeRemote = false;
73     if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_APPROACH) != EOK) {
74         LOGE("capability copy err.");
75         return ERR_DM_ENABLE_DISCOVERY_LISTENER_FAILED;
76     }
77     UpdateInfoFreq(discoverParam, dmSubInfo);
78     if (discoverParam.find(PARAM_KEY_META_TYPE) != discoverParam.end()) {
79         std::string metaType = discoverParam.find(PARAM_KEY_META_TYPE)->second;
80         LOGI("EnableDiscoveryListener, input MetaType = %{public}s in discoverParam map.", metaType.c_str());
81     }
82     if (discoverParam.find(PARAM_KEY_SUBSCRIBE_ID) != discoverParam.end()) {
83         dmSubInfo.subscribeId = std::atoi((discoverParam.find(PARAM_KEY_SUBSCRIBE_ID)->second).c_str());
84         {
85             std::lock_guard<std::mutex> autoLock(subIdMapLocks_);
86             pkgName2SubIdMap_[pkgNameTemp] = dmSubInfo.subscribeId;
87         }
88     }
89     if (discoverParam.find(PARAM_KEY_DISC_CAPABILITY) != discoverParam.end()) {
90         std::string capability = discoverParam.find(PARAM_KEY_DISC_CAPABILITY)->second;
91         if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, capability.c_str()) != EOK) {
92             LOGI("EnableDiscoveryListener failed, capability copy err.");
93             return ERR_DM_ENABLE_DISCOVERY_LISTENER_FAILED;
94         }
95     }
96     LOGI("EnableDiscoveryListener capability = %{public}s,", std::string(dmSubInfo.capability).c_str());
97     {
98         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
99         capabilityMap_[pkgNameTemp] = std::string(dmSubInfo.capability);
100     }
101     UpdateInfoMedium(discoverParam, dmSubInfo);
102     int32_t ret = softbusListener_->RefreshSoftbusLNN(DM_PKG_NAME, dmSubInfo, LNN_DISC_CAPABILITY);
103     if (ret != DM_OK) {
104         LOGE("EnableDiscoveryListener failed, softbus refresh lnn ret: %{public}d.", ret);
105         return ret;
106     }
107     softbusListener_->RegisterSoftbusLnnOpsCbk(pkgNameTemp, shared_from_this());
108     return DM_OK;
109 }
110 
DisableDiscoveryListener(const std::string & pkgName,const std::map<std::string,std::string> & extraParam)111 int32_t DiscoveryManager::DisableDiscoveryListener(const std::string &pkgName,
112     const std::map<std::string, std::string> &extraParam)
113 {
114     LOGI("DiscoveryManager::DisableDiscoveryListener begin for pkgName = %{public}s.", pkgName.c_str());
115     if (pkgName.empty()) {
116         LOGE("Invalid parameter, pkgName is empty.");
117         return ERR_DM_INPUT_PARA_INVALID;
118     }
119     std::string pkgNameTemp = RemoveMultiUserIdentify(pkgName);
120     if (extraParam.find(PARAM_KEY_META_TYPE) != extraParam.end()) {
121         LOGI("DisableDiscoveryListener, input MetaType = %{public}s",
122             (extraParam.find(PARAM_KEY_META_TYPE)->second).c_str());
123     }
124     uint16_t subscribeId = DM_INVALID_FLAG_ID;
125     if (extraParam.find(PARAM_KEY_SUBSCRIBE_ID) != extraParam.end()) {
126         subscribeId = std::atoi((extraParam.find(PARAM_KEY_SUBSCRIBE_ID)->second).c_str());
127         {
128             std::lock_guard<std::mutex> autoLock(subIdMapLocks_);
129             pkgName2SubIdMap_.erase(pkgNameTemp);
130         }
131     }
132     {
133         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
134         if (capabilityMap_.find(pkgNameTemp) != capabilityMap_.end()) {
135             capabilityMap_.erase(pkgNameTemp);
136         }
137     }
138     softbusListener_->UnRegisterSoftbusLnnOpsCbk(pkgNameTemp);
139     return softbusListener_->StopRefreshSoftbusLNN(subscribeId);
140 }
141 
StartDiscovering(const std::string & pkgName,const std::map<std::string,std::string> & discoverParam,const std::map<std::string,std::string> & filterOptions)142 int32_t DiscoveryManager::StartDiscovering(const std::string &pkgName,
143     const std::map<std::string, std::string> &discoverParam, const std::map<std::string, std::string> &filterOptions)
144 {
145     LOGI("DiscoveryManager::StartDiscovering begin for pkgName = %{public}s.", pkgName.c_str());
146     if (pkgName.empty()) {
147         LOGE("Invalid parameter, pkgName is empty.");
148         return ERR_DM_INPUT_PARA_INVALID;
149     }
150     std::string pkgNameTemp = AddMultiUserIdentify(pkgName);
151     DmSubscribeInfo dmSubInfo;
152     ConfigDiscParam(discoverParam, &dmSubInfo);
153     if (HandleDiscoveryQueue(pkgNameTemp, dmSubInfo.subscribeId, filterOptions) != DM_OK) {
154         return ERR_DM_DISCOVERY_REPEATED;
155     }
156 
157     bool isStandardMetaNode = true;
158     if (discoverParam.find(PARAM_KEY_META_TYPE) != discoverParam.end()) {
159         MetaNodeType metaType = (MetaNodeType)(std::atoi((discoverParam.find(PARAM_KEY_META_TYPE)->second).c_str()));
160         isStandardMetaNode = (metaType == MetaNodeType::PROXY_TRANSMISION);
161     }
162 
163     softbusListener_->RegisterSoftbusLnnOpsCbk(pkgNameTemp, shared_from_this());
164     StartDiscoveryTimer(pkgNameTemp);
165 
166     auto it = filterOptions.find(PARAM_KEY_FILTER_OPTIONS);
167     JsonObject jsonObject(it->second);
168     if (!jsonObject.IsDiscarded() && jsonObject.Contains(TYPE_MINE)) {
169         return StartDiscovering4MineLibary(pkgNameTemp, dmSubInfo, it->second);
170     }
171 
172     int32_t ret = isStandardMetaNode ? StartDiscoveringNoMetaType(pkgNameTemp, dmSubInfo, discoverParam) :
173             StartDiscovering4MetaType(pkgNameTemp, dmSubInfo, discoverParam);
174     if (ret != DM_OK) {
175         LOGE("StartDiscovering for meta node process failed, ret = %{public}d", ret);
176         return ret;
177     }
178     return ret;
179 }
180 
ConfigDiscParam(const std::map<std::string,std::string> & discoverParam,DmSubscribeInfo * dmSubInfo)181 void DiscoveryManager::ConfigDiscParam(const std::map<std::string, std::string> &discoverParam,
182     DmSubscribeInfo *dmSubInfo)
183 {
184     LOGI("DiscoveryManager::ConfigDiscParam");
185     if (dmSubInfo == nullptr) {
186         LOGE("ConfigDiscParam failed, dmSubInfo is nullptr.");
187         return;
188     }
189     dmSubInfo->subscribeId = DM_INVALID_FLAG_ID;
190     dmSubInfo->mode = DmDiscoverMode::DM_DISCOVER_MODE_ACTIVE;
191     dmSubInfo->medium = DmExchangeMedium::DM_AUTO;
192     dmSubInfo->freq = DmExchangeFreq::DM_LOW;
193     dmSubInfo->isSameAccount = false;
194     dmSubInfo->isWakeRemote = false;
195     if (discoverParam.find(PARAM_KEY_SUBSCRIBE_ID) != discoverParam.end()) {
196         dmSubInfo->subscribeId = std::atoi((discoverParam.find(PARAM_KEY_SUBSCRIBE_ID)->second).c_str());
197     }
198     if (discoverParam.find(PARAM_KEY_DISC_MEDIUM) != discoverParam.end()) {
199         int32_t medium = std::atoi((discoverParam.find(PARAM_KEY_DISC_MEDIUM)->second).c_str());
200         dmSubInfo->medium = static_cast<DmExchangeMedium>(medium);
201     }
202     if (discoverParam.find(PARAM_KEY_DISC_FREQ) != discoverParam.end()) {
203         int32_t freq = std::atoi((discoverParam.find(PARAM_KEY_DISC_FREQ)->second).c_str());
204         dmSubInfo->freq = static_cast<DmExchangeFreq>(freq);
205     }
206     if (discoverParam.find(PARAM_KEY_DISC_MODE) != discoverParam.end()) {
207         dmSubInfo->mode =
208             static_cast<DmDiscoverMode>(std::atoi((discoverParam.find(PARAM_KEY_DISC_MODE)->second).c_str()));
209     }
210 }
211 
StartDiscovering4MineLibary(const std::string & pkgName,DmSubscribeInfo & dmSubInfo,const std::string & searchJson)212 int32_t DiscoveryManager::StartDiscovering4MineLibary(const std::string &pkgName, DmSubscribeInfo &dmSubInfo,
213     const std::string &searchJson)
214 {
215     if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_OSD) != EOK) {
216         LOGE("capability copy err.");
217         return ERR_DM_START_DISCOVERING_FAILED;
218     }
219     LOGI("StartDiscovering for mine meta node process, pkgName = %{public}s, capability = %{public}s",
220         pkgName.c_str(), std::string(dmSubInfo.capability).c_str());
221     {
222         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
223         capabilityMap_[pkgName] = std::string(dmSubInfo.capability);
224     }
225     int32_t ret = mineSoftbusListener_->RefreshSoftbusLNN(pkgName, searchJson, dmSubInfo);
226     if (ret != DM_OK) {
227         LOGE("StartDiscovering for meta node process failed, ret = %{public}d", ret);
228         return ret;
229     }
230     return ret;
231 }
232 
StartDiscoveringNoMetaType(const std::string & pkgName,DmSubscribeInfo & dmSubInfo,const std::map<std::string,std::string> & param)233 int32_t DiscoveryManager::StartDiscoveringNoMetaType(const std::string &pkgName, DmSubscribeInfo &dmSubInfo,
234     const std::map<std::string, std::string> &param)
235 {
236     if (param.find(PARAM_KEY_DISC_CAPABILITY) != param.end() &&
237         !param.find(PARAM_KEY_DISC_CAPABILITY)->second.empty()) {
238         if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN,
239             param.find(PARAM_KEY_DISC_CAPABILITY)->second.c_str()) != EOK) {
240             LOGE("capability copy err.");
241             return ERR_DM_START_DISCOVERING_FAILED;
242         }
243     } else if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_OSD) != EOK) {
244         LOGE("capability copy err.");
245         return ERR_DM_START_DISCOVERING_FAILED;
246     }
247     LOGI("StartDiscovering for standard meta node process, pkgName = %{public}s, capability = %{public}s",
248         pkgName.c_str(), std::string(dmSubInfo.capability).c_str());
249 
250     {
251         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
252         capabilityMap_[pkgName] = std::string(dmSubInfo.capability);
253     }
254     std::string customData = LNN_DISC_CAPABILITY;
255     if (param.find(PARAM_KEY_CUSTOM_DATA) != param.end() && !param.find(PARAM_KEY_CUSTOM_DATA)->second.empty()) {
256         customData = param.find(PARAM_KEY_CUSTOM_DATA)->second;
257     }
258     int32_t ret = softbusListener_->RefreshSoftbusLNN(DM_PKG_NAME, dmSubInfo, customData);
259     if (ret != DM_OK) {
260         LOGE("StartDiscoveringNoMetaType failed, softbus refresh lnn ret: %{public}d.", ret);
261     }
262     return ret;
263 }
264 
StartDiscovering4MetaType(const std::string & pkgName,DmSubscribeInfo & dmSubInfo,const std::map<std::string,std::string> & param)265 int32_t DiscoveryManager::StartDiscovering4MetaType(const std::string &pkgName, DmSubscribeInfo &dmSubInfo,
266     const std::map<std::string, std::string> &param)
267 {
268     LOGI("StartDiscovering for meta node process, input metaType = %{public}s, pkgName = %{public}s",
269          (param.find(PARAM_KEY_META_TYPE)->second).c_str(), pkgName.c_str());
270     MetaNodeType metaType = (MetaNodeType)(std::atoi((param.find(PARAM_KEY_META_TYPE)->second).c_str()));
271     switch (metaType) {
272         case MetaNodeType::PROXY_SHARE:
273             LOGI("StartDiscovering4MetaType for share meta node process.");
274             if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_SHARE) != EOK) {
275                 LOGE("capability copy error.");
276                 return ERR_DM_FAILED;
277             }
278             break;
279         case MetaNodeType::PROXY_WEAR:
280             LOGI("StartDiscovering4MetaType for wear meta node process.");
281             if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_WEAR) != EOK) {
282                 LOGE("capability copy error.");
283                 return ERR_DM_FAILED;
284             }
285             break;
286         case MetaNodeType::PROXY_CASTPLUS:
287             LOGI("StartDiscovering4MetaType for cast_plus meta node process.");
288             if (strcpy_s(dmSubInfo.capability, DM_MAX_DEVICE_CAPABILITY_LEN, DM_CAPABILITY_CASTPLUS) != EOK) {
289                 LOGE("capability copy error.");
290                 return ERR_DM_FAILED;
291             }
292             break;
293         default:
294             LOGE("StartDiscovering4MetaType failed, unsupport meta type : %{public}d.", metaType);
295             return ERR_DM_UNSUPPORTED_METHOD;
296     }
297 
298     std::string customData = "";
299     if (param.find(PARAM_KEY_CUSTOM_DATA) != param.end()) {
300         customData = param.find(PARAM_KEY_CUSTOM_DATA)->second;
301     }
302     LOGI("StartDiscovering4MetaType capability = %{public}s,", std::string(dmSubInfo.capability).c_str());
303     {
304         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
305         capabilityMap_[pkgName] =std::string(dmSubInfo.capability);
306     }
307 
308     int32_t ret = softbusListener_->RefreshSoftbusLNN(DM_PKG_NAME, dmSubInfo, customData);
309     if (ret != DM_OK) {
310         LOGE("StartDiscovering4MetaType failed, softbus refresh lnn ret: %{public}d.", ret);
311     }
312     return ret;
313 }
314 
StopDiscovering(const std::string & pkgName,uint16_t subscribeId)315 int32_t DiscoveryManager::StopDiscovering(const std::string &pkgName, uint16_t subscribeId)
316 {
317     LOGI("DiscoveryManager::StopDiscovering begin for pkgName = %{public}s.", pkgName.c_str());
318     if (pkgName.empty()) {
319         LOGE("Invalid parameter, pkgName is empty.");
320         return ERR_DM_INPUT_PARA_INVALID;
321     }
322     std::string pkgNameTemp = RemoveMultiUserIdentify(pkgName);
323     {
324         std::lock_guard<std::mutex> autoLock(locks_);
325         if (pkgNameSet_.find(pkgNameTemp) != pkgNameSet_.end()) {
326             pkgNameSet_.erase(pkgNameTemp);
327         }
328 
329         if (discoveryContextMap_.find(pkgNameTemp) != discoveryContextMap_.end()) {
330             discoveryContextMap_.erase(pkgNameTemp);
331             if (timer_ != nullptr) {
332                 timer_->DeleteTimer(pkgNameTemp);
333             }
334         }
335     }
336     {
337         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
338         if (capabilityMap_.find(pkgNameTemp) != capabilityMap_.end()) {
339             capabilityMap_.erase(pkgNameTemp);
340         }
341     }
342     softbusListener_->UnRegisterSoftbusLnnOpsCbk(pkgNameTemp);
343 #if (defined(MINE_HARMONY))
344     return mineSoftbusListener_->StopRefreshSoftbusLNN(subscribeId);
345 #else
346     return softbusListener_->StopRefreshSoftbusLNN(subscribeId);
347 #endif
348 }
349 
OnDeviceFound(const std::string & pkgName,const DmDeviceInfo & info,bool isOnline)350 void DiscoveryManager::OnDeviceFound(const std::string &pkgName, const DmDeviceInfo &info, bool isOnline)
351 {
352     int32_t userId = -1;
353     std::string callerPkgName = "";
354     GetPkgNameAndUserId(pkgName, callerPkgName, userId);
355     DeviceFilterPara filterPara;
356     filterPara.isOnline = false;
357     filterPara.range = info.range;
358     filterPara.deviceType = info.deviceTypeId;
359     std::string deviceIdHash = static_cast<std::string>(info.deviceId);
360     if (isOnline && GetDeviceAclParam(callerPkgName, userId, deviceIdHash, filterPara.isOnline,
361         filterPara.authForm) != DM_OK) {
362         LOGE("The found device get online param failed.");
363     }
364     JsonObject jsonObject(info.extraData);
365     if (jsonObject.IsDiscarded()) {
366         LOGE("OnDeviceFound jsonStr error");
367         return;
368     }
369     if (!IsUint32(jsonObject, PARAM_KEY_DISC_CAPABILITY)) {
370         LOGE("err json string: %{public}s", PARAM_KEY_DISC_CAPABILITY);
371         return;
372     }
373     uint32_t capabilityType = jsonObject[PARAM_KEY_DISC_CAPABILITY].Get<uint32_t>();
374     OnDeviceFound(pkgName, capabilityType, info, filterPara);
375 }
376 
OnDeviceFound(const std::string & pkgName,const uint32_t capabilityType,const DmDeviceInfo & info,const DeviceFilterPara & filterPara)377 void DiscoveryManager::OnDeviceFound(const std::string &pkgName, const uint32_t capabilityType,
378     const DmDeviceInfo &info, const DeviceFilterPara &filterPara)
379 {
380     int32_t userId = -1;
381     std::string callerPkgName = "";
382     GetPkgNameAndUserId(pkgName, callerPkgName, userId);
383     ProcessInfo processInfo;
384     processInfo.userId = userId;
385     processInfo.pkgName = callerPkgName;
386     bool isIndiscoveryContextMap = false;
387     DiscoveryContext discoveryContext;
388     {
389         std::lock_guard<std::mutex> autoLock(locks_);
390         auto iter = discoveryContextMap_.find(pkgName);
391         isIndiscoveryContextMap = (iter != discoveryContextMap_.end());
392         if (isIndiscoveryContextMap) {
393             discoveryContext = iter->second;
394         }
395     }
396     if (!isIndiscoveryContextMap) {
397         {
398             std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
399             if (capabilityMap_.find(pkgName) == capabilityMap_.end() ||
400                 !CompareCapability(capabilityType, capabilityMap_[pkgName])) {
401                 return;
402             }
403         }
404         uint16_t subscribeId = 0;
405         {
406             std::lock_guard<std::mutex> autoLock(subIdMapLocks_);
407             subscribeId = pkgName2SubIdMap_[pkgName];
408         }
409         LOGD("OnDeviceFound, pkgName = %{public}s, cabability = %{public}d", pkgName.c_str(), capabilityType);
410         listener_->OnDeviceFound(processInfo, subscribeId, info);
411         return;
412     }
413     DiscoveryFilter filter;
414     if (filter.IsValidDevice(discoveryContext.filterOp, discoveryContext.filters, filterPara)) {
415         {
416             std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
417             if (capabilityMap_.find(pkgName) == capabilityMap_.end() ||
418                 !CompareCapability(capabilityType, capabilityMap_[pkgName])) {
419                 return;
420             }
421         }
422         LOGD("OnDeviceFound, pkgName = %{public}s, cabability = %{public}d", pkgName.c_str(), capabilityType);
423         listener_->OnDeviceFound(processInfo, discoveryContext.subscribeId, info);
424     }
425 }
426 
CompareCapability(uint32_t capabilityType,const std::string & capabilityStr)427 bool DiscoveryManager::CompareCapability(uint32_t capabilityType, const std::string &capabilityStr)
428 {
429     for (uint32_t i = 0; i < sizeof(g_capabilityMap) / sizeof(g_capabilityMap[0]); i++) {
430         if (strcmp(capabilityStr.c_str(), g_capabilityMap[i].capability) == 0) {
431             LOGD("capabilityType: %{public}d, capabilityStr: %{public}s", capabilityType, capabilityStr.c_str());
432             return ((capabilityType >> static_cast<uint32_t>(g_capabilityMap[i].bitmap)) & 1);
433         }
434     }
435     return false;
436 }
437 
OnDiscoveringResult(const std::string & pkgName,int32_t subscribeId,int32_t result)438 void DiscoveryManager::OnDiscoveringResult(const std::string &pkgName, int32_t subscribeId, int32_t result)
439 {
440     LOGI("DiscoveryManager::OnDiscoveringResult, subscribeId = %{public}d, result = %{public}d.", subscribeId, result);
441     int32_t userId = -1;
442     std::string callerPkgName = "";
443     GetPkgNameAndUserId(pkgName, callerPkgName, userId);
444     ProcessInfo processInfo;
445     processInfo.userId = userId;
446     processInfo.pkgName = callerPkgName;
447     if (pkgName.empty() || (listener_ == nullptr)) {
448         LOGE("DiscoveryManager::OnDiscoveringResult failed, IDeviceManagerServiceListener is null.");
449         return;
450     }
451     if (result == 0) {
452         std::lock_guard<std::mutex> autoLock(locks_);
453         discoveryContextMap_[pkgName].subscribeId = (uint32_t)subscribeId;
454         listener_->OnDiscoverySuccess(processInfo, subscribeId);
455         return;
456     }
457     {
458         std::lock_guard<std::mutex> autoLock(locks_);
459         if (pkgNameSet_.find(pkgName) != pkgNameSet_.end()) {
460             pkgNameSet_.erase(pkgName);
461         }
462         if (discoveryContextMap_.find(pkgName) != discoveryContextMap_.end()) {
463             discoveryContextMap_.erase(pkgName);
464             if (timer_ != nullptr) {
465                 timer_->DeleteTimer(pkgName);
466             }
467         }
468     }
469     {
470         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
471         if (capabilityMap_.find(pkgName) != capabilityMap_.end()) {
472             capabilityMap_.erase(pkgName);
473         }
474     }
475     listener_->OnDiscoveryFailed(processInfo, (uint32_t)subscribeId, result);
476     softbusListener_->StopRefreshSoftbusLNN(subscribeId);
477 }
478 
StartDiscoveryTimer(const std::string & pkgName)479 void DiscoveryManager::StartDiscoveryTimer(const std::string &pkgName)
480 {
481     if (timer_ == nullptr) {
482         timer_ = std::make_shared<DmTimer>();
483     }
484     timer_->StartTimer(pkgName, DISCOVERY_TIMEOUT,
485         [this] (std::string name) {
486             DiscoveryManager::HandleDiscoveryTimeout(name);
487         });
488 }
489 
HandleDiscoveryQueue(const std::string & pkgName,uint16_t subscribeId,const std::map<std::string,std::string> & filterOps)490 int32_t DiscoveryManager::HandleDiscoveryQueue(const std::string &pkgName, uint16_t subscribeId,
491     const std::map<std::string, std::string> &filterOps)
492 {
493     std::string filterData = "";
494     if (filterOps.find(PARAM_KEY_FILTER_OPTIONS) != filterOps.end()) {
495         filterData = filterOps.find(PARAM_KEY_FILTER_OPTIONS)->second;
496     }
497     DeviceFilterOption dmFilter;
498     if ((dmFilter.TransformToFilter(filterData) != DM_OK) && (dmFilter.TransformFilterOption(filterData) != DM_OK)) {
499         return ERR_DM_INPUT_PARA_INVALID;
500     }
501     {
502         std::lock_guard<std::mutex> autoLock(locks_);
503         if (pkgNameSet_.find(pkgName) == pkgNameSet_.end()) {
504             pkgNameSet_.emplace(pkgName);
505             DiscoveryContext context = {pkgName, filterData, subscribeId, dmFilter.filterOp_, dmFilter.filters_};
506             discoveryContextMap_.emplace(pkgName, context);
507             return DM_OK;
508         } else {
509             LOGE("DiscoveryManager::HandleDiscoveryQueue repeated, pkgName : %{public}s.", pkgName.c_str());
510             return ERR_DM_DISCOVERY_REPEATED;
511         }
512     }
513 }
514 
HandleDiscoveryTimeout(const std::string & pkgName)515 void DiscoveryManager::HandleDiscoveryTimeout(const std::string &pkgName)
516 {
517     LOGI("DiscoveryManager::HandleDiscoveryTimeout");
518     uint16_t subscribeId = 0;
519     {
520         std::lock_guard<std::mutex> autoLock(locks_);
521         if (pkgNameSet_.find(pkgName) == pkgNameSet_.end()) {
522             LOGE("HandleDiscoveryTimeout: pkgName: %{public}s is not exist.", pkgName.c_str());
523             return;
524         }
525         auto iter = discoveryContextMap_.find(pkgName);
526         if (iter == discoveryContextMap_.end()) {
527             LOGE("HandleDiscoveryTimeout: subscribeId not found by pkgName %{public}s.",
528                 GetAnonyString(pkgName).c_str());
529             return;
530         }
531         subscribeId = discoveryContextMap_[pkgName].subscribeId;
532     }
533     StopDiscovering(pkgName, subscribeId);
534 }
535 
UpdateInfoFreq(const std::map<std::string,std::string> & discoverParam,DmSubscribeInfo & dmSubInfo)536 void DiscoveryManager::UpdateInfoFreq(
537     const std::map<std::string, std::string> &discoverParam, DmSubscribeInfo &dmSubInfo)
538 {
539     if (auto it = discoverParam.find(PARAM_KEY_DISC_FREQ); it != discoverParam.end()) {
540         int32_t freq = StringToInt(it->second, DECIMALISM);
541         if (freq < DmExchangeFreq::DM_LOW || freq > DmExchangeFreq::DM_FREQ_BUTT) {
542             LOGE("Invalid freq value.");
543             return;
544         }
545         dmSubInfo.freq = static_cast<DmExchangeFreq>(freq);
546     }
547 }
548 
UpdateInfoMedium(const std::map<std::string,std::string> & discoverParam,DmSubscribeInfo & dmSubInfo)549 void DiscoveryManager::UpdateInfoMedium(
550     const std::map<std::string, std::string> &discoverParam, DmSubscribeInfo &dmSubInfo)
551 {
552     dmSubInfo.medium = DmExchangeMedium::DM_BLE;
553     if (discoverParam.find(PARAM_KEY_DISC_MEDIUM) != discoverParam.end()) {
554         int32_t medium = std::atoi((discoverParam.find(PARAM_KEY_DISC_MEDIUM)->second).c_str());
555         dmSubInfo.medium = static_cast<DmExchangeMedium>(medium);
556     }
557 }
558 
GetDeviceAclParam(const std::string & pkgName,int32_t userId,std::string deviceId,bool & isOnline,int32_t & authForm)559 int32_t DiscoveryManager::GetDeviceAclParam(const std::string &pkgName, int32_t userId, std::string deviceId,
560     bool &isOnline, int32_t &authForm)
561 {
562 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
563     char localDeviceId[DEVICE_UUID_LENGTH];
564     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
565     std::string requestDeviceId = static_cast<std::string>(localDeviceId);
566     DmDiscoveryInfo discoveryInfo;
567     discoveryInfo.pkgname = pkgName;
568     discoveryInfo.localDeviceId = requestDeviceId;
569     discoveryInfo.remoteDeviceIdHash = deviceId;
570     discoveryInfo.userId = userId;
571     if (DiscoveryManager::IsCommonDependencyReady() && DiscoveryManager::GetCommonDependencyObj() != nullptr) {
572         if (DiscoveryManager::GetCommonDependencyObj()->GetDeviceAclParam(discoveryInfo, isOnline, authForm) != DM_OK) {
573             LOGE("GetDeviceAclParam failed.");
574             return ERR_DM_FAILED;
575         }
576     }
577 #endif
578     return DM_OK;
579 }
580 
581 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
GetCommonDependencyObj()582 IDeviceProfileConnector* DiscoveryManager::GetCommonDependencyObj()
583 {
584     return dpConnector_;
585 }
586 
IsCommonDependencyReady()587 bool DiscoveryManager::IsCommonDependencyReady()
588 {
589     std::lock_guard<std::mutex> lock(comDependencyLoadLock);
590     if (isSoLoaded_ && dpConnector_ != nullptr && dpConnectorHandle_ != nullptr) {
591         return true;
592     }
593     dpConnectorHandle_ = dlopen(LIB_DM_COMDENPENDENCY_NAME, RTLD_NOW | RTLD_NODELETE | RTLD_NOLOAD);
594     if (dpConnectorHandle_ == nullptr) {
595         dpConnectorHandle_ = dlopen(LIB_DM_COMDENPENDENCY_NAME, RTLD_NOW | RTLD_NODELETE);
596     }
597     if (dpConnectorHandle_ == nullptr) {
598         LOGE("load libdevicemanagerdependency so failed, errMsg: %{public}s.", dlerror());
599         return false;
600     }
601     dlerror();
602     auto func = (CreateDpConnectorFuncPtr)dlsym(dpConnectorHandle_, "CreateDpConnectorInstance");
603     if (dlerror() != nullptr || func == nullptr) {
604         dlclose(dpConnectorHandle_);
605         LOGE("Create object function is not exist.");
606         return false;
607     }
608     dpConnector_ = func();
609     isSoLoaded_ = true;
610     LOGI("IsCommonDependencyReady success.");
611     return true;
612 }
613 
CloseCommonDependencyObj()614 bool DiscoveryManager::CloseCommonDependencyObj()
615 {
616     LOGI("DiscoveryManager::CloseCommonDependencyObj start.");
617     std::lock_guard<std::mutex> lock(comDependencyLoadLock);
618     if (!isSoLoaded_ && (dpConnector_ == nullptr) && (dpConnectorHandle_ == nullptr)) {
619         return true;
620     }
621 
622     int32_t ret = dlclose(dpConnectorHandle_);
623     if (ret != 0) {
624         LOGE("close libdevicemanagerdependency failed ret = %{public}d.", ret);
625         return false;
626     }
627     isSoLoaded_ = false;
628     dpConnector_ = nullptr;
629     dpConnectorHandle_ = nullptr;
630     LOGI("close libdevicemanagerdependency so success.");
631     return true;
632 }
633 #endif
634 
ClearDiscoveryCache(const ProcessInfo & processInfo)635 void DiscoveryManager::ClearDiscoveryCache(const ProcessInfo &processInfo)
636 {
637     LOGI("PkgName: %{public}s, userId: %{public}d", processInfo.pkgName.c_str(), processInfo.userId);
638     std::string pkgName = processInfo.pkgName + "#";
639     std::set<uint16_t> subscribeIdSet = ClearDiscoveryPkgName(pkgName);
640 
641     CHECK_NULL_VOID(softbusListener_);
642     for (auto it : subscribeIdSet) {
643         std::string pkgNameTemp = (ComposeStr(ComposeStr(processInfo.pkgName, it), processInfo.userId));
644         softbusListener_->UnRegisterSoftbusLnnOpsCbk(pkgNameTemp);
645         softbusListener_->StopRefreshSoftbusLNN(it);
646     }
647 
648     CHECK_NULL_VOID(timer_);
649     for (auto it : subscribeIdSet) {
650         std::string pkgNameTemp = (ComposeStr(ComposeStr(processInfo.pkgName, it), processInfo.userId));
651         timer_->DeleteTimer(pkgNameTemp);
652     }
653 }
654 
ClearDiscoveryPkgName(const std::string & pkgName)655 std::set<uint16_t> DiscoveryManager::ClearDiscoveryPkgName(const std::string &pkgName)
656 {
657     std::set<uint16_t> subscribeIdSet;
658     {
659         std::lock_guard<std::mutex> autoLock(locks_);
660         for (auto it = pkgNameSet_.begin(); it != pkgNameSet_.end();) {
661             if ((*it).find(pkgName) != std::string::npos) {
662                 LOGI("Erase pkgname %{public}s from pkgNameSet.", (*it).c_str());
663                 it = pkgNameSet_.erase(it);
664             } else {
665                 ++it;
666             }
667         }
668         for (auto it = discoveryContextMap_.begin(); it != discoveryContextMap_.end();) {
669             if (it->first.find(pkgName) != std::string::npos) {
670                 LOGI("Erase pkgname %{public}s from discoveryContextMap_.", it->first.c_str());
671                 subscribeIdSet.insert(it->second.subscribeId);
672                 it = discoveryContextMap_.erase(it);
673             } else {
674                 ++it;
675             }
676         }
677     }
678     {
679         std::lock_guard<std::mutex> capLock(capabilityMapLocks_);
680         for (auto it = capabilityMap_.begin(); it != capabilityMap_.end();) {
681             if (it->first.find(pkgName) != std::string::npos) {
682                 LOGI("Erase pkgname %{public}s from capabilityMap_.", it->first.c_str());
683                 it = capabilityMap_.erase(it);
684             } else {
685                 ++it;
686             }
687         }
688     }
689     {
690         std::lock_guard<std::mutex> autoLock(subIdMapLocks_);
691         for (auto it = pkgName2SubIdMap_.begin(); it != pkgName2SubIdMap_.end();) {
692             if (it->first.find(pkgName) != std::string::npos) {
693                 LOGI("Erase pkgname %{public}s from pkgName2SubIdMap_.", it->first.c_str());
694                 subscribeIdSet.insert(it->second);
695                 it = pkgName2SubIdMap_.erase(it);
696             } else {
697                 ++it;
698             }
699         }
700     }
701     return subscribeIdSet;
702 }
703 
AddMultiUserIdentify(const std::string & pkgName)704 std::string DiscoveryManager::AddMultiUserIdentify(const std::string &pkgName)
705 {
706     int32_t userId = -1;
707 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
708     MultipleUserConnector::GetCallerUserId(userId);
709 #endif
710     if (userId == -1) {
711         LOGE("Get caller userId failed.");
712         return pkgName;
713     }
714     MultiUserDiscovery multiUserDisc;
715     multiUserDisc.pkgName = pkgName;
716     multiUserDisc.userId = userId;
717     std::string pkgNameTemp = ComposeStr(pkgName, userId);
718     {
719         std::lock_guard<std::mutex> autoLock(multiUserDiscLocks_);
720         multiUserDiscMap_[pkgNameTemp] = multiUserDisc;
721     }
722     return pkgNameTemp;
723 }
724 
RemoveMultiUserIdentify(const std::string & pkgName)725 std::string DiscoveryManager::RemoveMultiUserIdentify(const std::string &pkgName)
726 {
727     int32_t userId = -1;
728 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
729     MultipleUserConnector::GetCallerUserId(userId);
730 #endif
731     if (userId == -1) {
732         LOGE("Get caller userId failed.");
733         return pkgName;
734     }
735     std::string pkgNameTemp = ComposeStr(pkgName, userId);
736     {
737         std::lock_guard<std::mutex> autoLock(multiUserDiscLocks_);
738         if (multiUserDiscMap_.find(pkgNameTemp) != multiUserDiscMap_.end()) {
739             multiUserDiscMap_.erase(pkgNameTemp);
740         }
741     }
742     return pkgNameTemp;
743 }
744 
GetPkgNameAndUserId(const std::string & pkgName,std::string & callerPkgName,int32_t & userId)745 void DiscoveryManager::GetPkgNameAndUserId(const std::string &pkgName, std::string &callerPkgName,
746     int32_t &userId)
747 {
748     {
749         std::lock_guard<std::mutex> autoLock(multiUserDiscLocks_);
750         if (multiUserDiscMap_.find(pkgName) != multiUserDiscMap_.end()) {
751             callerPkgName = GetCallerPkgName(multiUserDiscMap_[pkgName].pkgName);
752             userId = multiUserDiscMap_[pkgName].userId;
753             return;
754         }
755     }
756     LOGE("find failed PkgName %{public}s.", pkgName.c_str());
757 }
758 } // namespace DistributedHardware
759 } // namespace OHOS
760