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 std::shared_ptr<AppExecFwk::EventRunner> & runner)42 NetPolicyFileEventHandler::NetPolicyFileEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> &runner)
43 : EventHandler(runner)
44 {
45 }
46
SendWriteEvent(AppExecFwk::InnerEvent::Pointer & event)47 void NetPolicyFileEventHandler::SendWriteEvent(AppExecFwk::InnerEvent::Pointer &event)
48 {
49 SendEvent(event);
50 }
51
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)52 void NetPolicyFileEventHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
53 {
54 if ((event == nullptr) || !GetEventRunner()) {
55 NETMGR_LOG_E("parameter error (%d)", event == nullptr);
56 return;
57 }
58
59 auto eventId = event->GetInnerEventId();
60 auto eventData = event->GetSharedObject<PolicyFileEvent>();
61
62 if (eventId == MSG_POLICY_FILE_WRITE) {
63 fileContent_ = eventData->json;
64 if (commitWait_) {
65 return;
66 }
67 int64_t timeDelta = GetNowMilliSeconds() - timeStamp_;
68 uint32_t delay = timeDelta >= MAX_TIME_MS_DELTA ? 0 : static_cast<uint32_t>(MAX_TIME_MS_DELTA - timeDelta);
69 commitWait_ = true;
70 NETMGR_LOG_D("SendEvent MSG_POLICY_FILE_COMMIT[delay=%{public}d, now=%{public}s]", delay,
71 std::to_string(GetNowMilliSeconds()).c_str());
72 SendEvent(AppExecFwk::InnerEvent::Get(MSG_POLICY_FILE_COMMIT, std::make_shared<PolicyFileEvent>()), delay,
73 Priority::HIGH);
74 return;
75 }
76
77 if (eventId == MSG_POLICY_FILE_COMMIT) {
78 commitWait_ = !Write();
79 timeStamp_ = GetNowMilliSeconds();
80 if (commitWait_) {
81 SendEvent(AppExecFwk::InnerEvent::Get(MSG_POLICY_FILE_COMMIT, std::make_shared<PolicyFileEvent>()),
82 MAX_TIME_MS_DELTA, Priority::HIGH);
83 }
84 SendEvent(AppExecFwk::InnerEvent::Get(MSG_POLICY_FILE_DELETE, std::make_shared<PolicyFileEvent>()),
85 SEND_TIME_MS_INTERVAL, Priority::HIGH);
86 return;
87 }
88
89 if (MSG_POLICY_FILE_DELETE == eventId) {
90 DeleteBak();
91 }
92 }
93
Write()94 bool NetPolicyFileEventHandler::Write()
95 {
96 NETMGR_LOG_D("write file to disk.");
97 struct stat buffer;
98 if (stat(POLICY_FILE_NAME, &buffer) == 0) {
99 std::ifstream oldFile(POLICY_FILE_NAME, std::ios::binary);
100 std::ofstream newFile(POLICY_FILE_BAK_NAME, std::ios::binary);
101 if (!oldFile.is_open() && !newFile.is_open()) {
102 NETMGR_LOG_E("File backup failed.");
103 return false;
104 }
105 newFile << oldFile.rdbuf();
106 oldFile.close();
107 newFile.close();
108 }
109 std::fstream file(POLICY_FILE_NAME, std::fstream::out | std::fstream::trunc);
110 if (!file.is_open()) {
111 NETMGR_LOG_E("open file error.");
112 return false;
113 }
114 file << fileContent_;
115 file.close();
116 return true;
117 }
118
DeleteBak()119 bool NetPolicyFileEventHandler::DeleteBak()
120 {
121 struct stat buffer;
122 if (stat(POLICY_FILE_BAK_NAME, &buffer) == 0) {
123 int32_t err = remove(POLICY_FILE_BAK_NAME);
124 sync();
125 if (err != 0) {
126 NETMGR_LOG_E("remove file error.");
127 return false;
128 }
129 }
130 return true;
131 }
132 } // namespace NetManagerStandard
133 } // namespace OHOS
134