• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-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 "font_manager_addon.h"
17 
18 #include "font_define.h"
19 #include "font_hilog.h"
20 #include "font_manager_client.h"
21 
22 namespace OHOS {
23 namespace Global {
24 namespace FontManager {
25 
26 static constexpr int32_t ARRAY_SUBCRIPTOR_ZERO = 0;
27 static constexpr int32_t ARGS_SIZE_ONE = 1;
Init(napi_env env,napi_value exports)28 napi_value FontManagerAddon::Init(napi_env env, napi_value exports)
29 {
30     napi_property_descriptor properties[] = {
31         DECLARE_NAPI_FUNCTION("installFont", InstallFont),
32         DECLARE_NAPI_FUNCTION("uninstallFont", UninstallFont)
33     };
34     napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties);
35     return exports;
36 }
37 
GetCallbackErrorCode(napi_env env,const int32_t errCode,const std::string & errMsg)38 napi_value GetCallbackErrorCode(napi_env env, const int32_t errCode, const std::string &errMsg)
39 {
40     napi_value error = nullptr;
41     napi_value eCode = nullptr;
42     napi_value eMsg = nullptr;
43     napi_create_int32(env, errCode, &eCode);
44     napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &eMsg);
45     napi_create_object(env, &error);
46     napi_set_named_property(env, error, "code", eCode);
47     napi_set_named_property(env, error, "message", eMsg);
48     return error;
49 }
50 
Complete(napi_env env,napi_status status,void * data)51 void FontManagerAddon::Complete(napi_env env, napi_status status, void* data)
52 {
53     if (data == nullptr) {
54         return;
55     }
56     FontNapiCallback *fontNapiCallback = static_cast<FontNapiCallback*>(data);
57     if (fontNapiCallback == nullptr) {
58         return;
59     }
60     napi_value finalResult = nullptr;
61     napi_status ret = napi_create_int32(env, fontNapiCallback->errCode_, &finalResult);
62     if (ret != napi_ok) {
63         FONT_LOGE("InstallFont: create int result failed");
64         fontNapiCallback->success_ = false;
65     }
66 
67     napi_value result[] = { nullptr, nullptr };
68     if (fontNapiCallback->success_) {
69         napi_get_undefined(env, &result[0]);
70         result[1] = finalResult;
71     } else {
72         result[0] = GetCallbackErrorCode(env, fontNapiCallback->errCode_, fontNapiCallback->errMsg_.c_str());
73         napi_get_undefined(env, &result[1]);
74     }
75     ProcessPromiseResult(env, fontNapiCallback, result);
76     napi_delete_async_work(env, fontNapiCallback->work_);
77     delete fontNapiCallback;
78 };
79 
ProcessPromiseResult(napi_env env,FontNapiCallback * fontCallback,napi_value (& result)[2])80 void FontManagerAddon::ProcessPromiseResult(napi_env env, FontNapiCallback *fontCallback, napi_value (&result)[2])
81 {
82     if (fontCallback == nullptr) {
83         return;
84     }
85 
86     if (fontCallback->success_) {
87         if (napi_resolve_deferred(env, fontCallback->deferred_, result[1]) != napi_ok) {
88             FONT_LOGE("napi_resolve_deferred failed");
89         }
90     } else {
91         if (napi_reject_deferred(env, fontCallback->deferred_, result[0]) != napi_ok) {
92             FONT_LOGE("napi_reject_deferred failed");
93         }
94     }
95 }
96 
GetResult(napi_env env,std::unique_ptr<FontNapiCallback> & callback,const std::string & name,napi_async_execute_callback execute)97 napi_value FontManagerAddon::GetResult(napi_env env, std::unique_ptr<FontNapiCallback> &callback,
98     const std::string &name, napi_async_execute_callback execute)
99 {
100     napi_value result = nullptr;
101     if (callback == nullptr) {
102         return result;
103     }
104     napi_create_promise(env, &callback->deferred_, &result);
105 
106     napi_value resource = nullptr;
107     napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &resource);
108     if (napi_create_async_work(env, nullptr, resource, execute, FontManagerAddon::Complete,
109         static_cast<void*>(callback.get()), &callback->work_) != napi_ok) {
110         FONT_LOGE("Failed to create async work for %{public}s", name.c_str());
111         return result;
112     }
113     if (napi_queue_async_work_with_qos(env, callback->work_, napi_qos_user_initiated) != napi_ok) {
114         FONT_LOGE("Failed to queue async work for %{public}s", name.c_str());
115         return result;
116     }
117     callback.release();
118     return result;
119 }
120 
__anon88854f7c0102(napi_env env, void* data) 121 auto installFontFunc = [](napi_env env, void* data) {
122     if (data == nullptr) {
123         return;
124     }
125 
126     FontNapiCallback *callback = static_cast<FontNapiCallback*>(data);
127     if (callback->value_.empty()) {
128         callback->SetErrorMsg("invalid param", ERR_FILE_NOT_EXISTS);
129         return;
130     }
131     int ret = FontManagerClient::InstallFont(callback->value_, callback->errCode_);
132     if (ret != SUCCESS) {
133         callback->SetErrorMsg("Other error.", ERR_INSTALL_FAIL);
134     }
135     if (callback->errCode_ != SUCCESS) {
136         std::string msg = "";
137         switch (callback->errCode_) {
138             case ERR_NO_PERMISSION :
139                 msg = "Permission denied.";
140                 break;
141             case ERR_NOT_SYSTEM_APP :
142                 msg = "Non-system application.";
143                 break;
144             case ERR_FILE_NOT_EXISTS :
145                 msg = "Font does not exist.";
146                 break;
147             case ERR_FILE_VERIFY_FAIL :
148                 msg = "Font is not supported.";
149                 break;
150             case ERR_COPY_FAIL :
151                 msg = "Font file copy failed.";
152                 break;
153             case ERR_INSTALLED_ALRADY :
154                 msg = "Font file installed.";
155                 break;
156             case ERR_MAX_FILE_COUNT :
157                 msg = "Exceeded maximum number of installed files.";
158                 break;
159             default:
160                 msg = "Other error.";
161         }
162         callback->SetErrorMsg(msg, callback->errCode_);
163     }
164     return;
165 };
166 
InstallFont(napi_env env,napi_callback_info info)167 napi_value FontManagerAddon::InstallFont(napi_env env, napi_callback_info info)
168 {
169     return ProcessFontByValue(env, info, "InstallFont", installFontFunc);
170 }
171 
__anon88854f7c0202(napi_env env, void* data) 172 auto uninstallFontFunc = [](napi_env env, void* data) {
173     if (data == nullptr) {
174         return;
175     }
176 
177     FontNapiCallback *callback = static_cast<FontNapiCallback*>(data);
178     if (callback->value_.empty()) {
179         callback->SetErrorMsg("invalid param", ERR_UNINSTALL_FILE_NOT_EXISTS);
180         return;
181     }
182     int ret = FontManagerClient::UninstallFont(callback->value_, callback->errCode_);
183     if (ret != SUCCESS) {
184         callback->SetErrorMsg("Other error.", ERR_UNINSTALL_FAIL);
185     }
186     if (callback->errCode_ != SUCCESS) {
187         std::string msg = "";
188         switch (callback->errCode_) {
189             case ERR_NO_PERMISSION :
190                 msg = "Permission denied.";
191                 break;
192             case ERR_NOT_SYSTEM_APP :
193                 msg = "Non-system application.";
194                 break;
195             case ERR_UNINSTALL_FILE_NOT_EXISTS :
196                 msg = "Font file does not exist.";
197                 break;
198             case ERR_UNINSTALL_REMOVE_FAIL :
199                 msg = "Font file delete error.";
200                 break;
201             default:
202                 msg = "Other error.";
203         }
204         callback->SetErrorMsg(msg, callback->errCode_);
205     }
206     return;
207 };
208 
UninstallFont(napi_env env,napi_callback_info info)209 napi_value FontManagerAddon::UninstallFont(napi_env env, napi_callback_info info)
210 {
211     return ProcessFontByValue(env, info, "UninstallFont", uninstallFontFunc);
212 }
213 
ProcessFontByValue(napi_env env,napi_callback_info info,const std::string & name,napi_async_execute_callback execute)214 napi_value FontManagerAddon::ProcessFontByValue(
215     napi_env env, napi_callback_info info, const std::string &name, napi_async_execute_callback execute)
216 {
217     FONT_LOGI("ProcessFontByValue, func:%{public}s", name.c_str());
218     size_t argc = ARGS_SIZE_ONE;
219     napi_value argv[ARGS_SIZE_ONE] = {nullptr};
220     napi_value thisVar = nullptr;
221     void *data = nullptr;
222     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
223     std::unique_ptr<FontNapiCallback> callback = std::make_unique<FontNapiCallback>();
224     callback->value_ = GetResNameOrPath(env, argc, argv);
225     FONT_LOGD("ProcessFontByValue callback->value_= %{public}s", callback->value_.c_str());
226     return GetResult(env, callback, name, execute);
227 }
228 
GetResNameOrPath(napi_env env,size_t argc,napi_value * argv)229 std::string FontManagerAddon::GetResNameOrPath(napi_env env, size_t argc, napi_value *argv)
230 {
231     if (argc == 0 || argv == nullptr) {
232         return "";
233     }
234 
235     napi_valuetype valuetype;
236     napi_typeof(env, argv[0], &valuetype);
237     if (valuetype != napi_string) {
238         FONT_LOGE("Invalid param, not string");
239         return "";
240     }
241     size_t len = 0;
242     napi_status status = napi_get_value_string_utf8(
243         env, argv[ARRAY_SUBCRIPTOR_ZERO], nullptr, ARRAY_SUBCRIPTOR_ZERO, &len);
244     if (status != napi_ok) {
245         FONT_LOGE("Failed to get font path length");
246         return "";
247     }
248     std::vector<char> buf(len + 1);
249     status = napi_get_value_string_utf8(env, argv[ARRAY_SUBCRIPTOR_ZERO], buf.data(), len + 1, &len);
250     if (status != napi_ok) {
251         FONT_LOGE("Failed to get font file path");
252         return "";
253     }
254     return buf.data();
255 }
256 } // namespace FontManager
257 } // namespace Global
258 } // namespace OHOS