• 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 #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