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 #include "ani_error.h"
16
17 #include <unordered_map>
18
19 #include "access_token_error.h"
20 #include "accesstoken_common_log.h"
21 #include "data_validator.h"
22
23 namespace OHOS {
24 namespace Security {
25 namespace AccessToken {
26 constexpr const char* BUSINESS_ERROR_CLASS = "L@ohos/base/BusinessError;";
27 static const std::unordered_map<uint32_t, const char*> g_errorStringMap = {
28 { STS_ERROR_PERMISSION_DENIED, "Permission denied." },
29 { STS_ERROR_NOT_SYSTEM_APP, "Not system app." },
30 { STS_ERROR_SYSTEM_CAPABILITY_NOT_SUPPORT, "Not support system capability." },
31 { STS_ERROR_START_ABILITY_FAIL, "Start grant ability failed." },
32 { STS_ERROR_BACKGROUND_FAIL, "UI extension turn background failed." },
33 { STS_ERROR_TERMINATE_FAIL, "UI extension terminate failed." },
34 { STS_ERROR_PARAM_INVALID, "Invalid parameter." },
35 { STS_ERROR_TOKENID_NOT_EXIST, "The specified token id does not exist." },
36 { STS_ERROR_PERMISSION_NOT_EXIST, "The specified permission does not exist." },
37 { STS_ERROR_NOT_USE_TOGETHER, "The API is not used in pair with others." },
38 { STS_ERROR_REGISTERS_EXCEED_LIMITATION, "The number of registered listeners exceeds limitation." },
39 { STS_ERROR_PERMISSION_OPERATION_NOT_ALLOWED, "The operation of specified permission is not allowed." },
40 { STS_ERROR_SERVICE_NOT_RUNNING, "The service is abnormal." },
41 { STS_ERROR_OUT_OF_MEMORY, "Out of memory." },
42 { STS_ERROR_INNER, "Common inner error." },
43 { STS_ERROR_REQUEST_IS_ALREADY_EXIST, "The request already exists." },
44 { STS_ERROR_ALL_PERM_GRANTED, "All permissions in the permission list have been granted." },
45 { STS_ERROR_PERM_NOT_REVOKE_BY_USER,
46 "The permission list contains the permission that has not been revoked by the user." },
47 { STS_ERROR_GLOBAL_SWITCH_IS_ALREADY_OPEN, "The specific global switch is already open." },
48 };
49
ThrowError(ani_env * env,int32_t err,const std::string & errMsg)50 void BusinessErrorAni::ThrowError(ani_env* env, int32_t err, const std::string& errMsg)
51 {
52 if (env == nullptr) {
53 return;
54 }
55 ani_object error = CreateError(env, err, errMsg);
56 ThrowError(env, error);
57 }
58
CreateError(ani_env * env,ani_int code,const std::string & msg)59 ani_object BusinessErrorAni::CreateError(ani_env* env, ani_int code, const std::string& msg)
60 {
61 if (env == nullptr) {
62 LOGE(ATM_DOMAIN, ATM_TAG, "Env is null.");
63 return nullptr;
64 }
65 ani_class cls = nullptr;
66 ani_field field = nullptr;
67 ani_method method = nullptr;
68 ani_object obj = nullptr;
69
70 ani_status status = env->FindClass(BUSINESS_ERROR_CLASS, &cls);
71 if (status != ANI_OK) {
72 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to FindClass: %{public}d.", status);
73 return nullptr;
74 }
75 status = env->Class_FindMethod(cls, "<ctor>", ":V", &method);
76 if (status != ANI_OK) {
77 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to Class_FindMethod: %{public}d.", status);
78 return nullptr;
79 }
80 status = env->Object_New(cls, method, &obj);
81 if (status != ANI_OK) {
82 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to Object_New: %{public}d.", status);
83 return nullptr;
84 }
85 status = env->Class_FindField(cls, "code", &field);
86 if (status != ANI_OK) {
87 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to Class_FindField: %{public}d.", status);
88 return nullptr;
89 }
90 status = env->Object_SetField_Double(obj, field, code);
91 if (status != ANI_OK) {
92 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to Object_SetField_Double: %{public}d.", status);
93 return nullptr;
94 }
95 status = env->Class_FindField(cls, "data", &field);
96 if (status != ANI_OK) {
97 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to Class_FindField: %{public}d.", status);
98 return nullptr;
99 }
100 ani_string string = nullptr;
101 env->String_NewUTF8(msg.c_str(), msg.size(), &string);
102 status = env->Object_SetField_Ref(obj, field, static_cast<ani_ref>(string));
103 if (status != ANI_OK) {
104 LOGE(ATM_DOMAIN, ATM_TAG, "Failed to Object_SetField_Ref: %{public}d.", status);
105 return nullptr;
106 }
107 return obj;
108 }
109
GetParamErrorMsg(const std::string & param,const std::string & errMsg)110 std::string GetParamErrorMsg(const std::string& param, const std::string& errMsg)
111 {
112 std::string msg = "Parameter Error. The type of \"" + param + "\" must be " + errMsg + ".";
113 return msg;
114 }
115
GetErrorMessage(int32_t errCode,const std::string & extendMsg)116 std::string GetErrorMessage(int32_t errCode, const std::string& extendMsg)
117 {
118 auto iter = g_errorStringMap.find(errCode);
119 if (iter != g_errorStringMap.end()) {
120 return iter->second + (extendMsg.empty() ? "" : ("" + extendMsg));
121 }
122 std::string errMsg = "Failed to Unknown error, errCode " + std::to_string(errCode) + ".";
123 return errMsg;
124 }
125
ThrowParameterTypeError(ani_env * env,int32_t err,const std::string & errMsg)126 void BusinessErrorAni::ThrowParameterTypeError(ani_env* env, int32_t err, const std::string& errMsg)
127 {
128 if (env == nullptr) {
129 return;
130 }
131 ani_object error = CreateError(env, err, errMsg);
132 ThrowError(env, error);
133 }
134
ThrowError(ani_env * env,ani_object err)135 void BusinessErrorAni::ThrowError(ani_env* env, ani_object err)
136 {
137 if (err == nullptr) {
138 LOGE(ATM_DOMAIN, ATM_TAG, "Err is null.");
139 return;
140 }
141 env->ThrowError(static_cast<ani_error>(err));
142 }
143
GetStsErrorCode(int32_t errCode)144 int32_t BusinessErrorAni::GetStsErrorCode(int32_t errCode)
145 {
146 int32_t stsCode;
147 switch (errCode) {
148 case RET_SUCCESS:
149 stsCode = STS_OK;
150 break;
151 case ERR_PERMISSION_DENIED:
152 stsCode = STS_ERROR_PERMISSION_DENIED;
153 break;
154 case ERR_NOT_SYSTEM_APP:
155 stsCode = STS_ERROR_NOT_SYSTEM_APP;
156 break;
157 case ERR_PARAM_INVALID:
158 stsCode = STS_ERROR_PARAM_INVALID;
159 break;
160 case ERR_TOKENID_NOT_EXIST:
161 stsCode = STS_ERROR_TOKENID_NOT_EXIST;
162 break;
163 case ERR_PERMISSION_NOT_EXIST:
164 stsCode = STS_ERROR_PERMISSION_NOT_EXIST;
165 break;
166 case ERR_INTERFACE_NOT_USED_TOGETHER:
167 case ERR_CALLBACK_ALREADY_EXIST:
168 stsCode = STS_ERROR_NOT_USE_TOGETHER;
169 break;
170 case ERR_CALLBACKS_EXCEED_LIMITATION:
171 stsCode = STS_ERROR_REGISTERS_EXCEED_LIMITATION;
172 break;
173 case ERR_IDENTITY_CHECK_FAILED:
174 stsCode = STS_ERROR_PERMISSION_OPERATION_NOT_ALLOWED;
175 break;
176 case ERR_SERVICE_ABNORMAL:
177 case ERROR_IPC_REQUEST_FAIL:
178 case ERR_READ_PARCEL_FAILED:
179 case ERR_WRITE_PARCEL_FAILED:
180 stsCode = STS_ERROR_SERVICE_NOT_RUNNING;
181 break;
182 case ERR_MALLOC_FAILED:
183 stsCode = STS_ERROR_OUT_OF_MEMORY;
184 break;
185 default:
186 stsCode = STS_ERROR_INNER;
187 break;
188 }
189 LOGD(ATM_DOMAIN, ATM_TAG, "GetStsErrorCode nativeCode(%{public}d) stsCode(%{public}d).", errCode, stsCode);
190 return stsCode;
191 }
192
ValidateTokenIDWithThrowError(ani_env * env,AccessTokenID tokenID)193 bool BusinessErrorAni::ValidateTokenIDWithThrowError(ani_env* env, AccessTokenID tokenID)
194 {
195 if (!DataValidator::IsTokenIDValid(tokenID)) {
196 std::string errMsg = GetErrorMessage(STS_ERROR_PARAM_INVALID, "The tokenID is 0.");
197 BusinessErrorAni::ThrowError(env, STS_ERROR_PARAM_INVALID, errMsg);
198 return false;
199 }
200 return true;
201 }
202
ValidatePermissionWithThrowError(ani_env * env,const std::string & permission)203 bool BusinessErrorAni::ValidatePermissionWithThrowError(ani_env* env, const std::string& permission)
204 {
205 if (!DataValidator::IsPermissionNameValid(permission)) {
206 std::string errMsg = GetErrorMessage(
207 STS_ERROR_PARAM_INVALID, "The permissionName is empty or exceeds 256 characters.");
208 BusinessErrorAni::ThrowError(env, STS_ERROR_PARAM_INVALID, errMsg);
209 return false;
210 }
211 return true;
212 }
213
ValidatePermissionFlagWithThrowError(ani_env * env,uint32_t flag)214 bool BusinessErrorAni::ValidatePermissionFlagWithThrowError(ani_env* env, uint32_t flag)
215 {
216 if (!DataValidator::IsPermissionFlagValid(flag)) {
217 std::string errMsg = GetErrorMessage(STS_ERROR_PARAM_INVALID, "The permissionFlags is invalid.");
218 BusinessErrorAni::ThrowError(env, STS_ERROR_PARAM_INVALID, errMsg);
219 return false;
220 }
221 return true;
222 }
223 } // namespace AccessToken
224 } // namespace Security
225 } // namespace OHOS
226