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