• 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 "net_conn_client.h"
17 #include <ani.h>
18 #include <array>
19 #include <cstdint>
20 #include <iostream>
21 #include <string>
22 #include <vector>
23 
24 static const int32_t ANI_ERROR_CODE = 3;
25 
26 constexpr const char *NET_HANDLE_INNER = "L@ohos/net/connection/connection/NetHandleInner;";
27 constexpr const char *BUSINESS_ERROR = "L@ohos/base/BusinessError;";
28 constexpr const char *CTOR = "<ctor>";
29 
30 static const std::unordered_map<int32_t, std::string> errorMap = {
31     {201, "Permission denied."},
32     {2100002, "Failed to connect to the service."},
33     {2100003, "System internal error."},
34 };
35 
ANIUtils_StdStringToANIString(ani_env * env,std::string str)36 ani_string ANIUtils_StdStringToANIString(ani_env *env, std::string str)
37 {
38     ani_string result_string{};
39     env->String_NewUTF8(str.c_str(), str.size(), &result_string);
40     return result_string;
41 }
42 
GetClass(ani_env * env,const char * className)43 ani_class GetClass(ani_env *env, const char *className)
44 {
45     ani_class cls;
46     if (ANI_OK != env->FindClass(className, &cls)) {
47         std::cerr << "Not found '" << className << "'" << std::endl;
48     }
49     return cls;
50 }
GetMethod(ani_env * env,ani_class cls,const char * methodName,const char * methodSignature)51 ani_method GetMethod(ani_env *env, ani_class cls, const char *methodName, const char *methodSignature)
52 {
53     ani_method method;
54     if (ANI_OK != env->Class_FindMethod(cls, methodName, methodSignature, &method)) {
55         std::cerr << "Not found method '" << methodName << methodSignature << "'" << std::endl;
56     }
57     return method;
58 }
59 
ObjectNew(ani_env * env,const char * className,const char * methodSignature)60 ani_object ObjectNew(ani_env *env, const char *className, const char *methodSignature)
61 {
62     ani_class cls = GetClass(env, className);
63     ani_method ctor = GetMethod(env, cls, CTOR, methodSignature);
64     ani_object result;
65     env->Object_New(cls, ctor, &result);
66     return result;
67 }
68 
throwBusinessError(ani_env * env,int32_t code,std::string & msg)69 void throwBusinessError(ani_env *env, int32_t code, std::string &msg)
70 {
71     ani_class businessError = GetClass(env, BUSINESS_ERROR);
72     ani_method businessErrorCtor = GetMethod(env, businessError, CTOR, "DLescompat/Error;:V");
73     ani_class errorcls = GetClass(env, "Lescompat/Error;");
74     ani_method ctor = GetMethod(env, errorcls, CTOR, "Lstd/core/String;:V");
75     ani_string errorMsg = ANIUtils_StdStringToANIString(env, msg);
76 
77     ani_object errorObj;
78     env->Object_New(errorcls, ctor, &errorObj, errorMsg);
79 
80     ani_object businessErrorObj;
81     env->Object_New(businessError, businessErrorCtor, &businessErrorObj, errorObj);
82     env->ThrowError(static_cast<ani_error>(businessErrorObj));
83 }
84 
getDefaultNetSync(ani_env * env)85 static ani_object getDefaultNetSync([[maybe_unused]] ani_env *env)
86 {
87     OHOS::NetManagerStandard::NetHandle nethandle;
88     int32_t ret = OHOS::NetManagerStandard::NetConnClient::GetInstance().GetDefaultNet(nethandle);
89     if (ret == 0) {
90         ani_object nethandleInner = ObjectNew(env, NET_HANDLE_INNER, nullptr);
91         ani_class cls = GetClass(env, NET_HANDLE_INNER);
92         ani_method setter = GetMethod(env, cls, "<set>netId", nullptr);
93         env->Object_CallMethod_Void(nethandleInner, setter, ani_double(nethandle.GetNetId()));
94         return nethandleInner;
95     } else {
96         ani_ref undefined;
97         env->GetUndefined(&undefined);
98 
99         std::string msg;
100         auto it = errorMap.find(ret);
101         if (it != errorMap.end()) {
102             msg = it->second;
103         } else {
104             msg = "Unknown error.";
105         }
106         throwBusinessError(env, ret, msg);
107         return static_cast<ani_object>(undefined);
108     }
109 }
110 
ANI_Constructor(ani_vm * vm,uint32_t * result)111 ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)
112 {
113     ani_env *env;
114     if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) {
115         std::cerr << "Unsupported ANI_VERSION_1" << std::endl;
116         return (ani_status)ANI_ERROR_CODE;
117     }
118 
119     ani_namespace connection;
120     env->FindNamespace("L@ohos/net/connection/connection;", &connection);
121 
122     std::array methods = {
123         ani_native_function{"getDefaultNetSync", nullptr, reinterpret_cast<void *>(getDefaultNetSync)},
124     };
125 
126     if (ANI_OK != env->Namespace_BindNativeFunctions(connection, methods.data(), methods.size())) {
127         return (ani_status)ANI_ERROR_CODE;
128     };
129 
130     *result = ANI_VERSION_1;
131     return ANI_OK;
132 }