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 <mutex>
17 #include <string>
18 
19 #include "appevent_watcher_impl.h"
20 #include "app_event_observer_mgr.h"
21 #include "cj_ffi/cj_common_ffi.h"
22 #include "error.h"
23 #include "file_util.h"
24 #include "hiappevent_clean.h"
25 #include "hiappevent_config.h"
26 #include "hiappevent_impl.h"
27 #include "hiappevent_read.h"
28 #include "hiappevent_userinfo.h"
29 #include "hiappevent_verify.h"
30 #include "hiappevent_write.h"
31 #include "log.h"
32 #include "time_util.h"
33 
34 using namespace OHOS::HiviewDFX;
35 using namespace OHOS::HiviewDFX::HiAppEvent;
36 
37 namespace OHOS {
38 namespace CJSystemapi {
39 namespace HiAppEvent {
40 std::mutex g_mutex;
Configure(bool disable,const std::string & maxStorage)41 int HiAppEventImpl::Configure(bool disable, const std::string& maxStorage)
42 {
43     std::string disableStr = disable == true ? "true" : "false";
44     bool disableRes = HiAppEventConfig::GetInstance().SetConfigurationItem("disable", disableStr);
45     if (!disableRes) {
46         LOGE("HiAppEvent failed to configure disable HiAppEvent");
47         return ERR_INVALID_MAX_STORAGE;
48     }
49     bool maxStorageRes = HiAppEventConfig::GetInstance().SetConfigurationItem("max_storage", maxStorage);
50     if (!maxStorageRes) {
51         LOGE("HiAppEvent failed to configure maxStorage HiAppEvent");
52         return ERR_INVALID_MAX_STORAGE;
53     }
54     return SUCCESS_CODE;
55 }
56 
GetStorageDirPath()57 std::string GetStorageDirPath()
58 {
59     return HiAppEventConfig::GetInstance().GetStorageDir();
60 }
61 
GetMaxStorageSize()62 uint64_t GetMaxStorageSize()
63 {
64     return HiAppEventConfig::GetInstance().GetMaxStorageSize();
65 }
66 
GetStorageFileName()67 std::string GetStorageFileName()
68 {
69     return "app_event_" + TimeUtil::GetDate() + ".log";
70 }
71 
CheckStorageSpace(const std::string & dir)72 void CheckStorageSpace(const std::string& dir)
73 {
74     auto maxSize = GetMaxStorageSize();
75     if (!HiAppEventClean::IsStorageSpaceFull(dir, maxSize)) {
76         return;
77     }
78     LOGI("hiappevent dir space is full, start to clean");
79     HiAppEventClean::ReleaseSomeStorageSpace(dir, maxSize);
80 }
81 
WriteEventToFile(const std::string & filePath,const std::string & event)82 bool WriteEventToFile(const std::string& filePath, const std::string& event)
83 {
84     LogAssistant::Instance().RealTimeAppLogUpdate(event);
85     return FileUtil::SaveStringToFile(filePath, event);
86 }
87 
HiWriteEvent(std::shared_ptr<AppEventPack> appEventPack)88 void HiWriteEvent(std::shared_ptr<AppEventPack> appEventPack)
89 {
90     if (HiAppEventConfig::GetInstance().GetDisable()) {
91         LOGE("the HiAppEvent function is disabled.");
92         return;
93     }
94     if (appEventPack == nullptr) {
95         LOGE("appEventPack is null.");
96         return;
97     }
98     std::string dirPath = GetStorageDirPath();
99     if (dirPath.empty()) {
100         LOGE("dirPath is null, stop writing the event.");
101         return;
102     }
103     std::string event = appEventPack->GetEventStr();
104     {
105         std::lock_guard<std::mutex> lockGuard(g_mutex);
106         if (!FileUtil::IsFileExists(dirPath) && !FileUtil::ForceCreateDirectory(dirPath)) {
107             LOGE("failed to create hiappevent dir, errno=%{public}d.", errno);
108             return;
109         }
110         CheckStorageSpace(dirPath);
111         std::string filePath = FileUtil::GetFilePathByDir(dirPath, GetStorageFileName());
112         if (WriteEventToFile(filePath, event)) {
113             std::vector<std::shared_ptr<AppEventPack>> events;
114             events.emplace_back(appEventPack);
115             AppEventObserverMgr::GetInstance().HandleEvents(events);
116             return;
117         }
118         LOGE("failed to write event to log file, errno=%{public}d.", errno);
119     }
120 }
121 
Write(std::shared_ptr<HiviewDFX::AppEventPack> appEventPack)122 int HiAppEventImpl::Write(std::shared_ptr<HiviewDFX::AppEventPack> appEventPack)
123 {
124     if (auto ret = VerifyAppEvent(appEventPack); ret != 0) {
125         LOGE("HiAppEvent failed to write HiAppEvent %{public}d", ret);
126         return ret;
127     }
128     HiWriteEvent(appEventPack);
129     return SUCCESS_CODE;
130 }
131 
AddProcessor(const ReportConfig & conf)132 int64_t HiAppEventImpl::AddProcessor(const ReportConfig& conf)
133 {
134     int64_t processorId = AppEventObserverMgr::GetInstance().RegisterObserver(conf.name, conf);
135     if (processorId <= 0) {
136         LOGE("failed to add processor=%{public}s, register processor error", conf.name.c_str());
137         return processorId;
138     }
139     return processorId;
140 }
141 
RemoveProcessor(int64_t processorId)142 int HiAppEventImpl::RemoveProcessor(int64_t processorId)
143 {
144     if (processorId <= 0) {
145         LOGE("failed to remove processor id=%{public}" PRIi64 "", processorId);
146         return SUCCESS_CODE;
147     }
148     if (AppEventObserverMgr::GetInstance().UnregisterObserver(processorId) != 0) {
149         LOGE("failed to remove processor id=%{public}" PRIi64"", processorId);
150         return ERR_CODE_PARAM_INVALID;
151     }
152     return SUCCESS_CODE;
153 }
154 
SetUserId(const std::string & name,const std::string & value)155 int HiAppEventImpl::SetUserId(const std::string& name, const std::string& value)
156 {
157     if (value.empty()) {
158         if (UserInfo::GetInstance().RemoveUserId(name) != 0) {
159             LOGE("failed to remove userId");
160             return ERR_CODE_PARAM_INVALID;
161         }
162         return SUCCESS_CODE;
163     }
164     if (UserInfo::GetInstance().SetUserId(name, value) != 0) {
165         LOGE("failed to set userId");
166         return ERR_CODE_PARAM_INVALID;
167     }
168     return SUCCESS_CODE;
169 }
170 
GetUserId(const std::string & name)171 std::tuple<int, std::string> HiAppEventImpl::GetUserId(const std::string& name)
172 {
173     std::string strUserId;
174     if (UserInfo::GetInstance().GetUserId(name, strUserId) != 0) {
175         LOGE("failed to get userId");
176         return {ERR_CODE_PARAM_INVALID, nullptr};
177     }
178     return {SUCCESS_CODE, strUserId};
179 }
180 
SetUserProperty(const std::string & name,const std::string & value)181 int HiAppEventImpl::SetUserProperty(const std::string& name, const std::string& value)
182 {
183     if (value.empty()) {
184         if (UserInfo::GetInstance().RemoveUserProperty(name) != 0) {
185             LOGE("failed to set user propertyd");
186             return ERR_CODE_PARAM_INVALID;
187         }
188         return SUCCESS_CODE;
189     }
190     if (UserInfo::GetInstance().SetUserProperty(name, value) != 0) {
191         LOGE("failed to set user property");
192         return ERR_CODE_PARAM_INVALID;
193     }
194     return SUCCESS_CODE;
195 }
196 
GetUserProperty(const std::string & name)197 std::tuple<int, std::string> HiAppEventImpl::GetUserProperty(const std::string& name)
198 {
199     std::string strUserProperty;
200     if (UserInfo::GetInstance().GetUserProperty(name, strUserProperty) != 0) {
201         LOGE("failed to get user property");
202         return {ERR_CODE_PARAM_INVALID, nullptr};
203     }
204     return {SUCCESS_CODE, strUserProperty};
205 }
206 
ClearData()207 void HiAppEventImpl::ClearData()
208 {
209     std::string dir = HiAppEventConfig::GetInstance().GetStorageDir();
210     HiAppEventClean::ClearData(dir);
211 }
212 
addWatcher(const std::string & name,const std::vector<AppEventFilter> & filters,const TriggerCondition & cond,void (* callbackOnTriggerRef)(int,int,int64_t),void (* callbackOnReceiveRef)(char *,CArrRetAppEventGroup))213 std::tuple<int, int64_t> HiAppEventImpl::addWatcher(const std::string& name,
214                                                     const std::vector<AppEventFilter>& filters,
215                                                     const TriggerCondition& cond,
216                                                     void (*callbackOnTriggerRef)(int, int, int64_t),
217                                                     void (*callbackOnReceiveRef)(char*, CArrRetAppEventGroup))
218 {
219     auto watcherPtr = std::make_shared<AppEventWatcherImpl>(name, filters, cond);
220     if (callbackOnTriggerRef != (void*)-1) {
221         watcherPtr->InitTrigger(callbackOnTriggerRef);
222     }
223     if (callbackOnReceiveRef != (void*)-1) {
224         watcherPtr->InitReceiver(callbackOnReceiveRef);
225     }
226     int64_t observerSeq = AppEventObserverMgr::GetInstance().RegisterObserver(watcherPtr);
227     if (observerSeq <= 0) {
228         LOGE("invalid observer sequence");
229         return {ERR_CODE_PARAM_INVALID, -1};
230     }
231     auto holder = OHOS::FFI::FFIData::Create<AppEventPackageHolderImpl>(name, -1);
232     if (holder == nullptr) {
233         return {ERR_PARAM, -1};
234     }
235     watcherPtr->InitHolder(holder);
236     return {SUCCESS_CODE, holder->GetID()};
237 }
238 
removeWatcher(const std::string & name)239 void HiAppEventImpl::removeWatcher(const std::string& name)
240 {
241     AppEventObserverMgr::GetInstance().UnregisterObserver(name);
242 }
243 
Load(const std::string & moduleName)244 int HiAppEventImpl::Load(const std::string& moduleName)
245 {
246     return AppEventObserverMgr::GetInstance().Load(moduleName);
247 }
248 } // HiAppEvent
249 } // CJSystemapi
250 } // OHOS