• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
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 <algorithm>
17 #include <codecvt>
18 #include <string>
19 #include <memory>
20 #include <malloc.h>
21 #include <parameters.h>
22 
23 #include "ani_util.h"
24 #include "application_context.h"
25 #include "context.h"
26 #include "directory_ex.h"
27 #include "file_ex.h"
28 #include "hiappevent_util.h"
29 #include "hidebug_native_interface.h"
30 #include "hilog/log.h"
31 #include "iservice_registry.h"
32 #include "refbase.h"
33 #include "system_ability_definition.h"
34 
35 using namespace OHOS;
36 using namespace OHOS::HiviewDFX;
37 
38 namespace {
39 #undef LOG_DOMAIN
40 #define LOG_DOMAIN 0xD002D0A
41 #undef LOG_TAG
42 #define LOG_TAG "HiDebug_ANI"
43 
44 constexpr int MAX_TAGS_ARRAY_LENGTH = 40;
45 enum ErrorCode {
46     PERMISSION_ERROR = 201,
47     PARAMETER_ERROR = 401,
48     VERSION_ERROR = 801,
49     SYSTEM_ABILITY_NOT_FOUND = 11400101,
50     HAVA_ALREADY_TRACE = 11400102,
51     WITHOUT_WRITE_PERMISSON = 11400103,
52     SYSTEM_STATUS_ABNORMAL = 11400104,
53     NO_CAPTURE_TRACE_RUNNING = 11400105,
54 };
55 }
56 
IsArrayForAniValue(ani_env * env,ani_object param,ani_int & arraySize)57 static bool IsArrayForAniValue(ani_env *env, ani_object param, ani_int &arraySize)
58 {
59     ani_boolean isArray = ANI_FALSE;
60     ani_class cls = nullptr;
61     ani_static_method isArrayMethod = nullptr;
62     if (env->FindClass("Lescompat/Array;", &cls) != ANI_OK ||
63         env->Class_FindStaticMethod(cls, "isArray", "Lstd/core/Object;:Z", &isArrayMethod) != ANI_OK ||
64         env->Class_CallStaticMethod_Boolean(cls, isArrayMethod, &isArray, param) != ANI_OK ||
65         isArray == ANI_FALSE) {
66         return false;
67     }
68 
69     ani_double length = 0;
70     if (env->Object_GetPropertyByName_Double(param, "length", &length) != ANI_OK) {
71         return false;
72     }
73     arraySize = static_cast<ani_int>(length);
74     return true;
75 }
76 
GetDumpParam(ani_env * env,ani_object argsAni,std::vector<std::u16string> & args)77 static bool GetDumpParam(ani_env *env, ani_object argsAni, std::vector<std::u16string> &args)
78 {
79     ani_int arraySize = 0;
80     if (!IsArrayForAniValue(env, argsAni, arraySize)) {
81         HILOG_ERROR(LOG_CORE, "Get input args failed.");
82         return false;
83     }
84     for (ani_int i = 0; i < arraySize; i++) {
85         ani_ref aniValue = nullptr;
86         if (env->Object_CallMethodByName_Ref(argsAni, "$_get", "I:Lstd/core/Object;", &aniValue, i) != ANI_OK) {
87             HILOG_ERROR(LOG_CORE, "get_element -> Get input args failed.");
88             return false;
89         }
90         std::string strValue;
91         if (AniUtil::ParseAniString(env, static_cast<ani_string>(aniValue), strValue) != ANI_OK) {
92             HILOG_ERROR(LOG_CORE, "get_value -> Get input args failed.");
93             return false;
94         }
95         std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> strCnv;
96         args.push_back(strCnv.from_bytes(strValue));
97     }
98     return true;
99 }
100 
GetTraceParam(ani_env * env,ani_array_double tagsAni,std::vector<uint64_t> & tags)101 static bool GetTraceParam(ani_env *env, ani_array_double tagsAni, std::vector<uint64_t> &tags)
102 {
103     ani_size arraySize = 0;
104     if (env->Array_GetLength(static_cast<ani_array>(tagsAni), &arraySize) != ANI_OK) {
105         HILOG_ERROR(LOG_CORE, "Get input tags size failed.");
106         return false;
107     }
108     if (arraySize > static_cast<ani_size>(MAX_TAGS_ARRAY_LENGTH)) {
109         HILOG_ERROR(LOG_CORE, "The length of tags array exceeds the limit.");
110         return false;
111     }
112     ani_double *aniValues = new ani_double[arraySize];
113     if (env->Array_GetRegion_Double(tagsAni, 0, arraySize, aniValues) != ANI_OK) {
114         HILOG_ERROR(LOG_CORE, "Get input tags value failed.");
115         delete []aniValues;
116         return false;
117     }
118     for (ani_size i = 0; i < arraySize; i++) {
119         tags.push_back(static_cast<uint64_t>(aniValues[i]));
120     }
121     delete []aniValues;
122     return true;
123 }
124 
GetPss(ani_env * env)125 ani_object GetPss(ani_env *env)
126 {
127     ani_object pss = nullptr;
128     auto nativeMemInfoOption = HidebugNativeInterface::GetInstance().GetAppNativeMemInfo(false);
129     AniUtil::ToAniBigInt(env, nativeMemInfoOption ? static_cast<uint64_t>(nativeMemInfoOption->pss) : 0, pss);
130     return pss;
131 }
132 
GetSharedDirty(ani_env * env)133 ani_object GetSharedDirty(ani_env *env)
134 {
135     ApiInvokeRecorder apiInvokeRecorder("getSharedDirty");
136     ani_object sharedDirty = nullptr;
137     auto nativeMemInfoOption = HidebugNativeInterface::GetInstance().GetAppNativeMemInfo(false);
138     AniUtil::ToAniBigInt(env,
139         nativeMemInfoOption ? static_cast<uint64_t>(nativeMemInfoOption->sharedDirty) : 0, sharedDirty);
140     return sharedDirty;
141 }
142 
GetPrivateDirty(ani_env * env)143 ani_object GetPrivateDirty(ani_env *env)
144 {
145     ApiInvokeRecorder apiInvokeRecorder("getPrivateDirty");
146     ani_object privateDirtyValue = nullptr;
147     auto nativeMemInfoOption = HidebugNativeInterface::GetInstance().GetAppNativeMemInfo(false);
148     AniUtil::ToAniBigInt(env, nativeMemInfoOption ? nativeMemInfoOption->privateDirty : 0, privateDirtyValue);
149     return privateDirtyValue;
150 }
151 
GetCpuUsage(ani_env * env)152 ani_double GetCpuUsage(ani_env *env)
153 {
154     ApiInvokeRecorder apiInvokeRecorder("getCpuUsage");
155     return static_cast<ani_double>(HidebugNativeInterface::GetInstance().GetCpuUsage());
156 }
157 
GetNativeHeapSize(ani_env * env)158 ani_object GetNativeHeapSize(ani_env *env)
159 {
160     struct mallinfo mi = mallinfo();
161     ani_object nativeHeapSize = nullptr;
162     AniUtil::ToAniBigInt(env, uint64_t(mi.uordblks + mi.fordblks), nativeHeapSize);
163     return nativeHeapSize;
164 }
165 
GetNativeHeapAllocatedSize(ani_env * env)166 ani_object GetNativeHeapAllocatedSize(ani_env *env)
167 {
168     ApiInvokeRecorder apiInvokeRecorder("getNativeHeapAllocatedSize");
169     struct mallinfo mi = mallinfo();
170     ani_object nativeHeapAllocatedSize = nullptr;
171     AniUtil::ToAniBigInt(env, uint64_t(mi.uordblks), nativeHeapAllocatedSize);
172     return nativeHeapAllocatedSize;
173 }
174 
GetNativeHeapFreeSize(ani_env * env)175 ani_object GetNativeHeapFreeSize(ani_env *env)
176 {
177     ApiInvokeRecorder apiInvokeRecorder("getNativeHeapFreeSize");
178     struct mallinfo mi = mallinfo();
179     ani_object nativeHeapFreeSize = nullptr;
180     AniUtil::ToAniBigInt(env, uint64_t(mi.fordblks), nativeHeapFreeSize);
181     return nativeHeapFreeSize;
182 }
183 
GetServiceDump(ani_env * env,ani_double serviceIdAni,ani_double fdAni,ani_object argsAni)184 static void GetServiceDump(ani_env *env,
185     ani_double serviceIdAni, ani_double fdAni, ani_object argsAni)
186 {
187     ApiInvokeRecorder apiInvokeRecorder("getServiceDump");
188     int serviceAbilityId = static_cast<int>(serviceIdAni);
189     int fd = static_cast<int>(fdAni);
190     std::vector<std::u16string> args;
191     if (!GetDumpParam(env, argsAni, args)) {
192         std::string paramErrorMessage = "The parameter check failed.";
193         AniUtil::ThrowErrorMessage(env, paramErrorMessage, ErrorCode::PARAMETER_ERROR);
194         return;
195     }
196     sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
197     if (!sam) {
198         return;
199     }
200     sptr<IRemoteObject> sa = sam->CheckSystemAbility(serviceAbilityId);
201     if (sa == nullptr) {
202         HILOG_ERROR(LOG_CORE, "no this system ability.");
203         std::string idErrorMessage = "ServiceId invalid. The system ability does not exist.";
204         AniUtil::ThrowErrorMessage(env, idErrorMessage, ErrorCode::SYSTEM_ABILITY_NOT_FOUND);
205         return;
206     }
207     int dumpResult = sa->Dump(fd, args);
208     HILOG_INFO(LOG_CORE, "Dump result: %{public}d", dumpResult);
209 }
210 
GetVss(ani_env * env)211 ani_object GetVss(ani_env *env)
212 {
213     ApiInvokeRecorder apiInvokeRecorder("getVss");
214     ani_object vss = nullptr;
215     auto vssInfoOption = HidebugNativeInterface::GetInstance().GetVss();
216     AniUtil::ToAniBigInt(env, vssInfoOption ? vssInfoOption.value() : 0, vss);
217     return vss;
218 }
219 
GetSystemCpuUsage(ani_env * env)220 static ani_double GetSystemCpuUsage(ani_env *env)
221 {
222     ApiInvokeRecorder apiInvokeRecorder("getSystemCpuUsage");
223     auto cpuUsageOptional = HidebugNativeInterface::GetInstance().GetSystemCpuUsage();
224     if (!cpuUsageOptional) {
225         std::string paramErrorMessage = "The status of the system CPU usage is abnormal.";
226         AniUtil::ThrowErrorMessage(env, paramErrorMessage, ErrorCode::SYSTEM_STATUS_ABNORMAL);
227         return 0;
228     }
229     return static_cast<ani_double>(cpuUsageOptional.value());
230 }
231 
ConvertThreadCpuUsageToEts(ani_env * env,ani_class cls,uint32_t threadIdValue,double cpuUsageValue)232 static ani_object ConvertThreadCpuUsageToEts(ani_env *env, ani_class cls, uint32_t threadIdValue, double cpuUsageValue)
233 {
234     ani_method ctorMethod = nullptr;
235     ani_object obj = nullptr;
236     if (env->Class_FindMethod(cls, "<ctor>", ":V", &ctorMethod) != ANI_OK ||
237         env->Object_New(cls, ctorMethod, &obj) != ANI_OK) {
238         return AniUtil::CreateUndefined(env);
239     }
240     AniUtil::SetNamedPropertyNumber(env, obj, "threadId", static_cast<double>(threadIdValue));
241     AniUtil::SetNamedPropertyNumber(env, obj, "cpuUsage", cpuUsageValue);
242     return obj;
243 }
244 
ConvertThreadCpuUsageMapToEts(ani_env * env,const std::map<uint32_t,double> & threadMap)245 static ani_array_ref ConvertThreadCpuUsageMapToEts(ani_env *env, const std::map<uint32_t, double> &threadMap)
246 {
247     ani_class cls = nullptr;
248     ani_size aniSize = static_cast<ani_size>(threadMap.size());
249     ani_array_ref result = nullptr;
250     if (env->FindClass("L@ohos/hidebug/hidebug/ThreadCpuUsageImpl;", &cls) != ANI_OK ||
251         env->Array_New_Ref(static_cast<ani_type>(cls), aniSize, nullptr, &result) != ANI_OK) {
252         return result;
253     }
254     ani_size idx = 0;
255     for (const auto& [threadId, cpuUsage] : threadMap) {
256         ani_object obj = ConvertThreadCpuUsageToEts(env, cls, threadId, cpuUsage);
257         env->Array_Set_Ref(result, idx, static_cast<ani_ref>(obj));
258         idx++;
259     }
260     return result;
261 }
262 
GetAppThreadCpuUsage(ani_env * env)263 ani_array GetAppThreadCpuUsage(ani_env *env)
264 {
265     ApiInvokeRecorder apiInvokeRecorder("getAppThreadCpuUsage");
266     std::map<uint32_t, double> threadMap = HidebugNativeInterface::GetInstance().GetAppThreadCpuUsage();
267     return ConvertThreadCpuUsageMapToEts(env, threadMap);
268 }
269 
GetAppNativeMemInfo(ani_env * env)270 ani_object GetAppNativeMemInfo(ani_env *env)
271 {
272     ApiInvokeRecorder apiInvokeRecorder("getAppNativeMemInfo");
273     auto nativeMemInfoOption = HidebugNativeInterface::GetInstance().GetAppNativeMemInfo();
274     if (!nativeMemInfoOption) {
275         nativeMemInfoOption.emplace();
276     }
277 
278     ani_class cls = nullptr;
279     ani_method ctorMethod = nullptr;
280     ani_object memInfo = nullptr;
281     if (env->FindClass("L@ohos/hidebug/hidebug/NativeMemInfoImpl;", &cls) != ANI_OK ||
282         env->Class_FindMethod(cls, "<ctor>", ":V", &ctorMethod) != ANI_OK ||
283         env->Object_New(cls, ctorMethod, &memInfo) != ANI_OK) {
284         return AniUtil::CreateUndefined(env);
285     }
286     AniUtil::SetNamedPropertyBigInt(env, memInfo, "pss", nativeMemInfoOption->pss);
287     AniUtil::SetNamedPropertyBigInt(env, memInfo, "rss", nativeMemInfoOption->rss);
288     AniUtil::SetNamedPropertyBigInt(env, memInfo, "sharedDirty", nativeMemInfoOption->sharedDirty);
289     AniUtil::SetNamedPropertyBigInt(env, memInfo, "privateDirty", nativeMemInfoOption->privateDirty);
290     AniUtil::SetNamedPropertyBigInt(env, memInfo, "sharedClean", nativeMemInfoOption->sharedClean);
291     AniUtil::SetNamedPropertyBigInt(env, memInfo, "privateClean", nativeMemInfoOption->privateClean);
292     AniUtil::SetNamedPropertyBigInt(env, memInfo, "vss", nativeMemInfoOption->vss);
293     return memInfo;
294 }
295 
GetSystemMemInfo(ani_env * env)296 ani_object GetSystemMemInfo(ani_env *env)
297 {
298     ApiInvokeRecorder apiInvokeRecorder("getSystemMemInfo");
299     auto sysMemOption = HidebugNativeInterface::GetInstance().GetSystemMemInfo();
300     if (!sysMemOption) {
301         sysMemOption.emplace();
302     }
303 
304     ani_class cls = nullptr;
305     ani_method ctorMethod = nullptr;
306     ani_object sysMemInfo = nullptr;
307     if (env->FindClass("L@ohos/hidebug/hidebug/SystemMemInfoImpl;", &cls) != ANI_OK ||
308         env->Class_FindMethod(cls, "<ctor>", ":V", &ctorMethod) != ANI_OK ||
309         env->Object_New(cls, ctorMethod, &sysMemInfo) != ANI_OK) {
310         return AniUtil::CreateUndefined(env);
311     }
312 
313     AniUtil::SetNamedPropertyBigInt(env, sysMemInfo, "totalMem", static_cast<uint64_t>(sysMemOption->totalMem));
314     AniUtil::SetNamedPropertyBigInt(env, sysMemInfo, "freeMem", static_cast<uint64_t>(sysMemOption->freeMem));
315     AniUtil::SetNamedPropertyBigInt(env, sysMemInfo, "availableMem", static_cast<uint64_t>(sysMemOption->availableMem));
316     return sysMemInfo;
317 }
318 
StartAppTraceCapture(ani_env * env,ani_array_double tagsAni,ani_enum_item flagAni,ani_double limitSizeAni)319 ani_string StartAppTraceCapture(ani_env *env,
320     ani_array_double tagsAni, ani_enum_item flagAni, ani_double limitSizeAni)
321 {
322     ApiInvokeRecorder apiInvokeRecorder("startAppTraceCapture");
323     ani_string result = nullptr;
324     uint32_t traceFlag = 0;
325     uint32_t limitSize = static_cast<uint32_t>(limitSizeAni);
326     std::vector<uint64_t> tags;
327     if (AniUtil::ParseAniEnum(env, flagAni, traceFlag) != ANI_OK || !GetTraceParam(env, tagsAni, tags)) {
328         std::string paramErrorMessage = "Invalid argument";
329         apiInvokeRecorder.SetErrorCode(ErrorCode::PARAMETER_ERROR);
330         AniUtil::ThrowErrorMessage(env, paramErrorMessage, ErrorCode::PARAMETER_ERROR);
331         return nullptr;
332     }
333     uint64_t tag = std::accumulate(tags.begin(), tags.end(), 0ull, [](uint64_t a, uint64_t b) { return a | b; });
334     std::string file;
335     auto ret = HidebugNativeInterface::GetInstance().StartAppTraceCapture(tag, traceFlag, limitSize, file);
336     if (ret == TRACE_SUCCESS) {
337         env->String_NewUTF8(file.c_str(), file.size(), &result);
338         return result;
339     }
340     if (ret == TRACE_INVALID_ARGUMENT) {
341         std::string errorMessage = "Invalid argument";
342         apiInvokeRecorder.SetErrorCode(ErrorCode::PARAMETER_ERROR);
343         AniUtil::ThrowErrorMessage(env, errorMessage, ErrorCode::PARAMETER_ERROR);
344     }
345     if (ret == TRACE_CAPTURED_ALREADY) {
346         std::string errorMessage = "Capture trace already enabled.";
347         apiInvokeRecorder.SetErrorCode(ErrorCode::HAVA_ALREADY_TRACE);
348         AniUtil::ThrowErrorMessage(env, errorMessage, ErrorCode::HAVA_ALREADY_TRACE);
349     }
350     if (ret == TRACE_NO_PERMISSION) {
351         std::string errorMessage = "No write permission on the file.";
352         apiInvokeRecorder.SetErrorCode(ErrorCode::WITHOUT_WRITE_PERMISSON);
353         AniUtil::ThrowErrorMessage(env, errorMessage, ErrorCode::WITHOUT_WRITE_PERMISSON);
354     }
355     std::string errorMessage = "Abnormal trace status.";
356     apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
357     AniUtil::ThrowErrorMessage(env, errorMessage, ErrorCode::SYSTEM_STATUS_ABNORMAL);
358     return nullptr;
359 }
360 
StopAppTraceCapture(ani_env * env)361 void StopAppTraceCapture(ani_env *env)
362 {
363     ApiInvokeRecorder apiInvokeRecorder("stopAppTraceCapture");
364     auto ret = HidebugNativeInterface::GetInstance().StopAppTraceCapture();
365     if (ret == TRACE_ABNORMAL) {
366         std::string errorMessage = "The status of the trace is abnormal";
367         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
368         AniUtil::ThrowErrorMessage(env, errorMessage, ErrorCode::SYSTEM_STATUS_ABNORMAL);
369         return;
370     }
371     if (ret == NO_TRACE_RUNNING) {
372         std::string errorMessage = "No capture trace running";
373         apiInvokeRecorder.SetErrorCode(ErrorCode::NO_CAPTURE_TRACE_RUNNING);
374         AniUtil::ThrowErrorMessage(env, errorMessage, ErrorCode::NO_CAPTURE_TRACE_RUNNING);
375         return;
376     }
377 }
378 
GetGraphicsMemorySync(ani_env * env)379 ani_double GetGraphicsMemorySync(ani_env *env)
380 {
381     ApiInvokeRecorder apiInvokeRecorder("getGraphicsMemorySync");
382     std::optional<int32_t> result = HidebugNativeInterface::GetInstance().GetGraphicsMemory();
383     if (result) {
384         return static_cast<ani_double>(result.value());
385     }
386     constexpr const char* errMsg = "Failed to get the application memory due to a remote exception";
387     AniUtil::ThrowErrorMessage(env, errMsg, ErrorCode::SYSTEM_STATUS_ABNORMAL);
388     apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
389     return 0;
390 }
391 
ANI_Constructor(ani_vm * vm,uint32_t * result)392 ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)
393 {
394     ani_env *env = nullptr;
395     if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) {
396         return ANI_ERROR;
397     }
398     ani_namespace nameSpace = nullptr;
399     if (ANI_OK != env->FindNamespace("L@ohos/hidebug/hidebug;", &nameSpace)) {
400         return ANI_ERROR;
401     }
402     std::array methods = {
403         ani_native_function {"getPss", ":Lescompat/BigInt;", reinterpret_cast<void *>(GetPss)},
404         ani_native_function {"getSharedDirty", ":Lescompat/BigInt;", reinterpret_cast<void *>(GetSharedDirty)},
405         ani_native_function {"getPrivateDirty", ":Lescompat/BigInt;", reinterpret_cast<void *>(GetPrivateDirty)},
406         ani_native_function {"getCpuUsage", ":D", reinterpret_cast<void *>(GetCpuUsage)},
407         ani_native_function {"getServiceDump", "DDLescompat/Array;:V", reinterpret_cast<void *>(GetServiceDump)},
408         ani_native_function {"getNativeHeapSize", ":Lescompat/BigInt;", reinterpret_cast<void *>(GetNativeHeapSize)},
409         ani_native_function {"getNativeHeapAllocatedSize", ":Lescompat/BigInt;",
410             reinterpret_cast<void *>(GetNativeHeapAllocatedSize)},
411         ani_native_function {"getNativeHeapFreeSize", ":Lescompat/BigInt;",
412             reinterpret_cast<void *>(GetNativeHeapFreeSize)},
413         ani_native_function {"getVss", ":Lescompat/BigInt;", reinterpret_cast<void *>(GetVss)},
414         ani_native_function {"getAppThreadCpuUsage", ":[L@ohos/hidebug/hidebug/ThreadCpuUsage;",
415             reinterpret_cast<void *>(GetAppThreadCpuUsage)},
416         ani_native_function {"getSystemCpuUsage", ":D", reinterpret_cast<void *>(GetSystemCpuUsage)},
417         ani_native_function {"getAppNativeMemInfo", ":L@ohos/hidebug/hidebug/NativeMemInfo;",
418             reinterpret_cast<void *>(GetAppNativeMemInfo)},
419         ani_native_function {"getSystemMemInfo", ":L@ohos/hidebug/hidebug/SystemMemInfo;",
420             reinterpret_cast<void *>(GetSystemMemInfo)},
421         ani_native_function {"startAppTraceCapture", "[DL@ohos/hidebug/hidebug/TraceFlag;D:Lstd/core/String;",
422             reinterpret_cast<void *>(StartAppTraceCapture)},
423         ani_native_function {"stopAppTraceCapture", ":V", reinterpret_cast<void *>(StopAppTraceCapture)},
424         ani_native_function {"getGraphicsMemorySync", ":D", reinterpret_cast<void *>(GetGraphicsMemorySync)},
425     };
426     if (ANI_OK != env->Namespace_BindNativeFunctions(nameSpace, methods.data(), methods.size())) {
427         return ANI_ERROR;
428     }
429     *result = ANI_VERSION_1;
430     return ANI_OK;
431 }
432