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 #include "sys_event_sequence_mgr.h"
17 
18 #include <fstream>
19 
20 #include "file_util.h"
21 #include "hiview_logger.h"
22 #include "sys_event_dao.h"
23 
24 namespace OHOS {
25 namespace HiviewDFX {
26 namespace EventStore {
27 namespace {
28 DEFINE_LOG_TAG("HiView-SysEventSeqMgr");
29 constexpr char SEQ_PERSISTS_FILE_NAME[] = "event_sequence";
30 
SaveStringToFile(const std::string & filePath,const std::string & content)31 bool SaveStringToFile(const std::string& filePath, const std::string& content)
32 {
33     std::ofstream file;
34     file.open(filePath.c_str(), std::ios::in | std::ios::out);
35     if (!file.is_open()) {
36         file.open(filePath.c_str(), std::ios::out);
37         if (!file.is_open()) {
38             return false;
39         }
40     }
41     file.seekp(0);
42     file.write(content.c_str(), content.length() + 1);
43     bool ret = !file.fail();
44     file.close();
45     return ret;
46 }
47 }
48 
GetInstance()49 SysEventSequenceManager& SysEventSequenceManager::GetInstance()
50 {
51     static SysEventSequenceManager instance;
52     return instance;
53 }
54 
SysEventSequenceManager()55 SysEventSequenceManager::SysEventSequenceManager()
56 {
57     if (!FileUtil::FileExists(GetSequenceFile())) {
58         EventStore::SysEventDao::Restore();
59     }
60     int64_t seq = 0;
61     ReadSeqFromFile(seq);
62     curSeq_.store(seq, std::memory_order_release);
63 }
64 
SetSequence(int64_t seq)65 void SysEventSequenceManager::SetSequence(int64_t seq)
66 {
67     curSeq_.store(seq, std::memory_order_release);
68     WriteSeqToFile(seq);
69 }
70 
GetSequence()71 int64_t SysEventSequenceManager::GetSequence()
72 {
73     return curSeq_.load(std::memory_order_acquire);
74 }
75 
WriteSeqToFile(int64_t seq)76 void SysEventSequenceManager::WriteSeqToFile(int64_t seq)
77 {
78     std::string seqFile(GetSequenceFile());
79     std::string content(std::to_string(seq));
80     if (!SaveStringToFile(seqFile, content)) {
81         HIVIEW_LOGE("failed to write sequence %{public}s.", content.c_str());
82     }
83 }
84 
ReadSeqFromFile(int64_t & seq)85 void SysEventSequenceManager::ReadSeqFromFile(int64_t& seq)
86 {
87     std::string content;
88     std::string seqFile = GetSequenceFile();
89     if (!FileUtil::LoadStringFromFile(seqFile, content)) {
90         HIVIEW_LOGE("failed to read sequence value from %{public}s.", seqFile.c_str());
91         return;
92     }
93     seq = static_cast<int64_t>(strtoll(content.c_str(), nullptr, 0));
94     HIVIEW_LOGI("read sequence successful, value is %{public}" PRId64 ".", seq);
95 }
96 
GetSequenceFile() const97 std::string SysEventSequenceManager::GetSequenceFile() const
98 {
99     return EventStore::SysEventDao::GetDatabaseDir() + SEQ_PERSISTS_FILE_NAME;
100 }
101 } // EventStore
102 } // HiviewDFX
103 } // OHOS