• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "data_publisher.h"
17 
18 #include <cerrno>
19 #include <cstdlib>
20 #include <map>
21 #include <set>
22 #include <string>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 #include <utility>
27 #include <vector>
28 
29 #include "data_publisher_sys_event_callback.h"
30 #include "data_share_common.h"
31 #include "data_share_dao.h"
32 #include "data_share_store.h"
33 #include "data_share_util.h"
34 #include "event_publish.h"
35 #include "event_thread_pool.h"
36 #include "file_util.h"
37 #include "hisysevent.h"
38 #include "hiview_event_common.h"
39 #include "iquery_base_callback.h"
40 #include "json/json.h"
41 #include "logger.h"
42 #include "ret_code.h"
43 #include "string_util.h"
44 #include "sys_event_query.h"
45 #include "time_util.h"
46 
47 using namespace OHOS::HiviewDFX::SubscribeStore;
48 using namespace OHOS::HiviewDFX::BaseEventSpace;
49 
50 namespace OHOS {
51 namespace HiviewDFX {
52 DEFINE_LOG_TAG("HiView-DataPublisher");
53 namespace {
GetBundleNameFromJsonStr(const std::string & jsonInfo)54 std::string GetBundleNameFromJsonStr(const std::string& jsonInfo)
55 {
56     std::string bundleName = "";
57     Json::Value root;
58     Json::Reader reader;
59     if (!reader.parse(jsonInfo, root)) {
60         HIVIEW_LOGE("failed to parse jsonInfo.");
61         return bundleName;
62     }
63     if (root[BUNDLE_NAME].isString()) {
64         bundleName = root[BUNDLE_NAME].asString();
65     }
66     return bundleName;
67 }
68 }  // namespace
69 
DataPublisher()70 DataPublisher::DataPublisher()
71 {
72     this->InitSubscriber();
73 }
74 
AddSubscriber(int32_t uid,const std::vector<std::string> & eventList)75 int32_t DataPublisher::AddSubscriber(int32_t uid, const std::vector<std::string> &eventList)
76 {
77     std::string events;
78     std::shared_ptr<DataShareDao> dataShareDao = GetDataShareDao();
79     auto ret = dataShareDao->GetEventListByUid(uid, events);
80     if (ret != DB_SUCC) {
81         HIVIEW_LOGE("query DB failed.");
82         return ret;
83     }
84     std::vector<std::string> oldEventList;
85     StringUtil::SplitStr(events, ";", oldEventList);
86     for (auto &event : oldEventList) {
87         eventRelationMap_[event].erase(uid);
88     }
89     for (auto &event : eventList) {
90         eventRelationMap_[event].insert(uid);
91     }
92     auto newEvents = StringUtil::ConvertVectorToStr(eventList, ";");
93     ret = dataShareDao->SaveSubscriberInfo(uid, newEvents);
94     if (ret != DB_SUCC) {
95         HIVIEW_LOGE("query DB failed.");
96         return ret;
97     }
98     return IPC_CALL_SUCCEED;
99 }
100 
RemoveSubscriber(int32_t uid)101 int32_t DataPublisher::RemoveSubscriber(int32_t uid)
102 {
103     std::string events;
104     std::shared_ptr<DataShareDao> dataShareDao = GetDataShareDao();
105     auto ret = dataShareDao->GetEventListByUid(uid, events);
106     if (ret != DB_SUCC) {
107         HIVIEW_LOGE("failed to get events by uid");
108         return ERR_REMOVE_SUBSCRIBE;
109     }
110     if (events.empty()) {
111         HIVIEW_LOGE("events list is empty");
112         return ERR_REMOVE_SUBSCRIBE;
113     }
114     std::vector<std::string> eventList;
115     StringUtil::SplitStr(events, ";", eventList);
116     for (auto &event : eventList) {
117         eventRelationMap_[event].erase(uid);
118     }
119     ret = dataShareDao->DeleteSubscriberInfo(uid);
120     if (ret != DB_SUCC) {
121         HIVIEW_LOGE("failed to delete subscriberInfo");
122         return ERR_REMOVE_SUBSCRIBE;
123     }
124     return IPC_CALL_SUCCEED;
125 }
126 
InitSubscriber()127 void DataPublisher::InitSubscriber()
128 {
129     std::map<int, std::string> uidToEventsMap;
130     std::shared_ptr<DataShareDao> dataShareDao = GetDataShareDao();
131     int ret = dataShareDao->GetTotalSubscriberInfo(uidToEventsMap);
132     if (ret != DB_SUCC) {
133         HIVIEW_LOGE("failed to get total subscriberInfo");
134         return;
135     }
136     for (auto it = uidToEventsMap.begin(); it != uidToEventsMap.end(); ++it) {
137         int uid = it->first;
138         std::string events = it->second;
139         std::vector<std::string> eventList;
140         StringUtil::SplitStr(events, ";", eventList);
141         for (auto &event : eventList) {
142             eventRelationMap_[event].insert(uid);
143         }
144     }
145 }
146 
OnSysEvent(std::shared_ptr<OHOS::HiviewDFX::SysEvent> & event)147 void DataPublisher::OnSysEvent(std::shared_ptr<OHOS::HiviewDFX::SysEvent> &event)
148 {
149     HandleAppUninstallEvent(event);
150     HandleAppStartEvent(event);
151     if (eventRelationMap_.find(event->eventName_) == eventRelationMap_.end()) {
152         return;
153     }
154     if (!CreateHiviewTempDir()) {
155         HIVIEW_LOGE("failed to create resourceFile.");
156         return;
157     }
158     int64_t timestamp = static_cast<int64_t>(TimeUtil::GetMilliseconds());
159     std::string timeStr = std::to_string(timestamp);
160     std::string srcPath = TEMP_SRC_DIR;
161     if (looper_ != nullptr) {
162         auto task = std::bind(&DataPublisher::HandleSubscribeTask, this, event, srcPath, timeStr);
163         looper_->AddTimerEvent(nullptr, nullptr, task, DELAY_TIME, false);
164     } else {
165         HIVIEW_LOGW("looper_ is null, call the subscribe function directly.");
166         HandleSubscribeTask(event, srcPath, timeStr);
167     }
168 }
169 
HandleSubscribeTask(std::shared_ptr<OHOS::HiviewDFX::SysEvent> & event,std::string srcPath,std::string timeStr)170 void DataPublisher::HandleSubscribeTask(std::shared_ptr<OHOS::HiviewDFX::SysEvent> &event,
171     std::string srcPath, std::string timeStr)
172 {
173     std::string eventJson = event->AsJsonStr();
174     if (!FileUtil::SaveStringToFile(srcPath, eventJson + ",", true)) {
175         HIVIEW_LOGE("failed to persist eventJson to file.");
176         return;
177     }
178     std::set<int> uidSet = eventRelationMap_[event->eventName_];
179     std::string desPath;
180     for (auto uid : uidSet) {
181         desPath = OHOS::HiviewDFX::DataShareUtil::GetSandBoxPathByUid(uid);
182         desPath.append("/")
183             .append(event->domain_)
184             .append("-")
185             .append(timeStr)
186             .append("-")
187             .append(SUCCESS_CODE)
188             .append(FILE_SUFFIX);
189         auto res = OHOS::HiviewDFX::DataShareUtil::CopyFile(srcPath.c_str(), desPath.c_str());
190         if (res == -1) {
191             HIVIEW_LOGE("failed to move file to desPath.");
192         }
193         if (chmod(desPath.c_str(), FileUtil::FILE_PERM_666)) {
194             HIVIEW_LOGE("Failed to chmod socket.");
195         }
196     }
197 }
198 
HandleAppUninstallEvent(std::shared_ptr<OHOS::HiviewDFX::SysEvent> & event)199 void DataPublisher::HandleAppUninstallEvent(std::shared_ptr<OHOS::HiviewDFX::SysEvent> &event)
200 {
201     if (event->eventName_ != BUNDLE_UNINSTALL) {
202         return;
203     }
204     std::string jsonExtraInfo = event->AsJsonStr();
205     std::string bundleName = GetBundleNameFromJsonStr(jsonExtraInfo);
206     if (bundleName.empty()) {
207         return;
208     }
209     int32_t uid = -1;
210     std::shared_ptr<DataShareDao> dataShareDao = GetDataShareDao();
211     auto ret = dataShareDao->GetUidByBundleName(bundleName, uid);
212     if (ret != DB_SUCC) {
213         HIVIEW_LOGE("failed to query from DB.");
214         return;
215     }
216     ret = RemoveSubscriber(uid);
217     if (ret != DB_SUCC) {
218         HIVIEW_LOGE("failed to remove from DB.");
219     }
220 }
221 
HandleAppStartEvent(std::shared_ptr<OHOS::HiviewDFX::SysEvent> & event)222 void DataPublisher::HandleAppStartEvent(std::shared_ptr<OHOS::HiviewDFX::SysEvent> &event)
223 {
224     if (event->eventName_ != "APP_START") {
225         return;
226     }
227     std::string jsonExtraInfo = event->AsJsonStr();
228     std::string bundleName = GetBundleNameFromJsonStr(jsonExtraInfo);
229     if (bundleName.empty()) {
230         HIVIEW_LOGW("bundleName empty.");
231         return;
232     }
233     int32_t uid = OHOS::HiviewDFX::DataShareUtil::GetUidByBundleName(bundleName);
234     EventPublish::GetInstance().PushEvent(uid, event->eventName_, HiSysEvent::EventType::BEHAVIOR, jsonExtraInfo);
235 }
236 
SetWorkLoop(std::shared_ptr<EventLoop> looper)237 void DataPublisher::SetWorkLoop(std::shared_ptr<EventLoop> looper)
238 {
239     if (looper == nullptr) {
240         HIVIEW_LOGW("SetWorkLoop failed, looper is null.");
241         return;
242     }
243     looper_ = looper;
244 }
245 
AddExportTask(std::shared_ptr<BaseEventQueryWrapper> queryWrapper,int64_t timestamp,int32_t uid)246 void DataPublisher::AddExportTask(std::shared_ptr<BaseEventQueryWrapper> queryWrapper, int64_t timestamp, int32_t uid)
247 {
248     auto iter = uidTimeStampMap_.find(uid);
249     if (iter != uidTimeStampMap_.end()) {
250         iter->second = timestamp;
251     } else {
252         uidTimeStampMap_[uid] = timestamp;
253     }
254     if (!CreateHiviewTempDir()) {
255         HIVIEW_LOGE("failed to create resourceFile.");
256         return;
257     }
258     std::string timeStr = std::to_string(timestamp);
259     std::string srcPath = TEMP_EXPORT_SRC_DIR;
260     if (!FileUtil::RemoveFile(srcPath)) {
261         HIVIEW_LOGE("failed to remove resourceFile.");
262     }
263     std::string desPath = OHOS::HiviewDFX::DataShareUtil::GetSandBoxPathByUid(uid);
264     desPath.append(DOMAIN_PATH);
265     desPath.append(timeStr);
266     if (looper_ != nullptr) {
267         auto task = [queryWrapper, srcPath, desPath] {
268             OHOS::sptr<OHOS::HiviewDFX::IQueryBaseCallback> exportCallback =
269                 new(std::nothrow) DataPublisherSysEventCallback(srcPath, desPath, 0, 0);
270             int32_t queryResult = 0;
271             queryWrapper->Query(exportCallback, queryResult);
272         };
273         looper_->AddTimerEvent(nullptr, nullptr, task, DELAY_TIME, false);
274     } else {
275         static OHOS::sptr<OHOS::HiviewDFX::IQueryBaseCallback> exportCallback =
276             new(std::nothrow) DataPublisherSysEventCallback(srcPath, desPath, 0, 0);
277         int32_t queryResult = 0;
278         queryWrapper->Query(exportCallback, queryResult);
279     }
280 }
281 
CreateHiviewTempDir()282 bool DataPublisher::CreateHiviewTempDir()
283 {
284     if (!FileUtil::FileExists(PATH_DIR) && !FileUtil::ForceCreateDirectory(PATH_DIR)) {
285         HIVIEW_LOGE("failed to create events dir.");
286         return false;
287     }
288     return true;
289 }
290 
GetTimeStampByUid(int32_t uid)291 int64_t DataPublisher::GetTimeStampByUid(int32_t uid)
292 {
293     int64_t timeStamp;
294     auto iter = uidTimeStampMap_.find(uid);
295     if (iter != uidTimeStampMap_.end()) {
296         timeStamp = iter->second;
297     } else {
298         timeStamp = 0;
299     }
300     return timeStamp;
301 }
302 
GetDataShareDao()303 std::shared_ptr<DataShareDao> DataPublisher::GetDataShareDao()
304 {
305     std::shared_ptr<DataShareStore> dataShareStore = std::make_shared<DataShareStore>(DATABASE_DIR);
306     return std::make_shared<DataShareDao>(dataShareStore);
307 }
308 
309 }  // namespace HiviewDFX
310 }  // namespace OHOS