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 "resource_manager_ani_utils.h"
17
18 #include "hilog_wrapper.h"
19 #include "rstate.h"
20
21 using namespace OHOS;
22 using namespace Global;
23 using namespace Resource;
24
25 const std::unordered_map<int32_t, std::string> ResourceManagerAniUtils::ErrorCodeToMsg {
26 {ERROR_CODE_INVALID_INPUT_PARAMETER, "Invalid input parameter"},
27 {ERROR_CODE_RES_ID_NOT_FOUND, "Invalid resource ID"},
28 {ERROR_CODE_RES_NAME_NOT_FOUND, "Invalid resource name"},
29 {ERROR_CODE_RES_NOT_FOUND_BY_ID, "No matching resource is found based on the resource ID"},
30 {ERROR_CODE_RES_NOT_FOUND_BY_NAME, "No matching resource is found based on the resource name"},
31 {ERROR_CODE_RES_PATH_INVALID, "Invalid relative path"},
32 {ERROR_CODE_RES_REF_TOO_MUCH, "The resource is referenced cyclically"},
33 {ERROR_CODE_RES_ID_FORMAT_ERROR, "Failed to format the resource obtained based on the resource ID"},
34 {ERROR_CODE_RES_NAME_FORMAT_ERROR, "Failed to format the resource obtained based on the resource Name"},
35 {ERROR_CODE_SYSTEM_RES_MANAGER_GET_FAILED, "Failed to access the system resource"},
36 {ERROR_CODE_OVERLAY_RES_PATH_INVALID, "Invalid overlay path"},
37 {ERROR, "Unknow error"}
38 };
39
FindErrMsg(int32_t errCode)40 std::string ResourceManagerAniUtils::FindErrMsg(int32_t errCode)
41 {
42 auto iter = ResourceManagerAniUtils::ErrorCodeToMsg.find(errCode);
43 std::string errMsg = iter != ResourceManagerAniUtils::ErrorCodeToMsg.end() ? iter->second : "";
44 return errMsg;
45 }
46
WrapStsError(ani_env * env,const std::string & msg)47 ani_object ResourceManagerAniUtils::WrapStsError(ani_env *env, const std::string &msg)
48 {
49 ani_class cls {};
50 ani_method method {};
51 ani_object obj = nullptr;
52 ani_status status = ANI_ERROR;
53 if (env == nullptr) {
54 RESMGR_HILOGE(RESMGR_ANI_TAG, "null env");
55 return nullptr;
56 }
57
58 ani_string aniMsg = nullptr;
59 if ((status = env->String_NewUTF8(msg.c_str(), msg.size(), &aniMsg)) != ANI_OK) {
60 RESMGR_HILOGE(RESMGR_ANI_TAG, "String_NewUTF8 failed %{public}d", status);
61 return nullptr;
62 }
63
64 ani_ref undefRef;
65 if ((status = env->GetUndefined(&undefRef)) != ANI_OK) {
66 RESMGR_HILOGE(RESMGR_ANI_TAG, "GetUndefined failed %{public}d", status);
67 return nullptr;
68 }
69
70 if ((status = env->FindClass("Lescompat/Error;", &cls)) != ANI_OK) {
71 RESMGR_HILOGE(RESMGR_ANI_TAG, "FindClass failed %{public}d", status);
72 return nullptr;
73 }
74 if ((status = env->Class_FindMethod(cls, "<ctor>", "Lstd/core/String;Lescompat/ErrorOptions;:V", &method)) !=
75 ANI_OK) {
76 RESMGR_HILOGE(RESMGR_ANI_TAG, "Class_FindMethod failed %{public}d", status);
77 return nullptr;
78 }
79
80 if ((status = env->Object_New(cls, method, &obj, aniMsg, undefRef)) != ANI_OK) {
81 RESMGR_HILOGE(RESMGR_ANI_TAG, "Object_New failed %{public}d", status);
82 return nullptr;
83 }
84 return obj;
85 }
86
CreateError(ani_env * env,ani_int code,const std::string & msg)87 ani_object ResourceManagerAniUtils::CreateError(ani_env *env, ani_int code, const std::string &msg)
88 {
89 ani_class cls {};
90 ani_method method {};
91 ani_object obj = nullptr;
92 ani_status status = ANI_ERROR;
93 if (env == nullptr) {
94 RESMGR_HILOGE(RESMGR_ANI_TAG, "null env");
95 return nullptr;
96 }
97 if ((status = env->FindClass("L@ohos/base/BusinessError;", &cls)) != ANI_OK) {
98 RESMGR_HILOGE(RESMGR_ANI_TAG, "FindClass failed %{public}d", status);
99 return nullptr;
100 }
101 if ((status = env->Class_FindMethod(cls, "<ctor>", "DLescompat/Error;:V", &method)) != ANI_OK) {
102 RESMGR_HILOGE(RESMGR_ANI_TAG, "Class_FindMethod failed %{public}d", status);
103 return nullptr;
104 }
105 ani_object error = WrapStsError(env, msg);
106 if (error == nullptr) {
107 RESMGR_HILOGE(RESMGR_ANI_TAG, "error null");
108 return nullptr;
109 }
110 ani_double dCode(code);
111 if ((status = env->Object_New(cls, method, &obj, dCode, error)) != ANI_OK) {
112 RESMGR_HILOGE(RESMGR_ANI_TAG, "Object_New failed %{public}d", status);
113 return nullptr;
114 }
115 return obj;
116 }
117
AniThrow(ani_env * env,int32_t errCode)118 void ResourceManagerAniUtils::AniThrow(ani_env *env, int32_t errCode)
119 {
120 std::string errMsg = FindErrMsg(errCode);
121 if (errMsg != "") {
122 ani_object error = CreateError(env, errCode, errMsg);
123 env->ThrowError(static_cast<ani_error>(error));
124 }
125 }
126