1 /*
2  * Copyright (C) 2022-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 #define LOG_TAG "HiViewAdapter"
17 
18 #include "hiview_adapter.h"
19 
20 #include <algorithm>
21 #include <unistd.h>
22 #include <pthread.h>
23 #include <thread>
24 
25 #include "def.h"
26 #include "pasteboard_hilog.h"
27 #include "pasteboard_error.h"
28 #include "time_service_client.h"
29 
30 namespace OHOS {
31 using namespace HiviewDFX;
32 namespace MiscServices {
33 namespace {
34 const std::map<int, std::string> EVENT_COVERT_TABLE = {
35     { DfxCodeConstant::PASTEBOARD_FAULT, "PASTEBOARD_FAULT" },
36     { DfxCodeConstant::TIME_CONSUMING_STATISTIC, "TIME_CONSUMING_STATISTIC" },
37     { DfxCodeConstant::PASTEBOARD_BEHAVIOUR, "PASTEBOARD_BEHAVIOUR" },
38     { DfxCodeConstant::USE_BEHAVIOUR, "USE_BEHAVIOUR" },
39 };
40 } // namespace
41 
42 bool HiViewAdapter::running_ = false;
43 std::mutex HiViewAdapter::runMutex_;
44 std::mutex HiViewAdapter::timeConsumingMutex_;
45 std::mutex HiViewAdapter::behaviourMutex_;
46 std::vector<std::map<int, int>> HiViewAdapter::copyTimeConsumingStat_;
47 std::vector<std::map<int, int>> HiViewAdapter::pasteTimeConsumingStat_;
48 std::vector<std::map<int, int>> HiViewAdapter::remotePasteTimeConsumingStat_;
49 
50 std::map<std::string, int> HiViewAdapter::copyPasteboardBehaviour_;
51 std::map<std::string, int> HiViewAdapter::pastePasteboardBehaviour_;
52 std::map<std::string, int> HiViewAdapter::remotePastePasteboardBehaviour_;
53 
54 std::map<int, int> HiViewAdapter::dataMap_ = HiViewAdapter::InitDataMap();
55 std::map<int, int> HiViewAdapter::timeMap_ = HiViewAdapter::InitTimeMap();
56 
InitDataMap()57 std::map<int, int> HiViewAdapter::InitDataMap()
58 {
59     std::map<int, int> dataMap;
60     dataMap.insert(std::pair<int, int>(
61         static_cast<int>(DataRange::DR_ZERO_TO_HUNDRED_KB), static_cast<int>(DataConsumingLevel::DATA_LEVEL_ONE)));
62     dataMap.insert(std::pair<int, int>(static_cast<int>(DataRange::DR_HUNDRED_TO_FIVE_HUNDREDS_KB),
63         static_cast<int>(DataConsumingLevel::DATA_LEVEL_TWO)));
64     dataMap.insert(std::pair<int, int>(static_cast<int>(DataRange::DR_FIVE_HUNDREDS_TO_THOUSAND_KB),
65         static_cast<int>(DataConsumingLevel::DATA_LEVEL_THREE)));
66     dataMap.insert(std::pair<int, int>(
67         static_cast<int>(DataRange::DR_ONE_TO_FIVE_MB), static_cast<int>(DataConsumingLevel::DATA_LEVEL_FOUR)));
68     dataMap.insert(std::pair<int, int>(
69         static_cast<int>(DataRange::DR_FIVE_TO_TEN_MB), static_cast<int>(DataConsumingLevel::DATA_LEVEL_FIVE)));
70     dataMap.insert(std::pair<int, int>(
71         static_cast<int>(DataRange::DR_TEN_TO_FIFTY_MB), static_cast<int>(DataConsumingLevel::DATA_LEVEL_SIX)));
72     dataMap.insert(std::pair<int, int>(
73         static_cast<int>(DataRange::DR_OVER_FIFTY_MB), static_cast<int>(DataConsumingLevel::DATA_LEVEL_SEVEN)));
74     return dataMap;
75 }
76 
InitTimeMap()77 std::map<int, int> HiViewAdapter::InitTimeMap()
78 {
79     std::map<int, int> timeMap;
80     timeMap.insert(std::pair<int, int>(static_cast<int>(TimeConsumingStatistic::TCS_TIME_CONSUMING_LEVEL_ONE),
81         static_cast<int>(TimeConsumingLevel::TIME_LEVEL_ONE)));
82     timeMap.insert(std::pair<int, int>(static_cast<int>(TimeConsumingStatistic::TCS_TIME_CONSUMING_LEVEL_TWO),
83         static_cast<int>(TimeConsumingLevel::TIME_LEVEL_TWO)));
84     timeMap.insert(std::pair<int, int>(static_cast<int>(TimeConsumingStatistic::TCS_TIME_CONSUMING_LEVEL_THREE),
85         static_cast<int>(TimeConsumingLevel::TIME_LEVEL_THREE)));
86     timeMap.insert(std::pair<int, int>(static_cast<int>(TimeConsumingStatistic::TCS_TIME_CONSUMING_LEVEL_FOUR),
87         static_cast<int>(TimeConsumingLevel::TIME_LEVEL_FOUR)));
88     timeMap.insert(std::pair<int, int>(static_cast<int>(TimeConsumingStatistic::TCS_TIME_CONSUMING_LEVEL_FIVE),
89         static_cast<int>(TimeConsumingLevel::TIME_LEVEL_FIVE)));
90     timeMap.insert(std::pair<int, int>(static_cast<int>(TimeConsumingStatistic::TCS_TIME_CONSUMING_LEVEL_SIX),
91         static_cast<int>(TimeConsumingLevel::TIME_LEVEL_SIX)));
92     timeMap.insert(std::pair<int, int>(static_cast<int>(TimeConsumingStatistic::TCS_TIME_CONSUMING_LEVEL_SEVEN),
93         static_cast<int>(TimeConsumingLevel::TIME_LEVEL_SEVEN)));
94     timeMap.insert(std::pair<int, int>(static_cast<int>(TimeConsumingStatistic::TCS_TIME_CONSUMING_LEVEL_EIGHT),
95         static_cast<int>(TimeConsumingLevel::TIME_LEVEL_EIGHT)));
96     timeMap.insert(std::pair<int, int>(static_cast<int>(TimeConsumingStatistic::TCS_TIME_CONSUMING_LEVEL_NINE),
97         static_cast<int>(TimeConsumingLevel::TIME_LEVEL_NINE)));
98     timeMap.insert(std::pair<int, int>(static_cast<int>(TimeConsumingStatistic::TCS_TIME_CONSUMING_LEVEL_TEN),
99         static_cast<int>(TimeConsumingLevel::TIME_LEVEL_TEN)));
100     timeMap.insert(std::pair<int, int>(static_cast<int>(TimeConsumingStatistic::TCS_TIME_CONSUMING_LEVEL_ELEVEN),
101         static_cast<int>(TimeConsumingLevel::TIME_LEVEL_ELEVEN)));
102     return timeMap;
103 }
104 
ReportPasteboardFault(int dfxCode,const PasteboardFaultMsg & msg)105 void HiViewAdapter::ReportPasteboardFault(int dfxCode, const PasteboardFaultMsg &msg)
106 {
107     HiSysEventParam params[] = {
108         {.name = "USER_ID", .t = HISYSEVENT_INT32, .v = { .i32 = msg.userId }, .arraySize = 0, },
109         {.name = "ERROR_TYPE", .t = HISYSEVENT_STRING, .v = { .s = (char *)msg.errorCode.c_str() }, .arraySize = 0, },
110     };
111     size_t len = sizeof(params) / sizeof(params[0]);
112     int ret = OH_HiSysEvent_Write(PASTEBOARD_DOMAIN, CoverEventID(dfxCode).c_str(), HISYSEVENT_FAULT,
113         params, len);
114     if (ret != 0) {
115         PASTEBOARD_HILOGD(
116             PASTEBOARD_MODULE_SERVICE, "hisysevent write failed! ret %{public}d. errCode %{public}d", ret, dfxCode);
117     }
118 }
119 
InitializeTimeConsuming(int initFlag)120 void HiViewAdapter::InitializeTimeConsuming(int initFlag)
121 {
122     constexpr const int DATA_LEVEL_NUMBERS = 7;
123     std::map<int, int> initTimeConsuming;
124     initTimeConsuming.insert(std::pair<int, int>(static_cast<int>(TimeConsumingLevel::TIME_LEVEL_ONE), 0));
125     initTimeConsuming.insert(std::pair<int, int>(static_cast<int>(TimeConsumingLevel::TIME_LEVEL_TWO), 0));
126     initTimeConsuming.insert(std::pair<int, int>(static_cast<int>(TimeConsumingLevel::TIME_LEVEL_THREE), 0));
127     initTimeConsuming.insert(std::pair<int, int>(static_cast<int>(TimeConsumingLevel::TIME_LEVEL_FOUR), 0));
128     initTimeConsuming.insert(std::pair<int, int>(static_cast<int>(TimeConsumingLevel::TIME_LEVEL_FIVE), 0));
129     initTimeConsuming.insert(std::pair<int, int>(static_cast<int>(TimeConsumingLevel::TIME_LEVEL_SIX), 0));
130     initTimeConsuming.insert(std::pair<int, int>(static_cast<int>(TimeConsumingLevel::TIME_LEVEL_SEVEN), 0));
131     initTimeConsuming.insert(std::pair<int, int>(static_cast<int>(TimeConsumingLevel::TIME_LEVEL_EIGHT), 0));
132     initTimeConsuming.insert(std::pair<int, int>(static_cast<int>(TimeConsumingLevel::TIME_LEVEL_NINE), 0));
133     initTimeConsuming.insert(std::pair<int, int>(static_cast<int>(TimeConsumingLevel::TIME_LEVEL_TEN), 0));
134     initTimeConsuming.insert(std::pair<int, int>(static_cast<int>(TimeConsumingLevel::TIME_LEVEL_ELEVEN), 0));
135 
136     if (initFlag == INIT_COPY_TIME_SONSUMING) {
137         for (int i = 0; i < DATA_LEVEL_NUMBERS; ++i) {
138             copyTimeConsumingStat_.push_back(initTimeConsuming);
139             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "copyTimeConsumingStat_.push_back");
140         }
141     } else if (initFlag == INIT_PASTE_TIME_SONSUMING) {
142         for (int i = 0; i < DATA_LEVEL_NUMBERS; ++i) {
143             pasteTimeConsumingStat_.push_back(initTimeConsuming);
144             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "pasteTimeConsumingStat_.push_back");
145         }
146     } else {
147         for (int i = 0; i < DATA_LEVEL_NUMBERS; ++i) {
148             remotePasteTimeConsumingStat_.push_back(initTimeConsuming);
149             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "remotePasteTimeConsumingStat_.push_back");
150         }
151     }
152 }
153 
ReportTimeConsumingStatistic(const TimeConsumingStat & stat)154 void HiViewAdapter::ReportTimeConsumingStatistic(const TimeConsumingStat &stat)
155 {
156     std::lock_guard<std::mutex> lock(timeConsumingMutex_);
157     if (copyTimeConsumingStat_.empty()) {
158         InitializeTimeConsuming(INIT_COPY_TIME_SONSUMING);
159     }
160     if (pasteTimeConsumingStat_.empty()) {
161         InitializeTimeConsuming(INIT_PASTE_TIME_SONSUMING);
162     }
163     if (remotePasteTimeConsumingStat_.empty()) {
164         InitializeTimeConsuming(INIT_REMOTE_PASTE_TIME_SONSUMING);
165     }
166 
167     if (stat.pasteboardState == static_cast<int>(StatisticPasteboardState::SPS_COPY_STATE)) {
168         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "hisysevent pasteboard state is %{public}d", stat.pasteboardState);
169         auto iter = dataMap_.find(stat.dataSize);
170         if (iter != dataMap_.end()) {
171             CopyTimeConsuming(stat, iter->second);
172         } else {
173             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "wrong data level");
174         }
175     } else if ((stat.pasteboardState == static_cast<int>(StatisticPasteboardState::SPS_PASTE_STATE)) ||
176                (stat.pasteboardState == static_cast<int>(StatisticPasteboardState::SPS_REMOTE_PASTE_STATE))) {
177         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "hisysevent pasteboard state is %{public}d", stat.pasteboardState);
178         auto iter = dataMap_.find(stat.dataSize);
179         if (iter != dataMap_.end()) {
180             PasteTimeConsuming(stat, iter->second);
181         } else {
182             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "wrong data level");
183         }
184     } else {
185         PASTEBOARD_HILOGD(
186             PASTEBOARD_MODULE_SERVICE, "hisysevent wrong pasteboard state! errCode %{public}d", stat.pasteboardState);
187     }
188 }
189 
CopyTimeConsumingCount(int dataLevel,int timeLevel)190 void HiViewAdapter::CopyTimeConsumingCount(int dataLevel, int timeLevel)
191 {
192     if (static_cast<int>(copyTimeConsumingStat_.size()) <= dataLevel) {
193         return;
194     }
195     auto it = copyTimeConsumingStat_[dataLevel].find(timeLevel);
196     if (it != copyTimeConsumingStat_[dataLevel].end()) {
197         (it->second)++;
198     } else {
199         PASTEBOARD_HILOGD(
200             PASTEBOARD_MODULE_SERVICE, "hisysevent wrong copy time level, tiem level:  %{public}d", timeLevel);
201     }
202 }
203 
PasteTimeConsumingCount(int dataLevel,int timeLevel)204 void HiViewAdapter::PasteTimeConsumingCount(int dataLevel, int timeLevel)
205 {
206     if (static_cast<int>(pasteTimeConsumingStat_.size()) <= dataLevel) {
207         return;
208     }
209     auto it = pasteTimeConsumingStat_[dataLevel].find(timeLevel);
210     if (it != pasteTimeConsumingStat_[dataLevel].end()) {
211         (it->second)++;
212     } else {
213         PASTEBOARD_HILOGD(
214             PASTEBOARD_MODULE_SERVICE, "hisysevent wrong copy time level, tiem level:  %{public}d", timeLevel);
215     }
216 }
217 
RemotePasteTimeConsumingCount(int dataLevel,int timeLevel)218 void HiViewAdapter::RemotePasteTimeConsumingCount(int dataLevel, int timeLevel)
219 {
220     if (static_cast<int>(remotePasteTimeConsumingStat_.size()) <= dataLevel) {
221         return;
222     }
223     auto it = remotePasteTimeConsumingStat_[dataLevel].find(timeLevel);
224     if (it != remotePasteTimeConsumingStat_[dataLevel].end()) {
225         (it->second)++;
226     } else {
227         PASTEBOARD_HILOGD(
228             PASTEBOARD_MODULE_SERVICE, "hisysevent wrong copy time level, tiem level:  %{public}d", timeLevel);
229     }
230 }
231 
CopyTimeConsuming(const TimeConsumingStat & stat,int level)232 void HiViewAdapter::CopyTimeConsuming(const TimeConsumingStat &stat, int level)
233 {
234     auto iter = timeMap_.find(stat.timeConsuming);
235     if (iter != timeMap_.end()) {
236         CopyTimeConsumingCount(level, iter->second);
237     } else {
238         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "wrong time level");
239     }
240 }
241 
PasteTimeConsuming(const TimeConsumingStat & stat,int level)242 void HiViewAdapter::PasteTimeConsuming(const TimeConsumingStat &stat, int level)
243 {
244     auto iter = timeMap_.find(stat.timeConsuming);
245     if (iter != timeMap_.end()) {
246         if (stat.pasteboardState == SPS_PASTE_STATE) {
247             PasteTimeConsumingCount(level, iter->second);
248         } else {
249             RemotePasteTimeConsumingCount(level, iter->second);
250         }
251     } else {
252         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "wrong time level");
253     }
254 }
255 
ReportPasteboardBehaviour(const PasteboardBehaviourMsg & msg)256 void HiViewAdapter::ReportPasteboardBehaviour(const PasteboardBehaviourMsg &msg)
257 {
258     std::lock_guard<std::mutex> lock(behaviourMutex_);
259 
260     if (msg.pasteboardState == static_cast<int>(BehaviourPasteboardState::BPS_COPY_STATE)) {
261         auto it = copyPasteboardBehaviour_.find(msg.bundleName);
262         if (it != copyPasteboardBehaviour_.end()) {
263             (it->second)++;
264         } else {
265             copyPasteboardBehaviour_.insert(std::pair<std::string, int>(msg.bundleName, 1));
266         }
267     } else if (msg.pasteboardState == static_cast<int>(BehaviourPasteboardState::BPS_PASTE_STATE)) {
268         auto it = pastePasteboardBehaviour_.find(msg.bundleName);
269         if (it != pastePasteboardBehaviour_.end()) {
270             (it->second)++;
271         } else {
272             pastePasteboardBehaviour_.insert(std::pair<std::string, int>(msg.bundleName, 1));
273         }
274     } else if (msg.pasteboardState == static_cast<int>(BehaviourPasteboardState::BPS_REMOTE_PASTE_STATE)) {
275         auto it = remotePastePasteboardBehaviour_.find(msg.bundleName);
276         if (it != remotePastePasteboardBehaviour_.end()) {
277             (it->second)++;
278         } else {
279             remotePastePasteboardBehaviour_.insert(std::pair<std::string, int>(msg.bundleName, 1));
280         }
281     } else {
282         PASTEBOARD_HILOGD(
283             PASTEBOARD_MODULE_SERVICE, "hisysevent wrong pasteboard state! errCode %{public}d", msg.pasteboardState);
284     }
285 }
286 
GetDataLevel(int dataLevel)287 const char *HiViewAdapter::GetDataLevel(int dataLevel)
288 {
289     constexpr const char *WRONG_LEVEL = "WRONG_LEVEL";
290     switch (dataLevel) {
291         case static_cast<int>(DataConsumingLevel::DATA_LEVEL_ONE): {
292             return ZERO_TO_HUNDRED_KB;
293         }
294         case static_cast<int>(DataConsumingLevel::DATA_LEVEL_TWO): {
295             return HUNDRED_TO_FIVE_HUNDREDS_KB;
296         }
297         case static_cast<int>(DataConsumingLevel::DATA_LEVEL_THREE): {
298             return FIVE_HUNDREDS_TO_THOUSAND_KB;
299         }
300         case static_cast<int>(DataConsumingLevel::DATA_LEVEL_FOUR): {
301             return ONE_TO_FIVE_MB;
302         }
303         case static_cast<int>(DataConsumingLevel::DATA_LEVEL_FIVE): {
304             return FIVE_TO_TEN_MB;
305         }
306         case static_cast<int>(DataConsumingLevel::DATA_LEVEL_SIX): {
307             return TEN_TO_FIFTY_MB;
308         }
309         case static_cast<int>(DataConsumingLevel::DATA_LEVEL_SEVEN): {
310             return OVER_FIFTY_MB;
311         }
312         default: {
313             return WRONG_LEVEL;
314         }
315     }
316 }
317 
InvokeTimeConsuming()318 void HiViewAdapter::InvokeTimeConsuming()
319 {
320     std::lock_guard<std::mutex> lock(timeConsumingMutex_);
321     ReportStatisticEvent(copyTimeConsumingStat_, COPY_STATE);
322     copyTimeConsumingStat_.clear();
323     ReportStatisticEvent(pasteTimeConsumingStat_, PASTE_STATE);
324     pasteTimeConsumingStat_.clear();
325     ReportStatisticEvent(remotePasteTimeConsumingStat_, REMOTE_PASTE_STATE);
326     remotePasteTimeConsumingStat_.clear();
327 }
328 
ReportStatisticEvent(const std::vector<std::map<int,int>> & timeConsumingStat,const std::string & pasteboardState)329 void HiViewAdapter::ReportStatisticEvent(
330     const std::vector<std::map<int, int>> &timeConsumingStat, const std::string &pasteboardState)
331 {
332     if (timeConsumingStat.empty()) {
333         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "hisysevent timeConsumingStat is empty.");
334         return;
335     }
336     for (std::int32_t i = 0; i < static_cast<int>(timeConsumingStat.size()); ++i) {
337         std::string buffMsg = ": [";
338         for (std::int32_t j = TimeConsumingLevel::TIME_LEVEL_ONE; j <= TimeConsumingLevel::TIME_LEVEL_ELEVEN; ++j) {
339             buffMsg = buffMsg + std::to_string(timeConsumingStat[i].at(j)) + ",";
340         }
341         buffMsg += "]";
342 
343         int ret = -1;
344         if (pasteboardState == REMOTE_PASTE_STATE) {
345             std::string netType = "WIFI";
346             HiSysEventParam params[] = {
347                 {.name = {"PASTEBOARD_STATE"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)pasteboardState.c_str()},
348                     .arraySize = 0, },
349                 {.name = {"NET_TYPE"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)netType.c_str()}, .arraySize = 0, },
350                 {.name = {"DATA_LEVEL"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)GetDataLevel(i)}, .arraySize = 0},
351                 {.name = {"CONSUMING_DATA"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)buffMsg.c_str()},
352                     .arraySize = 0, },
353             };
354             size_t len = sizeof(params) / sizeof(params[0]);
355             ret = OH_HiSysEvent_Write(PASTEBOARD_DOMAIN,
356                 CoverEventID(DfxCodeConstant::TIME_CONSUMING_STATISTIC).c_str(), HISYSEVENT_STATISTIC, params, len);
357         } else {
358             HiSysEventParam params[] = {
359                 {.name = {"PASTEBOARD_STATE"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)pasteboardState.c_str()},
360                     .arraySize = 0, },
361                 {.name = {"DATA_LEVEL"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)GetDataLevel(i)}, .arraySize = 0},
362                 {.name = {"CONSUMING_DATA"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)buffMsg.c_str()},
363                     .arraySize = 0, },
364             };
365             size_t len = sizeof(params) / sizeof(params[0]);
366             ret = OH_HiSysEvent_Write(PASTEBOARD_DOMAIN,
367                 CoverEventID(DfxCodeConstant::TIME_CONSUMING_STATISTIC).c_str(), HISYSEVENT_STATISTIC, params, len);
368         }
369         if (ret != HiviewDFX::SUCCESS) {
370             PASTEBOARD_HILOGD(
371                 PASTEBOARD_MODULE_SERVICE, "hisysevent write failed! ret = %{public}d, i = %{public}d.", ret, i);
372         }
373     }
374 }
375 
ReportBehaviour(std::map<std::string,int> & behaviour,const char * pasteboardState)376 void HiViewAdapter::ReportBehaviour(std::map<std::string, int> &behaviour, const char *pasteboardState)
377 {
378     if (behaviour.empty()) {
379         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "behaviour is empty!");
380         return;
381     }
382     std::vector<std::pair<std::string, int>> vec;
383     constexpr const int TOTAL_APP_NUMBERS = 10;
384     for (auto it = behaviour.begin(); it != behaviour.end(); ++it) {
385         vec.push_back(std::pair<std::string, int>(it->first, it->second));
386     }
387     sort(vec.begin(), vec.end(),
388          [](std::pair<std::string, int> a, std::pair<std::string, int> b) { return a.second > b.second; });
389     std::vector<std::string> appPackName;
390     for (int i = 0; i < TOTAL_APP_NUMBERS; ++i) {
391         appPackName.push_back("default");
392     }
393     int index = 0;
394     for (auto iter = vec.begin(); iter != vec.end(); ++iter) {
395         appPackName[index] = iter->first + " :" + std::to_string(iter->second);
396         ++index;
397         if (index >= TOTAL_APP_NUMBERS) {
398             break;
399         }
400     }
401     HiSysEventParam params[] = {
402         {.name = {"PASTEBOARD_STATE"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)pasteboardState}, .arraySize = 0},
403         {.name = {"TOP_ONE_APP"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)appPackName[0].c_str()}, .arraySize = 0},
404         {.name = {"TOP_TOW_APP"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)appPackName[1].c_str()}, .arraySize = 0},
405         {.name = {"TOP_THREE_APP"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)appPackName[2].c_str()},
406             .arraySize = 0},
407         {.name = {"TOP_FOUR_APP"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)appPackName[3].c_str()}, .arraySize = 0},
408         {.name = {"TOP_FIVE_APP"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)appPackName[4].c_str()}, .arraySize = 0},
409         {.name = {"TOP_SIX_APP"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)appPackName[5].c_str()}, .arraySize = 0},
410         {.name = {"TOP_SEVEN_APP"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)appPackName[6].c_str()},
411             .arraySize = 0},
412         {.name = {"TOP_EIGHT_APP"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)appPackName[7].c_str()},
413             .arraySize = 0},
414         {.name = {"TOP_NINE_APP"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)appPackName[8].c_str()}, .arraySize = 0},
415         {.name = {"TOP_TEN_APP"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)appPackName[9].c_str()}, .arraySize = 0},
416     };
417     int ret = OH_HiSysEvent_Write(PASTEBOARD_DOMAIN, CoverEventID(DfxCodeConstant::PASTEBOARD_BEHAVIOUR).c_str(),
418         HISYSEVENT_BEHAVIOR, params, sizeof(params) / sizeof(params[0]));
419     if (ret != HiviewDFX::SUCCESS) {
420         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "hisysevent write failed! ret %{public}d.", ret);
421     }
422 }
423 
InvokePasteBoardBehaviour()424 void HiViewAdapter::InvokePasteBoardBehaviour()
425 {
426     std::lock_guard<std::mutex> lock(behaviourMutex_);
427     if (!copyPasteboardBehaviour_.empty()) {
428         ReportBehaviour(copyPasteboardBehaviour_, COPY_STATE);
429         copyPasteboardBehaviour_.clear();
430     } else {
431         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "InvokePasteBoardBehaviour :copyPasteboardBehaviour_ is empty ");
432     }
433     if (!pastePasteboardBehaviour_.empty()) {
434         ReportBehaviour(pastePasteboardBehaviour_, PASTE_STATE);
435         pastePasteboardBehaviour_.clear();
436     } else {
437         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "InvokePasteBoardBehaviour :pastePasteboardBehaviour_ is empty ");
438     }
439     if (!remotePastePasteboardBehaviour_.empty()) {
440         ReportBehaviour(remotePastePasteboardBehaviour_, REMOTE_PASTE_STATE);
441         remotePastePasteboardBehaviour_.clear();
442     } else {
443         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "remotePastePasteboardBehaviour_ is empty ");
444     }
445 }
446 
StartTimerThread()447 void HiViewAdapter::StartTimerThread()
448 {
449     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "StartTimerThread enter");
450     std::lock_guard<std::mutex> lock(runMutex_);
451     if (running_) {
452         return;
453     }
454     running_ = true;
455     auto fun = []() {
456         while (true) {
457             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "StartTimerThread while");
458             time_t current = time(nullptr);
459             if (current == -1) {
460                 sleep(ONE_HOUR_IN_SECONDS);
461                 continue;
462             }
463 
464             tm localTime = { 0 };
465             tm *result = localtime_r(&current, &localTime);
466             if (result == nullptr) {
467                 sleep(ONE_HOUR_IN_SECONDS);
468                 continue;
469             }
470             int currentHour = localTime.tm_hour;
471             int currentMin = localTime.tm_min;
472             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "StartTimerThread get");
473             if ((EXEC_MIN_TIME - currentMin) != EXEC_MIN_TIME) {
474                 int nHours = EXEC_HOUR_TIME - currentHour;
475                 int nMin = EXEC_MIN_TIME - currentMin;
476                 int nTime = (nMin)*ONE_MINUTE_IN_SECONDS + (nHours)*ONE_HOUR_IN_SECONDS;
477                 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE,
478                     " StartTimerThread if needHours=%{public}d,needMin=%{public}d,needTime=%{public}d", nHours, nMin,
479                     nTime);
480                 sleep(nTime);
481                 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "StartTimerThread invoke");
482                 InvokePasteBoardBehaviour();
483                 InvokeTimeConsuming();
484             } else {
485                 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "StartTimerThread sleep");
486                 sleep(ONE_HOUR_IN_SECONDS * (ONE_DAY_IN_HOURS - currentHour));
487                 current = time(nullptr);
488                 InvokePasteBoardBehaviour();
489                 InvokeTimeConsuming();
490             }
491             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "StartTimerThread end");
492         }
493     };
494     std::thread th = std::thread(fun);
495     pthread_setname_np(th.native_handle(), "HiViewReport");
496     th.detach();
497 }
498 
ReportUseBehaviour(PasteData & pastData,const char * state,int32_t result)499 void HiViewAdapter::ReportUseBehaviour(PasteData& pastData, const char* state, int32_t result)
500 {
501     std::string stateStr = state;
502     std::string bundleName = pastData.GetBundleName();
503     std::string primaryMimeType = pastData.GetPrimaryMimeType() != nullptr? *pastData.GetPrimaryMimeType() : "null";
504     std::string shareOption;
505     PasteData::ShareOptionToString(pastData.GetShareOption(), shareOption);
506     auto isLocalPaste = pastData.IsLocalPaste();
507     auto isRemote = pastData.IsRemote();
508     std::thread thread([bundleName, primaryMimeType, shareOption, isLocalPaste, isRemote, stateStr, result]() {
509         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
510         auto iter = PasteboardErrorMap.find(PasteboardError(result));
511         const char *appRet;
512         if (iter != PasteboardErrorMap.end()) {
513             appRet = iter->second;
514         } else {
515             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Match error result: %{public}d.", result);
516             appRet = "MATCH ERROR";
517         }
518         HiSysEventParam params[] = {
519             {.name = {"PASTEBOARD_STATE"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)stateStr.c_str()},
520                 .arraySize = 0, },
521             {.name = {"BOOTTIME"}, .t = HISYSEVENT_INT64,
522                 .v = { .i64 = TimeServiceClient::GetInstance()->GetBootTimeMs()}, .arraySize = 0, },
523             {.name = {"WALLTIME"}, .t = HISYSEVENT_INT64,
524                 .v = { .i64 = TimeServiceClient::GetInstance()->GetWallTimeMs()}, .arraySize = 0, },
525 
526             {.name = {"RESULT"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)appRet}, .arraySize = 0, },
527             {.name = {"OPERATE_APP"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)bundleName.c_str()}, .arraySize = 0},
528             {.name = {"PRI_MIME_TYPE"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)primaryMimeType.c_str()},
529                 .arraySize = 0, },
530             {.name = {"ISLOCALPASTE"}, .t = HISYSEVENT_BOOL, .v = { .b = isLocalPaste}, .arraySize = 0, },
531             {.name = {"ISREMOTE"}, .t = HISYSEVENT_BOOL, .v = { .b = isRemote}, .arraySize = 0, },
532             {.name = {"SHAREOPTION"}, .t = HISYSEVENT_STRING, .v = { .s = (char *)shareOption.c_str()},
533                 .arraySize = 0, },
534         };
535         size_t len = sizeof(params) / sizeof(params[0]);
536         int ret = OH_HiSysEvent_Write(PASTEBOARD_DOMAIN, CoverEventID(DfxCodeConstant::USE_BEHAVIOUR).c_str(),
537             HISYSEVENT_BEHAVIOR, params, len);
538         if (ret != HiviewDFX::SUCCESS) {
539             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "hisysevent write failed! ret %{public}d.", ret);
540         }
541         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "end.");
542     });
543     thread.detach();
544 }
545 
CoverEventID(int dfxCode)546 std::string HiViewAdapter::CoverEventID(int dfxCode)
547 {
548     std::string sysEventID = "";
549     auto operatorIter = EVENT_COVERT_TABLE.find(dfxCode);
550     if (operatorIter != EVENT_COVERT_TABLE.end()) {
551         sysEventID = operatorIter->second;
552     }
553     return sysEventID;
554 }
555 } // namespace MiscServices
556 } // namespace OHOS
557