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 "appevent_packageholder_impl.h"
17 #include "log.h"
18 #include "hiappevent_base.h"
19 #include "hiappevent_config.h"
20 #include "error.h"
21
22 using namespace OHOS::HiviewDFX;
23 namespace OHOS {
24 namespace CJSystemapi {
25 namespace HiAppEvent {
26
MallocCString(const std::string & origin)27 char* MallocCString(const std::string& origin)
28 {
29 if (origin.empty()) {
30 return nullptr;
31 }
32 auto length = origin.length() + 1;
33 char* res = static_cast<char*>(malloc(sizeof(char) * length));
34 if (res == nullptr) {
35 return nullptr;
36 }
37 return std::char_traits<char>::copy(res, origin.c_str(), length);
38 }
39
ConvertArrString(std::vector<std::string> & vecStr)40 CArrString ConvertArrString(std::vector<std::string>& vecStr)
41 {
42 CArrString arrStr{0};
43 if (vecStr.empty()) {
44 return arrStr;
45 }
46 arrStr.size = static_cast<int64_t>(vecStr.size());
47 char **retValue = static_cast<char**>(malloc(sizeof(char *) * arrStr.size));
48 if (retValue == nullptr) {
49 return arrStr;
50 }
51 for (int i = 0; i < arrStr.size; ++i) {
52 retValue[i] = MallocCString(vecStr[i]);
53 }
54 arrStr.head = retValue;
55 return arrStr;
56 }
57
AppEventPackageHolderImpl(const std::string & name,int64_t observerSeq)58 AppEventPackageHolderImpl::AppEventPackageHolderImpl(const std::string& name, int64_t observerSeq)
59 : name_(name), observerSeq_(observerSeq)
60 {
61 takeSize_ = 512 * 1024; // 512 * 1024: 512KB
62 packageId_ = 0; // id is incremented from 0
63 // if the seq is invalid, need to get seq by the name(for js constructor)
64 if (observerSeq_ <= 0) {
65 observerSeq_ = GetObserverSeqByName(name_);
66 }
67 }
68
SetSize(int size)69 void AppEventPackageHolderImpl::SetSize(int size)
70 {
71 LOGI("hodler seq=%{public}" PRIi64 ", set size=%{public}d", observerSeq_, size);
72 takeSize_ = size;
73 }
74
TakeNext()75 std::tuple<int32_t, RetAppEventPackage> AppEventPackageHolderImpl::TakeNext()
76 {
77 std::vector<std::shared_ptr<AppEventPack>> events;
78 int32_t ret = ERR_PARAM;
79 RetAppEventPackage package;
80 if (AppEventStore::GetInstance().QueryEvents(events, observerSeq_) != 0) {
81 LOGE("failed to query events, seq=%{public}" PRId64, observerSeq_);
82 return {ret, package};
83 }
84 if (events.empty()) {
85 LOGE("end to query events, seq=%{public}" PRId64, observerSeq_);
86 return {ret, package};
87 }
88 std::vector<int64_t> eventSeqs;
89 std::vector<std::string> eventStrs;
90 size_t totalSize = 0;
91 for (const auto& event : events) {
92 std::string eventStr = event->GetEventStr();
93 if (static_cast<int>(totalSize + eventStr.size()) > takeSize_) {
94 LOGI("stop to take data, totalSize=%{public}zu, takeSize=%{public}" PRIi64 "", totalSize, takeSize_);
95 break;
96 }
97 totalSize += eventStr.size();
98 eventStrs.emplace_back(eventStr);
99 eventSeqs.emplace_back(event->GetSeq());
100 }
101 if (eventStrs.empty()) {
102 LOGE("take data is empty, seq=%{public}" PRId64, observerSeq_);
103 return {ret, package};
104 }
105 if (AppEventStore::GetInstance().DeleteEventMapping(observerSeq_, eventSeqs) < 0) {
106 LOGE("failed to delete mapping data, seq=%{public}" PRId64, observerSeq_);
107 return {ret, package};
108 }
109 package.packageId = packageId_++;
110 package.row = static_cast<int>(eventStrs.size());
111 package.size = static_cast<int>(totalSize);
112 package.events = ConvertArrString(eventStrs);
113 ret = SUCCESS_CODE;
114 return {ret, package};
115 }
116
GetObserverSeqByName(const std::string & name)117 int64_t GetObserverSeqByName(const std::string& name)
118 {
119 int64_t observerSeq = ERR_CODE_PARAM_INVALID;
120 if (observerSeq = AppEventStore::GetInstance().QueryObserverSeq(name); observerSeq <= 0) {
121 LOGE("failed to query seq by name= %{public}s", name.c_str());
122 return ERR_CODE_PARAM_INVALID;
123 }
124 return observerSeq;
125 }
126 } // HiAppEvent
127 } // CJSystemapi
128 } // OHOS