1 /*
2  * Copyright (c) 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 #define LOG_TAG "ObjectDmsHandler"
17 
18 #include "object_dms_handler.h"
19 
20 #include "device_manager_adapter.h"
21 #include "dms_handler.h"
22 #include "log_print.h"
23 #include "utils/anonymous.h"
24 
25 namespace OHOS::DistributedObject {
26 constexpr const char *PKG_NAME = "ohos.distributeddata.service";
DSchedEventNotify(DistributedSchedule::EventNotify & notify)27 void DmsEventListener::DSchedEventNotify(DistributedSchedule::EventNotify &notify)
28 {
29     ObjectDmsHandler::GetInstance().ReceiveDmsEvent(notify);
30 }
31 
ReceiveDmsEvent(DistributedSchedule::EventNotify & event)32 void ObjectDmsHandler::ReceiveDmsEvent(DistributedSchedule::EventNotify &event)
33 {
34     std::lock_guard<std::mutex> lock(mutex_);
35     auto now = std::chrono::steady_clock::now();
36     dmsEvents_.push_back(std::make_pair(event, now));
37     if (dmsEvents_.size() > MAX_EVENTS) {
38         dmsEvents_.pop_front();
39     }
40     ZLOGI("Received dms event, eventType: %{public}d, srcNetworkId: %{public}s, srcBundleName: %{public}s, "
41         "dstNetworkId: %{public}s, destBundleName: %{public}s", event.dSchedEventType_,
42         DistributedData::Anonymous::Change(event.srcNetworkId_).c_str(), event.srcBundleName_.c_str(),
43         DistributedData::Anonymous::Change(event.dstNetworkId_).c_str(), event.destBundleName_.c_str());
44 }
45 
IsContinue(const std::string & bundleName)46 bool ObjectDmsHandler::IsContinue(const std::string &bundleName)
47 {
48     std::lock_guard<std::mutex> lock(mutex_);
49     auto validityTime = std::chrono::steady_clock::now() - std::chrono::seconds(VALIDITY);
50     DistributedHardware::DmDeviceInfo localDeviceInfo;
51     DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, localDeviceInfo);
52     for (auto it = dmsEvents_.rbegin(); it != dmsEvents_.rend(); ++it) {
53         if (it->second < validityTime) {
54             continue;
55         }
56         if (it->first.dSchedEventType_ != DistributedSchedule::DMS_CONTINUE) {
57             continue;
58         }
59         if (it->first.srcNetworkId_ == localDeviceInfo.networkId && it->first.srcBundleName_ == bundleName) {
60             ZLOGI("Continue source, networkId: %{public}s, bundleName: %{public}s",
61                 DistributedData::Anonymous::Change(localDeviceInfo.networkId).c_str(), bundleName.c_str());
62             return true;
63         }
64         if (it->first.dstNetworkId_ == localDeviceInfo.networkId && it->first.destBundleName_ == bundleName) {
65             ZLOGI("Continue destination, networkId: %{public}s, bundleName: %{public}s",
66                 DistributedData::Anonymous::Change(localDeviceInfo.networkId).c_str(), bundleName.c_str());
67             return true;
68         }
69     }
70     ZLOGW("Not in continue, networkId: %{public}s, bundleName: %{public}s",
71         DistributedData::Anonymous::Change(localDeviceInfo.networkId).c_str(), bundleName.c_str());
72     return false;
73 }
74 
GetDstBundleName(const std::string & srcBundleName,const std::string & dstNetworkId)75 std::string ObjectDmsHandler::GetDstBundleName(const std::string &srcBundleName, const std::string &dstNetworkId)
76 {
77     std::lock_guard<std::mutex> lock(mutex_);
78     auto validityTime = std::chrono::steady_clock::now() - std::chrono::seconds(VALIDITY);
79     DistributedHardware::DmDeviceInfo localDeviceInfo;
80     DistributedHardware::DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, localDeviceInfo);
81     for (auto it = dmsEvents_.rbegin(); it != dmsEvents_.rend(); ++it) {
82         if (it->second < validityTime) {
83             continue;
84         }
85         if (it->first.dSchedEventType_ != DistributedSchedule::DMS_CONTINUE) {
86             continue;
87         }
88         if (it->first.srcNetworkId_ == localDeviceInfo.networkId && it->first.srcBundleName_ == srcBundleName &&
89             it->first.dstNetworkId_ == dstNetworkId) {
90             ZLOGI("In continue, srcBundleName: %{public}s, dstBundleName: %{public}s",
91                 srcBundleName.c_str(), it->first.destBundleName_.c_str());
92             return it->first.destBundleName_;
93         }
94     }
95     ZLOGW("Not in continue, srcBundleName: %{public}s, srcNetworkId: %{public}s",
96         srcBundleName.c_str(), DistributedData::Anonymous::Change(localDeviceInfo.networkId).c_str());
97     return srcBundleName;
98 }
99 
RegisterDmsEvent()100 void ObjectDmsHandler::RegisterDmsEvent()
101 {
102     ZLOGI("Start register dms event");
103     if (dmsEventListener_ == nullptr) {
104         dmsEventListener_ = sptr<DistributedSchedule::IDSchedEventListener>(new DmsEventListener);
105     }
106     if (dmsEventListener_ == nullptr) {
107         ZLOGE("Register dms event listener failed, listener is nullptr");
108         return;
109     }
110     auto status = DistributedSchedule::DmsHandler::GetInstance().RegisterDSchedEventListener(
111         DistributedSchedule::DSchedEventType::DMS_ALL, dmsEventListener_);
112     if (status != 0) {
113         ZLOGE("Register dms event listener failed, status: %{public}d", status);
114     }
115 }
116 }