• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "ani_app_event_holder.h"
17 
18 #include <cinttypes>
19 
20 #include "app_event_store.h"
21 #include "hilog/log.h"
22 #include "hiappevent_ani_util.h"
23 
24 #undef LOG_DOMAIN
25 #define LOG_DOMAIN 0xD002D07
26 
27 #undef LOG_TAG
28 #define LOG_TAG "AniHolder"
29 
30 namespace OHOS {
31 namespace HiviewDFX {
32 namespace {
33 constexpr size_t PARAM_NUM = 1;
34 constexpr int DEFAULT_ROW_NUM = 1;
35 constexpr int DEFAULT_SIZE = 512 * 1024; // 512 * 1024: 512KB
36 const std::string HOLDER_CLASS_NAME = "AppEventPackageHolder";
37 
GetObserverSeqByName(const std::string & name)38 int64_t GetObserverSeqByName(const std::string& name)
39 {
40     int64_t observerSeq = -1;
41     if (observerSeq = AppEventStore::GetInstance().QueryObserverSeq(name); observerSeq <= 0) {
42         HILOG_WARN(LOG_CORE, "failed to query seq by name=%{public}s", name.c_str());
43         return -1;
44     }
45     return observerSeq;
46 }
47 }
48 
AniAppEventHolder(const std::string & name,int64_t observerSeq)49 AniAppEventHolder::AniAppEventHolder(const std::string& name, int64_t observerSeq)
50     : name_(name), observerSeq_(observerSeq), hasSetRow_(false), hasSetSize_(false)
51 {
52     takeRow_ = DEFAULT_ROW_NUM;
53     takeSize_ = DEFAULT_SIZE;
54     packageId_ = 0; // id is incremented from 0
55 
56     // if the seq is invalid, need to get seq by the name(for js constructor)
57     if (observerSeq_ <= 0) {
58         observerSeq_ = GetObserverSeqByName(name_);
59     }
60 }
61 
Wrap(ani_env * env,ani_object aniObject,AniAppEventHolder * holder)62 static ani_object Wrap(ani_env *env, ani_object aniObject, AniAppEventHolder *holder)
63 {
64     if (env->Object_SetFieldByName_Long(aniObject, "nativeHolder", reinterpret_cast<ani_long>(holder)) != ANI_OK) {
65         HILOG_ERROR(LOG_CORE, "New holder Fail");
66         return nullptr;
67     }
68     return aniObject;
69 }
70 
Unwrap(ani_env * env,ani_object aniObject)71 static AniAppEventHolder* Unwrap(ani_env *env, ani_object aniObject)
72 {
73     ani_long context;
74     if (env->Object_GetFieldByName_Long(aniObject, "nativeHolder", &context) != ANI_OK) {
75         return nullptr;
76     }
77     return reinterpret_cast<AniAppEventHolder*>(context);
78 }
79 
AniConstructor(ani_env * env,ani_object aniObject,ani_string watcherName)80 void AniAppEventHolder::AniConstructor(ani_env *env, ani_object aniObject, ani_string watcherName)
81 {
82     auto holder = new(std::nothrow) AniAppEventHolder(HiAppEventAniUtil::ParseStringValue(env, watcherName));
83     if (holder == nullptr) {
84         HILOG_INFO(LOG_CORE, "AniConstructor  holder nullptr");
85     }
86     Wrap(env, aniObject, holder);
87 }
88 
AniFinalize(ani_env * env,ani_object object,ani_long nativeHolder)89 void AniAppEventHolder::AniFinalize(ani_env *env, ani_object object, ani_long nativeHolder)
90 {
91     AniAppEventHolder* holder = reinterpret_cast<AniAppEventHolder*>(nativeHolder);
92     delete holder;
93 }
94 
AniSetRow(ani_env * env,ani_object object,ani_double size)95 void AniAppEventHolder::AniSetRow(ani_env *env, ani_object object, ani_double size)
96 {
97     int num = static_cast<int>(size);
98     if (num <= 0) {
99         HiAppEventAniUtil::ThrowAniError(env, ERR_INVALID_SIZE, "Invalid size value.");
100         return;
101     }
102     AniAppEventHolder* holder = Unwrap(env, object);
103     if (holder != nullptr) {
104         holder->SetRow(num);
105     }
106     return;
107 }
108 
AniSetSize(ani_env * env,ani_object object,ani_double size)109 void AniAppEventHolder::AniSetSize(ani_env *env, ani_object object, ani_double size)
110 {
111     int num = static_cast<int>(size);
112     if (num < 0) {
113         HiAppEventAniUtil::ThrowAniError(env, ERR_INVALID_SIZE, "Invalid size value.");
114         return;
115     }
116     AniAppEventHolder* holder = Unwrap(env, object);
117     if (holder != nullptr) {
118         holder->SetSize(num);
119     }
120     return;
121 }
122 
AniTakeNext(ani_env * env,ani_object object)123 ani_object AniAppEventHolder::AniTakeNext(ani_env *env, ani_object object)
124 {
125     ani_object packageObj = HiAppEventAniUtil::CreateObject(env, CLASS_NAME_EVENT_PACKAGE);
126     AniAppEventHolder* holder = Unwrap(env, object);
127     if (holder == nullptr) {
128         return packageObj;
129     }
130     auto package = holder->TakeNext();
131     if (package == nullptr) {
132         return packageObj;
133     }
134     env->Object_SetPropertyByName_Double(packageObj, "packageId", package->packageId);
135     env->Object_SetPropertyByName_Double(packageObj, "row", package->row);
136     env->Object_SetPropertyByName_Double(packageObj, "size", package->size);
137     env->Object_SetPropertyByName_Ref(packageObj, "data", HiAppEventAniUtil::CreateStrings(env, package->data));
138     env->Object_SetPropertyByName_Ref(packageObj, "appEventInfos",
139         HiAppEventAniUtil::CreateEventInfoArray(env, package->events));
140     return packageObj;
141 }
142 
SetRow(int row)143 void AniAppEventHolder::SetRow(int row)
144 {
145     HILOG_INFO(LOG_CORE, "hodler seq=%{public}" PRId64 " set row=%{public}d", observerSeq_, row);
146     takeRow_ = row;
147     hasSetRow_ = true;
148 }
149 
SetSize(int size)150 void AniAppEventHolder::SetSize(int size)
151 {
152     HILOG_INFO(LOG_CORE, "hodler seq=%{public}" PRId64 " set size=%{public}d", observerSeq_, size);
153     takeSize_ = size;
154     hasSetSize_ = true;
155 }
156 
TakeNext()157 std::shared_ptr<AppEventPackage> AniAppEventHolder::TakeNext()
158 {
159     std::vector<std::shared_ptr<AppEventPack>> events;
160     bool shouldTakeSize = hasSetSize_ && !hasSetRow_;
161     int rowNum = shouldTakeSize ? 0 : takeRow_;
162     if (AppEventStore::GetInstance().QueryEvents(events, observerSeq_, rowNum) != 0) {
163         HILOG_WARN(LOG_CORE, "failed to query events, seq=%{public}" PRId64, observerSeq_);
164         return nullptr;
165     }
166     if (events.empty()) {
167         HILOG_DEBUG(LOG_CORE, "end to query events, seq=%{public}" PRId64, observerSeq_);
168         return nullptr;
169     }
170 
171     std::vector<int64_t> eventSeqs;
172     std::vector<std::string> eventStrs;
173     size_t totalSize = 0;
174     auto package = std::make_shared<AppEventPackage>();
175     for (auto event : events) {
176         std::string eventStr = event->GetEventStr();
177         if (shouldTakeSize && static_cast<int>(totalSize + eventStr.size()) > takeSize_) {
178             HILOG_INFO(LOG_CORE, "stop to take data, totalSize=%{public}zu, takeSize=%{public}d",
179                 totalSize, takeSize_);
180             break;
181         }
182         totalSize += eventStr.size();
183         eventStrs.emplace_back(eventStr);
184         eventSeqs.emplace_back(event->GetSeq());
185         package->events.emplace_back(event);
186     }
187     if (eventStrs.empty()) {
188         HILOG_INFO(LOG_CORE, "take data is empty, seq=%{public}" PRId64, observerSeq_);
189         return nullptr;
190     }
191     if (!AppEventStore::GetInstance().DeleteData(observerSeq_, eventSeqs)) {
192         HILOG_INFO(LOG_CORE, "failed to delete mapping data, seq=%{public}" PRId64, observerSeq_);
193         return nullptr;
194     }
195 
196     package->packageId = packageId_++;
197     package->row = static_cast<int>(eventStrs.size());
198     package->size = static_cast<int>(totalSize);
199     package->data = eventStrs;
200     return package;
201 }
202 } // namespace HiviewDFX
203 } // namespace OHOS
204