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 #define LOG_TAG "UniformTypeDescriptorAni"
17
18 #include "ani_utils.h"
19 #include "logger.h"
20 #include "error_code.h"
21 #include "utd_client.h"
22 #include <ani.h>
23
24 using namespace OHOS::UDMF;
25
26 static uint32_t paramsCheckError = 401;
27
ThrowBusinessError(ani_env * env,int errCode,std::string && errMsg)28 static void ThrowBusinessError(ani_env *env, int errCode, std::string&& errMsg)
29 {
30 LOG_INFO(UDMF_KITS_NAPI, "Begin ThrowBusinessError.");
31 static const char *errorClsName = "L@ohos/base/BusinessError;";
32 ani_class cls {};
33 if (ANI_OK != env->FindClass(errorClsName, &cls)) {
34 LOG_ERROR(UDMF_KITS_NAPI, "find class BusinessError %{public}s failed", errorClsName);
35 return;
36 }
37 ani_method ctor;
38 if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", ":V", &ctor)) {
39 LOG_ERROR(UDMF_KITS_NAPI, "find method BusinessError.constructor failed");
40 return;
41 }
42 ani_object errorObject;
43 if (ANI_OK != env->Object_New(cls, ctor, &errorObject)) {
44 LOG_ERROR(UDMF_KITS_NAPI, "create BusinessError object failed");
45 return;
46 }
47 ani_double aniErrCode = static_cast<ani_double>(errCode);
48 ani_string errMsgStr;
49 if (ANI_OK != env->String_NewUTF8(errMsg.c_str(), errMsg.size(), &errMsgStr)) {
50 LOG_ERROR(UDMF_KITS_NAPI, "convert errMsg to ani_string failed");
51 return;
52 }
53 if (ANI_OK != env->Object_SetFieldByName_Double(errorObject, "code", aniErrCode)) {
54 LOG_ERROR(UDMF_KITS_NAPI, "set error code failed");
55 return;
56 }
57 if (ANI_OK != env->Object_SetPropertyByName_Ref(errorObject, "message", errMsgStr)) {
58 LOG_ERROR(UDMF_KITS_NAPI, "set error message failed");
59 return;
60 }
61 env->ThrowError(static_cast<ani_error>(errorObject));
62 return;
63 }
64
GetUniformDataTypeByFilenameExtension(ani_env * env,ani_string filenameExtension,ani_object belongsTo)65 static ani_string GetUniformDataTypeByFilenameExtension(ani_env *env, ani_string filenameExtension,
66 ani_object belongsTo)
67 {
68 LOG_INFO(UDMF_KITS_NAPI, "GetUniformDataTypeByFilenameExtension is called!");
69 if (filenameExtension == nullptr) {
70 ThrowBusinessError(env, paramsCheckError, "ParserParam failed!");
71 return nullptr;
72 }
73 std::string filenameExtension_ = AniStringUtils::ToStd(env, filenameExtension);
74 if (filenameExtension_.empty()) {
75 ThrowBusinessError(env, paramsCheckError, "ParserParam failed!");
76 return nullptr;
77 }
78 ani_boolean isUndefined;
79 if (ANI_OK != env->Reference_IsUndefined(belongsTo, &isUndefined)) {
80 LOG_ERROR(UDMF_KITS_NAPI, "Object_GetFieldByName_Ref isRepeat failed.");
81 return nullptr;
82 }
83 std::string typeId;
84 auto status = E_OK;
85 if (isUndefined) {
86 status = UtdClient::GetInstance().GetUniformDataTypeByFilenameExtension(filenameExtension_, typeId);
87 } else {
88 std::string belongsTo_ = AniStringUtils::ToStd(env, static_cast<ani_string>(belongsTo));
89 status = UtdClient::GetInstance().GetUniformDataTypeByFilenameExtension(filenameExtension_, typeId, belongsTo_);
90 }
91
92 if (status != E_OK) {
93 LOG_ERROR(UDMF_KITS_NAPI, "invalid arguments!");
94 return nullptr;
95 }
96
97 if (!typeId.empty()) {
98 return AniStringUtils::ToAni(env, typeId);
99 }
100 return nullptr;
101 }
102
103
ANI_Constructor(ani_vm * vm,uint32_t * result)104 ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)
105 {
106 ani_env *env;
107 if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) {
108 LOG_ERROR(UDMF_KITS_NAPI, "Unsupported ANI_VERSION_1");
109 return ANI_ERROR;
110 }
111
112 static const char *nsName = "L@ohos/data/uniformTypeDescriptor/uniformTypeDescriptor;";
113 ani_namespace ns;
114 if (ANI_OK != env->FindNamespace(nsName, &ns)) {
115 LOG_ERROR(UDMF_KITS_NAPI, "Not found %{public}s", nsName);
116 return ANI_ERROR;
117 }
118
119 std::array methods = {
120 ani_native_function {"getUniformDataTypeByFilenameExtension", nullptr,
121 reinterpret_cast<void *>(GetUniformDataTypeByFilenameExtension) },
122 };
123
124 if (ANI_OK != env->Namespace_BindNativeFunctions(ns, methods.data(), methods.size())) {
125 LOG_ERROR(UDMF_KITS_NAPI, "Cannot bind native methods to %{public}s", nsName);
126 return ANI_ERROR;
127 };
128
129 if (result == nullptr) {
130 LOG_ERROR(UDMF_KITS_NAPI, "param result is null");
131 return ANI_ERROR;
132 }
133 *result = ANI_VERSION_1;
134 return ANI_OK;
135 }