1 /*
2 * Copyright (c) 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 "net_policy_file_event_handler.h"
17
18 #include <fcntl.h>
19 #include <fstream>
20 #include <iostream>
21 #include <sys/stat.h>
22 #include <thread>
23 #include <unistd.h>
24
25 #include "net_mgr_log_wrapper.h"
26 #include "net_policy_inner_define.h"
27
28 namespace OHOS {
29 namespace NetManagerStandard {
30 namespace {
31 constexpr uint32_t MAX_TIME_MS_DELTA = 5000;
32 constexpr uint32_t SEND_TIME_MS_INTERVAL = 2000;
33
GetNowMilliSeconds()34 int64_t GetNowMilliSeconds()
35 {
36 auto nowSys = AppExecFwk::InnerEvent::Clock::now();
37 auto epoch = nowSys.time_since_epoch();
38 return std::chrono::duration_cast<std::chrono::milliseconds>(epoch).count();
39 }
40 } // namespace
41
NetPolicyFileEventHandler(const char * queueName)42 NetPolicyFileEventHandler::NetPolicyFileEventHandler(const char *queueName) : netPolicyFileEventQueue_(queueName) {}
43
SendWriteEvent(AppExecFwk::InnerEvent::Pointer & event)44 void NetPolicyFileEventHandler::SendWriteEvent(AppExecFwk::InnerEvent::Pointer &event)
45 {
46 SendEvent(event);
47 }
48
SendEvent(const AppExecFwk::InnerEvent::Pointer & event,uint32_t delayTime)49 void NetPolicyFileEventHandler::SendEvent(const AppExecFwk::InnerEvent::Pointer &event, uint32_t delayTime)
50 {
51 auto eventId = event->GetInnerEventId();
52 auto eventData = event->GetSharedObject<PolicyFileEvent>();
53 netPolicyFileEventQueue_.submit([this, eventId, eventData] { ProcessEvent(eventId, eventData); },
54 ffrt::task_attr().delay(static_cast<uint64_t>(delayTime)).name("FfrtSendEvent"));
55 }
56
ProcessEvent(uint32_t eventId,std::shared_ptr<PolicyFileEvent> eventData)57 void NetPolicyFileEventHandler::ProcessEvent(uint32_t eventId, std::shared_ptr<PolicyFileEvent> eventData)
58 {
59 if (eventId == MSG_POLICY_FILE_WRITE) {
60 fileContent_ = eventData->json;
61 if (commitWait_) {
62 return;
63 }
64 int64_t timeDelta = GetNowMilliSeconds() - timeStamp_;
65 uint32_t delay = timeDelta >= MAX_TIME_MS_DELTA ? 0 : static_cast<uint32_t>(MAX_TIME_MS_DELTA - timeDelta);
66 commitWait_ = true;
67 NETMGR_LOG_D("SendEvent MSG_POLICY_FILE_COMMIT[delay=%{public}d, now=%{public}s]", delay,
68 std::to_string(GetNowMilliSeconds()).c_str());
69 SendEvent(AppExecFwk::InnerEvent::Get(MSG_POLICY_FILE_COMMIT, std::make_shared<PolicyFileEvent>()), delay);
70 return;
71 }
72
73 if (eventId == MSG_POLICY_FILE_COMMIT) {
74 commitWait_ = !Write();
75 timeStamp_ = GetNowMilliSeconds();
76 if (commitWait_) {
77 SendEvent(AppExecFwk::InnerEvent::Get(MSG_POLICY_FILE_COMMIT, std::make_shared<PolicyFileEvent>()),
78 MAX_TIME_MS_DELTA);
79 }
80 SendEvent(AppExecFwk::InnerEvent::Get(MSG_POLICY_FILE_DELETE, std::make_shared<PolicyFileEvent>()),
81 SEND_TIME_MS_INTERVAL);
82 return;
83 }
84
85 if (MSG_POLICY_FILE_DELETE == eventId) {
86 DeleteBak();
87 }
88 }
89
Write()90 bool NetPolicyFileEventHandler::Write()
91 {
92 NETMGR_LOG_D("write file to disk.");
93 struct stat buffer;
94 if (stat(POLICY_FILE_NAME, &buffer) == 0) {
95 std::ifstream oldFile(POLICY_FILE_NAME, std::ios::binary);
96 std::ofstream newFile(POLICY_FILE_BAK_NAME, std::ios::binary);
97 if (!oldFile.is_open() && !newFile.is_open()) {
98 NETMGR_LOG_E("File backup failed.");
99 return false;
100 }
101 newFile << oldFile.rdbuf();
102 oldFile.close();
103 newFile.close();
104 }
105 std::fstream file(POLICY_FILE_NAME, std::fstream::out | std::fstream::trunc);
106 if (!file.is_open()) {
107 NETMGR_LOG_E("open file error.");
108 return false;
109 }
110 file << fileContent_;
111 file.close();
112 return true;
113 }
114
DeleteBak()115 bool NetPolicyFileEventHandler::DeleteBak()
116 {
117 struct stat buffer;
118 if (stat(POLICY_FILE_BAK_NAME, &buffer) == 0) {
119 int32_t err = remove(POLICY_FILE_BAK_NAME);
120 if (err != 0) {
121 NETMGR_LOG_E("remove file error.");
122 return false;
123 }
124 int fd = open(POLICY_FILE_BAK_PATH, O_RDONLY);
125 if (fd == -1) {
126 NETMGR_LOG_E("open the file path failed.");
127 return false;
128 }
129 if (fsync(fd) != 0) {
130 NETMGR_LOG_E("fsync the file path failed.");
131 close(fd);
132 return false;
133 }
134 close(fd);
135 }
136 return true;
137 }
138 } // namespace NetManagerStandard
139 } // namespace OHOS
140