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 "system_resource_manager.h"
17 #include "hilog_wrapper.h"
18 #include "resourceManager.h"
19 #include "resource_manager_ani_utils.h"
20 #include "resource_manager_data_context.h"
21 #include "resource_manager_impl.h"
22
23 using namespace OHOS;
24 using namespace Global;
25 using namespace Resource;
26
27 constexpr ani_double ABNORMAL_NUMBER_RETURN_VALUE = -1;
28
29 static constexpr const char *ANI_ARRAY_SIGN = "Lescompat/Array;";
30 static constexpr const char *ANI_STRING_SIGN = "Lstd/core/String;";
31 static constexpr const char *ANI_UINT8ARRAY_SIGN = "Lescompat/Uint8Array;";
32
33 static constexpr const char *RESOURCE_MANAGER_INNER_SIGN =
34 "L@ohos/resourceManager/resourceManager/ResourceManagerInner;";
35 static constexpr const char *RAW_FILE_DESCRIPTOR_SIGN = "Lglobal/rawFileDescriptorInner/RawFileDescriptorInner;";
36 static constexpr const char *NAMESPACE_SIGN = "L@ohos/resourceManager/resourceManager;";
37 static constexpr const char *CONFIGURATION_SIGN = "L@ohos/resourceManager/resourceManager/Configuration;";
38 static constexpr const char *DIRECTION_SIGN = "L@ohos/resourceManager/resourceManager/Direction;";
39 static constexpr const char *DEVICE_TYPE_SIGN = "L@ohos/resourceManager/resourceManager/DeviceType;";
40 static constexpr const char *SCREEN_DENSITY_SIGN = "L@ohos/resourceManager/resourceManager/ScreenDensity;";
41 static constexpr const char *COLOR_MODE_SIGN = "L@ohos/resourceManager/resourceManager/ColorMode;";
42 static constexpr const char *DEVICE_CAPABILITY_SIGN = "L@ohos/resourceManager/resourceManager/DeviceCapability;";
43
44 enum ScreenDensityIndex {
45 SCREEN_DENSITY_ONE = 0,
46 SCREEN_DENSITY_TWO = 1,
47 SCREEN_DENSITY_THREE = 2,
48 SCREEN_DENSITY_FOUR = 3,
49 SCREEN_DENSITY_FIVE = 4,
50 SCREEN_DENSITY_SIX = 5,
51 };
52
53 struct ArrayElement {
54 enum class ElementType {
55 ERROR,
56 NUMBER,
57 STRING,
58 } type;
59 std::variant<double, std::string> value;
60
ArrayElementArrayElement61 ArrayElement(ElementType type, double number) : type(type), value(number) {}
ArrayElementArrayElement62 ArrayElement(ElementType type, const std::string& str) : type(type), value(str) {}
63 };
64
65 static std::shared_ptr<ResourceManager> sysResMgr = nullptr;
66 static std::mutex sysMgrMutex;
67 static std::array methods = {
68 ani_native_function { "getStringSync", "D:Lstd/core/String;",
69 reinterpret_cast<void*>(ResMgrAddon::GetStringSyncById) },
70 ani_native_function { "getStringSync", "DLescompat/Array;:Lstd/core/String;",
71 reinterpret_cast<void *>(ResMgrAddon::GetFormatStringSyncById) },
72
73 ani_native_function { "getStringByNameSync", "Lstd/core/String;:Lstd/core/String;",
74 reinterpret_cast<void*>(ResMgrAddon::GetStringByNameSync) },
75 ani_native_function { "getStringByNameSync", "Lstd/core/String;Lescompat/Array;:Lstd/core/String;",
76 reinterpret_cast<void*>(ResMgrAddon::GetFormatStringByNameSync) },
77
78 ani_native_function { "getBoolean", nullptr, reinterpret_cast<void*>(ResMgrAddon::GetBooleanById) },
79 ani_native_function { "getBooleanByName", nullptr, reinterpret_cast<void*>(ResMgrAddon::GetBooleanByName) },
80
81 ani_native_function { "getNumber", nullptr, reinterpret_cast<void*>(ResMgrAddon::GetNumberById) },
82 ani_native_function { "getNumberByName", nullptr, reinterpret_cast<void*>(ResMgrAddon::GetNumberByName) },
83
84 ani_native_function { "getIntPluralStringValueSync", nullptr,
85 reinterpret_cast<void*>(ResMgrAddon::GetIntPluralStringValueSyncById) },
86 ani_native_function { "getIntPluralStringByNameSync", nullptr,
87 reinterpret_cast<void*>(ResMgrAddon::GetIntPluralStringByNameSync) },
88
89 ani_native_function { "getDoublePluralStringValueSync", nullptr,
90 reinterpret_cast<void*>(ResMgrAddon::GetDoublePluralStringValueSyncById) },
91 ani_native_function { "getDoublePluralStringByNameSync", nullptr,
92 reinterpret_cast<void*>(ResMgrAddon::GetDoublePluralStringByNameSync) },
93
94 ani_native_function { "getColorSync", nullptr, reinterpret_cast<void*>(ResMgrAddon::GetColorSyncById) },
95 ani_native_function { "getColorByNameSync", nullptr, reinterpret_cast<void*>(ResMgrAddon::GetColorByNameSync) },
96
97 ani_native_function { "addResource", nullptr, reinterpret_cast<void*>(ResMgrAddon::AddResource) },
98 ani_native_function { "removeResource", nullptr, reinterpret_cast<void*>(ResMgrAddon::RemoveResource) },
99
100 ani_native_function { "getRawFdSync", nullptr, reinterpret_cast<void*>(ResMgrAddon::GetRawFdSync) },
101 ani_native_function { "closeRawFdSync", nullptr, reinterpret_cast<void*>(ResMgrAddon::CloseRawFdSync) },
102 ani_native_function { "isRawDir", nullptr, reinterpret_cast<void*>(ResMgrAddon::IsRawDir) },
103
104 ani_native_function { "getRawFileListSync", nullptr, reinterpret_cast<void*>(ResMgrAddon::GetRawFileListSync) },
105 ani_native_function { "getRawFileContentSync", nullptr,
106 reinterpret_cast<void*>(ResMgrAddon::GetRawFileContentSync) },
107
108 ani_native_function { "getMediaContentSync", nullptr,
109 reinterpret_cast<void*>(ResMgrAddon::GetMediaContentSyncById) },
110 ani_native_function { "getMediaContentBase64Sync", nullptr,
111 reinterpret_cast<void*>(ResMgrAddon::GetMediaContentBase64SyncById) },
112
113 ani_native_function { "getStringArrayValueSync", nullptr,
114 reinterpret_cast<void*>(ResMgrAddon::GetStringArrayValueSyncById) },
115 ani_native_function { "getStringArrayByNameSync", nullptr,
116 reinterpret_cast<void*>(ResMgrAddon::GetStringArrayByNameSync) },
117
118 ani_native_function { "getMediaByNameSync", nullptr, reinterpret_cast<void*>(ResMgrAddon::GetMediaByNameSync) },
119 ani_native_function { "getMediaBase64ByNameSync", nullptr,
120 reinterpret_cast<void*>(ResMgrAddon::GetMediaBase64ByNameSync) },
121
122 ani_native_function { "getConfigurationSync", nullptr, reinterpret_cast<void*>(ResMgrAddon::GetConfigurationSync) },
123 ani_native_function { "getDeviceCapabilitySync", nullptr,
124 reinterpret_cast<void*>(ResMgrAddon::GetDeviceCapabilitySync) },
125 ani_native_function { "getLocales", nullptr, reinterpret_cast<void*>(ResMgrAddon::GetLocales) },
126
127 ani_native_function { "getSymbol", nullptr, reinterpret_cast<void*>(ResMgrAddon::GetSymbolById) },
128 ani_native_function { "getSymbolByName", nullptr, reinterpret_cast<void*>(ResMgrAddon::GetSymbolByName) },
129
130 ani_native_function { "getOverrideResourceManager", nullptr,
131 reinterpret_cast<void*>(ResMgrAddon::GetOverrideResourceManager) },
132 ani_native_function { "getOverrideConfiguration", nullptr,
133 reinterpret_cast<void*>(ResMgrAddon::GetOverrideConfiguration) },
134 ani_native_function { "updateOverrideConfiguration", nullptr,
135 reinterpret_cast<void*>(ResMgrAddon::UpdateOverrideConfiguration) },
136 };
137
ResMgrAddon(const std::string & bundleName,const std::shared_ptr<ResourceManager> & resMgr,const std::shared_ptr<AbilityRuntime::Context> & context,bool isSystem)138 ResMgrAddon::ResMgrAddon(
139 const std::string& bundleName, const std::shared_ptr<ResourceManager>& resMgr,
140 const std::shared_ptr<AbilityRuntime::Context>& context, bool isSystem)
141 : bundleName_(bundleName), resMgr_(resMgr), context_(context), isSystem_(isSystem)
142 {
143 RESMGR_HILOGD(RESMGR_ANI_TAG, "create ResMgrAddon %{public}s", bundleName_.c_str());
144 }
145
ResMgrAddon(const std::shared_ptr<ResourceManager> & resMgr,bool isSystem)146 ResMgrAddon::ResMgrAddon(const std::shared_ptr<ResourceManager>& resMgr, bool isSystem)
147 : resMgr_(resMgr), isSystem_(isSystem)
148 {
149 RESMGR_HILOGD(RESMGR_ANI_TAG, "create ResMgrAddon.");
150 }
151
CreateResMgr(ani_env * env,const std::string & bundleName,const std::shared_ptr<ResourceManager> & resMgr,std::shared_ptr<AbilityRuntime::Context> context)152 ani_object ResMgrAddon::CreateResMgr(
153 ani_env* env, const std::string& bundleName, const std::shared_ptr<ResourceManager>& resMgr,
154 std::shared_ptr<AbilityRuntime::Context> context)
155 {
156 std::shared_ptr<ResMgrAddon> addon = std::make_shared<ResMgrAddon>(bundleName, resMgr, context);
157 return WrapResourceManager(env, addon);
158 }
159
WrapResourceManager(ani_env * env,std::shared_ptr<ResMgrAddon> & addon)160 ani_object ResMgrAddon::WrapResourceManager(ani_env* env, std::shared_ptr<ResMgrAddon> &addon)
161 {
162 ani_object nativeResMgr;
163 ani_class cls;
164 if (ANI_OK != env->FindClass(RESOURCE_MANAGER_INNER_SIGN, &cls)) {
165 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find class '%{public}s' failed", RESOURCE_MANAGER_INNER_SIGN);
166 return nullptr;
167 }
168
169 ani_method ctor;
170 if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor)) {
171 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find method '<ctor>' failed");
172 return nullptr;
173 }
174
175 auto addonPtr = std::make_unique<std::shared_ptr<ResMgrAddon>>(addon);
176 if (ANI_OK != env->Object_New(cls, ctor, &nativeResMgr, reinterpret_cast<ani_long>(addonPtr.get()))) {
177 RESMGR_HILOGE(RESMGR_ANI_TAG, "New object '%{public}s' failed", RESOURCE_MANAGER_INNER_SIGN);
178 return nullptr;
179 }
180 addonPtr.release();
181 return nativeResMgr;
182 }
183
AniStrToString(ani_env * env,ani_ref aniStr)184 static std::string AniStrToString(ani_env *env, ani_ref aniStr)
185 {
186 ani_string str = static_cast<ani_string>(aniStr);
187 ani_size size = 0;
188 env->String_GetUTF8Size(str, &size);
189
190 std::string result(size, 0);
191 ani_size written;
192 env->String_GetUTF8(str, result.data(), size + 1, &written);
193 return result;
194 }
195
CreateAniUint8Array(ani_env * env,ResMgrDataContext & context)196 static ani_object CreateAniUint8Array(ani_env* env, ResMgrDataContext &context)
197 {
198 size_t length = context.len_;
199 auto data = std::make_unique<uint8_t[]>(length);
200 std::unique_ptr<uint8_t[]> tempData = std::move(context.mediaData);
201 std::copy(tempData.get(), tempData.get() + length, data.get());
202
203 ani_class cls;
204 if (ANI_OK != env->FindClass(ANI_UINT8ARRAY_SIGN, &cls)) {
205 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find class '%{public}s' failed", ANI_UINT8ARRAY_SIGN);
206 return nullptr;
207 }
208
209 ani_method ctor;
210 if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", "I:V", &ctor)) {
211 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find method '<ctor>' failed");
212 return nullptr;
213 }
214
215 ani_object ret = {};
216 if (ANI_OK != env->Object_New(cls, ctor, &ret, length)) {
217 RESMGR_HILOGE(RESMGR_ANI_TAG, "New object '%{public}s' failed", ANI_UINT8ARRAY_SIGN);
218 return nullptr;
219 }
220
221 ani_method set;
222 if (ANI_OK != env->Class_FindMethod(cls, "$_set", "II:V", &set)) {
223 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find method '$_set' failed");
224 return nullptr;
225 }
226
227 for (size_t i = 0; i < length; i++) {
228 if (ANI_OK != env->Object_CallMethod_Void(ret, set, i, data.get()[i])) {
229 RESMGR_HILOGE(RESMGR_ANI_TAG, "Call method '$_set' failed");
230 return nullptr;
231 }
232 }
233
234 return ret;
235 }
236
UnwrapAddon(ani_env * env,ani_object object)237 static std::shared_ptr<ResMgrAddon> UnwrapAddon(ani_env* env, ani_object object)
238 {
239 ani_long ptr;
240 if (ANI_OK != env->Object_GetFieldByName_Long(object, "nativeResMgr", &ptr)) {
241 RESMGR_HILOGE(RESMGR_ANI_TAG, "Get Long 'nativeResMgr' failed");
242 return nullptr;
243 }
244 return *reinterpret_cast<std::shared_ptr<ResMgrAddon>*>(ptr);
245 }
246
CreateAniString(ani_env * env,ResMgrDataContext & context)247 static ani_string CreateAniString(ani_env *env, ResMgrDataContext& context)
248 {
249 ani_string result;
250 std::string str = context.value_;
251 if (ANI_OK != env->String_NewUTF8(str.c_str(), str.size(), &result)) {
252 context.SetErrorMsg("Failed to create result");
253 return nullptr;
254 }
255 return result;
256 }
257
GetSysResourceManager(ani_env * env)258 ani_object ResMgrAddon::GetSysResourceManager(ani_env* env)
259 {
260 auto systemResManager = OHOS::Global::Resource::SystemResourceManager::CreateSysResourceManager();
261 if (systemResManager == nullptr) {
262 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_SYSTEM_RES_MANAGER_GET_FAILED);
263 return nullptr;
264 }
265 std::shared_ptr<ResMgrAddon> addon = std::make_shared<ResMgrAddon>(systemResManager, true);
266 if (addon == nullptr) {
267 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_SYSTEM_RES_MANAGER_GET_FAILED);
268 return nullptr;
269 }
270 return WrapResourceManager(env, addon);
271 }
272
GetHapResourceManager(const ResMgrDataContext * dataContext,std::shared_ptr<ResourceManager> & resMgr,uint32_t & resId)273 static bool GetHapResourceManager(const ResMgrDataContext* dataContext,
274 std::shared_ptr<ResourceManager> &resMgr, uint32_t &resId)
275 {
276 if (dataContext->addon_ == nullptr || dataContext->addon_->GetResMgr() == nullptr) {
277 return false;
278 }
279 resMgr = dataContext->addon_->GetResMgr();
280 resId = dataContext->resId_;
281 return true;
282 }
283
GetStringSyncById(ani_env * env,ani_object object,ani_double resId)284 ani_string ResMgrAddon::GetStringSyncById(ani_env* env, ani_object object, ani_double resId)
285 {
286 auto dataContext = std::make_unique<ResMgrDataContext>();
287 dataContext->addon_ = UnwrapAddon(env, object);
288 dataContext->resId_ = resId;
289
290 std::shared_ptr<ResourceManager> resMgr = nullptr;
291 uint32_t notUse = 0;
292 bool ret = GetHapResourceManager(dataContext.get(), resMgr, notUse);
293 if (!ret || resMgr == nullptr) {
294 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getStringSyncById");
295 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
296 return nullptr;
297 }
298
299 RState state = resMgr->GetStringFormatById(resId, dataContext->value_, dataContext->jsParams_);
300 if (state != RState::SUCCESS) {
301 dataContext->SetErrorMsg("getStringSyncById failed state", true);
302 ResourceManagerAniUtils::AniThrow(env, state);
303 return nullptr;
304 }
305 return CreateAniString(env, *dataContext);
306 }
307
GetArrayElement(ani_env * env,ani_object args,const int index)308 static ArrayElement GetArrayElement(ani_env* env, ani_object args, const int index)
309 {
310 ani_ref value;
311 if (ANI_OK != env->Array_Get_Ref(static_cast<ani_array_ref>(args), index, &value)) {
312 RESMGR_HILOGE(RESMGR_ANI_TAG, "Call get failed");
313 return ArrayElement{ArrayElement::ElementType::ERROR, 0};
314 }
315
316 ani_class stringClass;
317 if (ANI_OK != env->FindClass(ANI_STRING_SIGN, &stringClass)) {
318 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find class ' %{public}s' failed", ANI_STRING_SIGN);
319 return ArrayElement{ArrayElement::ElementType::ERROR, 0};
320 }
321
322 ani_boolean isString;
323 env->Object_InstanceOf(static_cast<ani_object>(value), stringClass, &isString);
324
325 if (isString) {
326 return ArrayElement{ArrayElement::ElementType::STRING, AniStrToString(env, value)};
327 } else {
328 ani_double param;
329 ani_status state = env->Object_CallMethodByName_Double(static_cast<ani_object>(value),
330 "unboxed", ":D", ¶m);
331 if (state != ANI_OK) {
332 return ArrayElement{ArrayElement::ElementType::ERROR, 0};
333 }
334 return ArrayElement{ArrayElement::ElementType::NUMBER, param};
335 }
336 }
337
StringToAniStr(ani_env * env,const std::string & str)338 static ani_string StringToAniStr(ani_env *env, const std::string &str)
339 {
340 ani_string ret;
341 if (ANI_OK != env->String_NewUTF8(str.c_str(), str.size(), &ret)) {
342 RESMGR_HILOGE(RESMGR_ANI_TAG, "Create ani string failed");
343 return nullptr;
344 }
345 return ret;
346 }
347
InitAniParameters(ani_env * env,ani_object args,std::vector<std::tuple<ResourceManager::NapiValueType,std::string>> & jsParams)348 static bool InitAniParameters(ani_env *env, ani_object args,
349 std::vector<std::tuple<ResourceManager::NapiValueType, std::string>> &jsParams)
350 {
351 ani_size size;
352 if (ANI_OK != env->Array_GetLength(static_cast<ani_array>(args), &size)) {
353 RESMGR_HILOGE(RESMGR_ANI_TAG, "Get length failed");
354 return false;
355 }
356
357 if (size <= 0) {
358 return true;
359 }
360
361 for (size_t i = 0; i < size; ++i) {
362 auto param = GetArrayElement(env, args, i);
363 if (param.type == ArrayElement::ElementType::NUMBER) {
364 jsParams.push_back(std::make_tuple(ResourceManager::NapiValueType::NAPI_NUMBER,
365 std::to_string(std::get<double>(param.value))));
366 } else if (param.type == ArrayElement::ElementType::STRING) {
367 jsParams.push_back(std::make_tuple(ResourceManager::NapiValueType::NAPI_STRING,
368 std::get<string>(param.value)));
369 } else {
370 return false;
371 }
372 }
373 return true;
374 }
375
GetFormatStringSyncById(ani_env * env,ani_object object,ani_double resId,ani_object args)376 ani_string ResMgrAddon::GetFormatStringSyncById(ani_env *env, ani_object object, ani_double resId, ani_object args)
377 {
378 auto dataContext = std::make_unique<ResMgrDataContext>();
379 dataContext->addon_ = UnwrapAddon(env, object);
380 dataContext->resId_ = resId;
381 std::shared_ptr<ResourceManager> resMgr = nullptr;
382 uint32_t notUse = 0;
383 bool ret = GetHapResourceManager(dataContext.get(), resMgr, notUse);
384 if (!ret || resMgr == nullptr) {
385 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getStringSyncById");
386 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
387 return nullptr;
388 }
389 if (!InitAniParameters(env, args, dataContext->jsParams_)) {
390 RESMGR_HILOGE(RESMGR_ANI_TAG, "getFormatStringSyncById formatting error");
391 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_ID_FORMAT_ERROR);
392 return nullptr;
393 }
394 RState state = resMgr->GetStringFormatById(resId, dataContext->value_, dataContext->jsParams_);
395 if (state != RState::SUCCESS) {
396 dataContext->SetErrorMsg("getFormatStringSyncById failed state", true);
397 ResourceManagerAniUtils::AniThrow(env, state);
398 return nullptr;
399 }
400 return CreateAniString(env, *dataContext);
401 }
402
GetRawFileContentSync(ani_env * env,ani_object object,ani_string path)403 ani_object ResMgrAddon::GetRawFileContentSync(ani_env* env, ani_object object, ani_string path)
404 {
405 std::unique_ptr<ResMgrDataContext> dataContext = std::make_unique<ResMgrDataContext>();
406 dataContext->path_ = AniStrToString(env, path);
407 dataContext->addon_ = UnwrapAddon(env, object);
408 if (dataContext->addon_ == nullptr || dataContext->addon_->GetResMgr() == nullptr) {
409 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in GetRawFileContentSync.");
410 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_INVALID_INPUT_PARAMETER);
411 return nullptr;
412 }
413 RState state = dataContext->addon_->GetResMgr()->GetRawFileFromHap(dataContext->path_,
414 dataContext->len_, dataContext->mediaData);
415 if (state != RState::SUCCESS) {
416 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get rawfile by path");
417 ResourceManagerAniUtils::AniThrow(env, state);
418 return nullptr;
419 }
420 return CreateAniUint8Array(env, *dataContext);
421 }
422
GetIntPluralStringValueSyncById(ani_env * env,ani_object object,ani_double resId,ani_double num,ani_object args)423 ani_string ResMgrAddon::GetIntPluralStringValueSyncById(ani_env* env, ani_object object,
424 ani_double resId, ani_double num, ani_object args)
425 {
426 std::unique_ptr<ResMgrDataContext> dataContext = std::make_unique<ResMgrDataContext>();
427 dataContext->addon_ = UnwrapAddon(env, object);
428 dataContext->resId_ = resId;
429 double number = num;
430 if (number > INT_MAX) {
431 number = INT_MAX;
432 } else if (number < INT_MIN) {
433 number = INT_MIN;
434 }
435 dataContext->quantity_ = { true, number, 0.0 };
436
437 std::shared_ptr<ResourceManager> resMgr = nullptr;
438 uint32_t notUse = 0;
439 bool ret = GetHapResourceManager(dataContext.get(), resMgr, notUse);
440 if (!ret || resMgr == nullptr) {
441 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getIntPluralStringValueSyncById");
442 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
443 return nullptr;
444 }
445
446 if (!InitAniParameters(env, args, dataContext->jsParams_)) {
447 RESMGR_HILOGE(RESMGR_ANI_TAG, "InitOptionalParameters formatting error");
448 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_ID_FORMAT_ERROR);
449 return nullptr;
450 }
451
452 RState state = resMgr->GetFormatPluralStringById(dataContext->value_, resId, dataContext->quantity_,
453 dataContext->jsParams_);
454 if (state != RState::SUCCESS) {
455 dataContext->SetErrorMsg("Failed to GetFormatPluralStringById state", true, state);
456 ResourceManagerAniUtils::AniThrow(env, state);
457 return nullptr;
458 }
459 return CreateAniString(env, *dataContext);
460 }
461
GetIntPluralStringByNameSync(ani_env * env,ani_object object,ani_string resName,ani_double num,ani_object args)462 ani_string ResMgrAddon::GetIntPluralStringByNameSync(ani_env* env, ani_object object,
463 ani_string resName, ani_double num, ani_object args)
464 {
465 auto dataContext = std::make_unique<ResMgrDataContext>();
466 dataContext->addon_ = UnwrapAddon(env, object);
467 dataContext->resName_ = AniStrToString(env, static_cast<ani_ref>(resName));
468 double number = num;
469 if (number > INT_MAX) {
470 number = INT_MAX;
471 } else if (number < INT_MIN) {
472 number = INT_MIN;
473 }
474 dataContext->quantity_ = { true, number, 0.0 };
475
476 if (!InitAniParameters(env, args, dataContext->jsParams_)) {
477 RESMGR_HILOGE(RESMGR_ANI_TAG, "InitOptionalParameters formatting error");
478 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_ID_FORMAT_ERROR);
479 return nullptr;
480 }
481
482 if (dataContext->addon_ == nullptr || dataContext->addon_->GetResMgr() == nullptr) {
483 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getIntPluralStringByNameSync");
484 ResourceManagerAniUtils::AniThrow(env, NOT_FOUND);
485 return nullptr;
486 }
487
488 RState state = dataContext->addon_->GetResMgr()->GetFormatPluralStringByName(dataContext->value_,
489 dataContext->resName_.c_str(), dataContext->quantity_, dataContext->jsParams_);
490 if (state != RState::SUCCESS) {
491 dataContext->SetErrorMsg("GetFormatPluralStringByName failed state", false);
492 ResourceManagerAniUtils::AniThrow(env, state);
493 return nullptr;
494 }
495 return CreateAniString(env, *dataContext);
496 }
497
GetDoublePluralStringValueSyncById(ani_env * env,ani_object object,ani_double resId,ani_double num,ani_object args)498 ani_string ResMgrAddon::GetDoublePluralStringValueSyncById(ani_env* env, ani_object object,
499 ani_double resId, ani_double num, ani_object args)
500 {
501 std::unique_ptr<ResMgrDataContext> dataContext = std::make_unique<ResMgrDataContext>();
502 dataContext->addon_ = UnwrapAddon(env, object);
503 dataContext->resId_ = resId;
504 dataContext->quantity_ = { false, 0, num };
505
506 std::shared_ptr<ResourceManager> resMgr = nullptr;
507 uint32_t notUse = 0;
508 bool ret = GetHapResourceManager(dataContext.get(), resMgr, notUse);
509 if (!ret || resMgr == nullptr) {
510 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getIntPluralStringValueSyncById");
511 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
512 return nullptr;
513 }
514
515 if (!InitAniParameters(env, args, dataContext->jsParams_)) {
516 RESMGR_HILOGE(RESMGR_ANI_TAG, "InitOptionalParameters formatting error");
517 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_ID_FORMAT_ERROR);
518 return nullptr;
519 }
520
521 RState state = resMgr->GetFormatPluralStringById(dataContext->value_, resId, dataContext->quantity_,
522 dataContext->jsParams_);
523 if (state != RState::SUCCESS) {
524 dataContext->SetErrorMsg("Failed to GetFormatPluralStringById state", true, state);
525 ResourceManagerAniUtils::AniThrow(env, state);
526 return nullptr;
527 }
528 return CreateAniString(env, *dataContext);
529 }
530
GetDoublePluralStringByNameSync(ani_env * env,ani_object object,ani_string resName,ani_double num,ani_object args)531 ani_string ResMgrAddon::GetDoublePluralStringByNameSync(ani_env* env, ani_object object,
532 ani_string resName, ani_double num, ani_object args)
533 {
534 auto dataContext = std::make_unique<ResMgrDataContext>();
535 dataContext->addon_ = UnwrapAddon(env, object);
536 dataContext->resName_ = AniStrToString(env, static_cast<ani_ref>(resName));
537 dataContext->quantity_ = { false, 0, num };
538
539 if (!InitAniParameters(env, args, dataContext->jsParams_)) {
540 RESMGR_HILOGE(RESMGR_ANI_TAG, "InitOptionalParameters formatting error");
541 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_ID_FORMAT_ERROR);
542 return nullptr;
543 }
544
545 if (dataContext->addon_ == nullptr || dataContext->addon_->GetResMgr() == nullptr) {
546 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getDoublePluralStringByNameSync");
547 ResourceManagerAniUtils::AniThrow(env, NOT_FOUND);
548 return nullptr;
549 }
550
551 RState state = dataContext->addon_->GetResMgr()->GetFormatPluralStringByName(dataContext->value_,
552 dataContext->resName_.c_str(), dataContext->quantity_, dataContext->jsParams_);
553 if (state != RState::SUCCESS) {
554 dataContext->SetErrorMsg("GetFormatPluralStringByName failed state", false);
555 ResourceManagerAniUtils::AniThrow(env, state);
556 return nullptr;
557 }
558 return CreateAniString(env, *dataContext);
559 }
560
BindContext(ani_env * env)561 ani_status ResMgrAddon::BindContext(ani_env* env)
562 {
563 ani_class cls;
564 if (ANI_OK != env->FindClass(RESOURCE_MANAGER_INNER_SIGN, &cls)) {
565 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find class '%{public}s' failed", RESOURCE_MANAGER_INNER_SIGN);
566 return (ani_status)ANI_ERROR;
567 }
568
569 if (ANI_OK != env->Class_BindNativeMethods(cls, methods.data(), methods.size())) {
570 RESMGR_HILOGE(RESMGR_ANI_TAG, "Cannot bind native methods to '%{public}s'", RESOURCE_MANAGER_INNER_SIGN);
571 return (ani_status)ANI_ERROR;
572 };
573
574 ani_namespace ns;
575 if (ANI_OK != env->FindNamespace(NAMESPACE_SIGN, &ns)) {
576 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find namespace '%{public}s' failed", NAMESPACE_SIGN);
577 return (ani_status)ANI_ERROR;
578 }
579
580 std::array nsMethods = {
581 ani_native_function { "getSysResourceManager", nullptr, reinterpret_cast<void*>(GetSysResourceManager) },
582 };
583
584 if (ANI_OK != env->Namespace_BindNativeFunctions(ns, nsMethods.data(), nsMethods.size())) {
585 RESMGR_HILOGE(RESMGR_ANI_TAG, "Cannot bind native methods to '%{public}s'", NAMESPACE_SIGN);
586 return (ani_status)ANI_ERROR;
587 };
588 return ANI_OK;
589 }
590
591
GetStringByNameSync(ani_env * env,ani_object object,ani_string resName)592 ani_string ResMgrAddon::GetStringByNameSync(ani_env* env, ani_object object, ani_string resName)
593 {
594 auto dataContext = std::make_unique<ResMgrDataContext>();
595 dataContext->addon_ = UnwrapAddon(env, object);
596 dataContext->resName_ = AniStrToString(env, static_cast<ani_ref>(resName));
597
598 std::shared_ptr<ResourceManager> resMgr = nullptr;
599 uint32_t resId = 0;
600 bool ret = GetHapResourceManager(dataContext.get(), resMgr, resId);
601 if (!ret || resMgr == nullptr) {
602 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getStringByNameSync");
603 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
604 return nullptr;
605 }
606
607 RState state = resMgr->GetStringFormatByName(dataContext->resName_.c_str(),
608 dataContext->value_, dataContext->jsParams_);
609 if (state != RState::SUCCESS) {
610 dataContext->SetErrorMsg("GetStringByNameSync failed state", false);
611 ResourceManagerAniUtils::AniThrow(env, state);
612 return nullptr;
613 }
614 return CreateAniString(env, *dataContext);
615 }
616
GetFormatStringByNameSync(ani_env * env,ani_object object,ani_string resName,ani_object args)617 ani_string ResMgrAddon::GetFormatStringByNameSync(ani_env *env, ani_object object, ani_string resName, ani_object args)
618 {
619 auto dataContext = std::make_unique<ResMgrDataContext>();
620 dataContext->addon_ = UnwrapAddon(env, object);
621 dataContext->resName_ = AniStrToString(env, static_cast<ani_ref>(resName));
622
623 std::shared_ptr<ResourceManager> resMgr = nullptr;
624 uint32_t resId = 0;
625 bool ret = GetHapResourceManager(dataContext.get(), resMgr, resId);
626 if (!ret || resMgr == nullptr) {
627 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getFormatStringByNameSync");
628 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
629 return nullptr;
630 }
631
632 if (!InitAniParameters(env, args, dataContext->jsParams_)) {
633 RESMGR_HILOGE(RESMGR_ANI_TAG, "getFormatStringByNameSync formatting error");
634 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NAME_FORMAT_ERROR);
635 return nullptr;
636 }
637
638 RState state = resMgr->GetStringFormatByName(dataContext->resName_.c_str(),
639 dataContext->value_, dataContext->jsParams_);
640 if (state != RState::SUCCESS) {
641 dataContext->SetErrorMsg("GetStringByNameSync failed state", false);
642 ResourceManagerAniUtils::AniThrow(env, state);
643 return nullptr;
644 }
645 return CreateAniString(env, *dataContext);
646 }
647
GetBooleanById(ani_env * env,ani_object object,ani_double resId)648 ani_boolean ResMgrAddon::GetBooleanById(ani_env* env, ani_object object, ani_double resId)
649 {
650 std::unique_ptr<ResMgrDataContext> dataContext = std::make_unique<ResMgrDataContext>();
651 dataContext->addon_ = UnwrapAddon(env, object);
652 dataContext->resId_ = resId;
653
654 std::shared_ptr<ResourceManager> resMgr = nullptr;
655 uint32_t notUse = 0;
656 bool ret = GetHapResourceManager(dataContext.get(), resMgr, notUse);
657 if (!ret || resMgr == nullptr) {
658 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getBooleanById");
659 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
660 return false;
661 }
662
663 RState state = resMgr->GetBooleanById(resId, dataContext->bValue_);
664 if (state != RState::SUCCESS) {
665 dataContext->SetErrorMsg("Failed to GetBoolean state", true);
666 ResourceManagerAniUtils::AniThrow(env, state);
667 return false;
668 }
669 return dataContext->bValue_;
670 }
671
GetBooleanByName(ani_env * env,ani_object object,ani_string resName)672 ani_boolean ResMgrAddon::GetBooleanByName(ani_env* env, ani_object object, ani_string resName)
673 {
674 auto dataContext = std::make_unique<ResMgrDataContext>();
675 dataContext->addon_ = UnwrapAddon(env, object);
676 dataContext->resName_ = AniStrToString(env, static_cast<ani_ref>(resName));
677
678 std::shared_ptr<ResourceManager> resMgr = nullptr;
679 uint32_t resId = 0;
680 bool ret = GetHapResourceManager(dataContext.get(), resMgr, resId);
681 if (!ret || resMgr == nullptr) {
682 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getBooleanByName");
683 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
684 return false;
685 }
686
687 RState state = resMgr->GetBooleanByName(dataContext->resName_.c_str(), dataContext->bValue_);
688 if (state != RState::SUCCESS) {
689 dataContext->SetErrorMsg("GetBooleanByName failed state", false);
690 ResourceManagerAniUtils::AniThrow(env, state);
691 return false;
692 }
693 return dataContext->bValue_;
694 }
695
GetNumberById(ani_env * env,ani_object object,ani_double resId)696 ani_double ResMgrAddon::GetNumberById(ani_env* env, ani_object object, ani_double resId)
697 {
698 auto dataContext = std::make_unique<ResMgrDataContext>();
699 dataContext->addon_ = UnwrapAddon(env, object);
700 dataContext->resId_ = resId;
701
702 std::shared_ptr<ResourceManager> resMgr = nullptr;
703 uint32_t notUse = 0;
704 bool ret = GetHapResourceManager(dataContext.get(), resMgr, notUse);
705 if (!ret || resMgr == nullptr) {
706 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getNumberById");
707 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
708 return ABNORMAL_NUMBER_RETURN_VALUE;
709 }
710
711 RState state = resMgr->GetIntegerById(resId, dataContext->iValue_);
712 if (state != RState::SUCCESS) {
713 state = resMgr->GetFloatById(resId, dataContext->fValue_);
714 if (state != RState::SUCCESS) {
715 dataContext->SetErrorMsg("Failed to process string in getNumberById", true);
716 ResourceManagerAniUtils::AniThrow(env, state);
717 return ABNORMAL_NUMBER_RETURN_VALUE;
718 }
719 }
720
721 ani_double aniValue;
722 if (dataContext->iValue_) {
723 aniValue = dataContext->iValue_;
724 } else {
725 aniValue = dataContext->fValue_;
726 }
727 return aniValue;
728 }
729
GetNumberByName(ani_env * env,ani_object object,ani_string resName)730 ani_double ResMgrAddon::GetNumberByName(ani_env* env, ani_object object, ani_string resName)
731 {
732 auto dataContext = std::make_unique<ResMgrDataContext>();
733 dataContext->addon_ = UnwrapAddon(env, object);
734 dataContext->resName_ = AniStrToString(env, static_cast<ani_ref>(resName));
735
736 if (dataContext->addon_ == nullptr) {
737 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get addon in getNumberByName");
738 ResourceManagerAniUtils::AniThrow(env, NOT_FOUND);
739 return ABNORMAL_NUMBER_RETURN_VALUE;
740 }
741
742 auto resMgr = dataContext->addon_->GetResMgr();
743 if (resMgr == nullptr) {
744 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getNumberByName");
745 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
746 return ABNORMAL_NUMBER_RETURN_VALUE;
747 }
748
749 RState state = resMgr->GetIntegerByName(dataContext->resName_.c_str(), dataContext->iValue_);
750 if (state != RState::SUCCESS) {
751 state = resMgr->GetFloatByName(dataContext->resName_.c_str(), dataContext->fValue_);
752 if (state != RState::SUCCESS) {
753 dataContext->SetErrorMsg("Failed to process number in getNumberByName", false);
754 ResourceManagerAniUtils::AniThrow(env, state);
755 return ABNORMAL_NUMBER_RETURN_VALUE;
756 }
757 }
758
759 ani_double aniValue;
760 if (dataContext->iValue_) {
761 aniValue = dataContext->iValue_;
762 } else {
763 aniValue = dataContext->fValue_;
764 }
765 return aniValue;
766 }
767
768
GetColorSyncById(ani_env * env,ani_object object,ani_double resId)769 ani_double ResMgrAddon::GetColorSyncById(ani_env* env, ani_object object, ani_double resId)
770 {
771 auto dataContext = std::make_unique<ResMgrDataContext>();
772 dataContext->addon_ = UnwrapAddon(env, object);
773 dataContext->resId_ = resId;
774
775 std::shared_ptr<ResourceManager> resMgr = nullptr;
776 uint32_t notUse = 0;
777 bool ret = GetHapResourceManager(dataContext.get(), resMgr, notUse);
778 if (!ret || resMgr == nullptr) {
779 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getColorSyncById");
780 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
781 return ABNORMAL_NUMBER_RETURN_VALUE;
782 }
783
784 RState state = resMgr->GetColorById(resId, dataContext->colorValue_);
785 if (state != RState::SUCCESS) {
786 dataContext->SetErrorMsg("getColorSyncById failed state", true);
787 ResourceManagerAniUtils::AniThrow(env, state);
788 return ABNORMAL_NUMBER_RETURN_VALUE;
789 }
790 return dataContext->colorValue_;
791 }
792
GetColorByNameSync(ani_env * env,ani_object object,ani_string resName)793 ani_double ResMgrAddon::GetColorByNameSync(ani_env* env, ani_object object, ani_string resName)
794 {
795 auto dataContext = std::make_unique<ResMgrDataContext>();
796 dataContext->addon_ = UnwrapAddon(env, object);
797 dataContext->resName_ = AniStrToString(env, static_cast<ani_ref>(resName));
798
799 std::shared_ptr<ResourceManager> resMgr = nullptr;
800 uint32_t resId = 0;
801 bool ret = GetHapResourceManager(dataContext.get(), resMgr, resId);
802 if (!ret || resMgr == nullptr) {
803 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getColorByNameSync");
804 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
805 return ABNORMAL_NUMBER_RETURN_VALUE;
806 }
807
808 RState state = resMgr->GetColorByName(dataContext->resName_.c_str(), dataContext->colorValue_);
809 if (state != RState::SUCCESS) {
810 dataContext->SetErrorMsg("Failed to process number in getColorByNameSync", false);
811 ResourceManagerAniUtils::AniThrow(env, state);
812 return ABNORMAL_NUMBER_RETURN_VALUE;
813 }
814 return dataContext->colorValue_;
815 }
816
817
AddResource(ani_env * env,ani_object object,ani_string path)818 void ResMgrAddon::AddResource(ani_env* env, ani_object object, ani_string path)
819 {
820 auto dataContext = std::make_unique<ResMgrDataContext>();
821 dataContext->path_ = AniStrToString(env, path);
822
823 auto resMgr = UnwrapAddon(env, object);
824 if (resMgr == nullptr || resMgr->GetResMgr() == nullptr) {
825 RESMGR_HILOGE(RESMGR_JS_TAG, "resMgr is null, add overlay failed.");
826 return;
827 }
828
829 if (!resMgr->GetResMgr()->AddAppOverlay(dataContext->path_)) {
830 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to add overlay path.");
831 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_OVERLAY_RES_PATH_INVALID);
832 return;
833 }
834 }
835
RemoveResource(ani_env * env,ani_object object,ani_string path)836 void ResMgrAddon::RemoveResource(ani_env* env, ani_object object, ani_string path)
837 {
838 auto dataContext = std::make_unique<ResMgrDataContext>();
839 dataContext->path_ = AniStrToString(env, path);
840
841 auto resMgr = UnwrapAddon(env, object);
842 if (resMgr == nullptr || resMgr->GetResMgr() == nullptr) {
843 RESMGR_HILOGE(RESMGR_JS_TAG, "resMgr is null, overlay path.");
844 return;
845 }
846
847 if (!resMgr->GetResMgr()->RemoveAppOverlay(dataContext->path_)) {
848 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to remove overlay path.");
849 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_OVERLAY_RES_PATH_INVALID);
850 return;
851 }
852 }
853
GetRawFdSync(ani_env * env,ani_object object,ani_string path)854 ani_object ResMgrAddon::GetRawFdSync(ani_env* env, ani_object object, ani_string path)
855 {
856 auto dataContext = std::make_unique<ResMgrDataContext>();
857 dataContext->path_ = AniStrToString(env, path);
858 dataContext->addon_ = UnwrapAddon(env, object);
859
860 if (dataContext->addon_ == nullptr || dataContext->addon_->GetResMgr() == nullptr) {
861 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get addon in getRawFdSync");
862 ResourceManagerAniUtils::AniThrow(env, NOT_FOUND);
863 return nullptr;
864 }
865
866 RState state = dataContext->addon_->GetResMgr()->GetRawFileDescriptorFromHap(dataContext->path_,
867 dataContext->descriptor_);
868 if (state != RState::SUCCESS) {
869 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get rawfd.");
870 ResourceManagerAniUtils::AniThrow(env, state);
871 return nullptr;
872 }
873
874 ani_class cls;
875 auto ret = env->FindClass(RAW_FILE_DESCRIPTOR_SIGN, &cls);
876 if (ANI_OK != ret) {
877 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find class '%{public}s' failed, error code: %{public}d",
878 RAW_FILE_DESCRIPTOR_SIGN, ret);
879 return nullptr;
880 }
881
882 ani_method ctor;
883 if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor)) {
884 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find method '<ctor>' failed");
885 return nullptr;
886 }
887
888 ani_object obj;
889 if (ANI_OK != env->Object_New(cls, ctor, &obj)) {
890 RESMGR_HILOGE(RESMGR_ANI_TAG, "New object '%{public}s' failed", RAW_FILE_DESCRIPTOR_SIGN);
891 return nullptr;
892 }
893
894 if (ANI_OK != env->Object_SetPropertyByName_Double(obj, "fd", dataContext->descriptor_.fd)) {
895 RESMGR_HILOGE(RESMGR_ANI_TAG, "Set property 'fd' failed");
896 }
897
898 if (ANI_OK != env->Object_SetPropertyByName_Double(obj, "offset", dataContext->descriptor_.offset)) {
899 RESMGR_HILOGE(RESMGR_ANI_TAG, "Set property 'offset' failed");
900 }
901
902 if (ANI_OK != env->Object_SetPropertyByName_Double(obj, "length", dataContext->descriptor_.length)) {
903 RESMGR_HILOGE(RESMGR_ANI_TAG, "Set property 'length' failed");
904 }
905 return obj;
906 }
907
CloseRawFdSync(ani_env * env,ani_object object,ani_string path)908 void ResMgrAddon::CloseRawFdSync(ani_env* env, ani_object object, ani_string path)
909 {
910 auto dataContext = std::make_unique<ResMgrDataContext>();
911 dataContext->path_ = AniStrToString(env, path);
912 dataContext->addon_ = UnwrapAddon(env, object);
913
914 if (dataContext->addon_ == nullptr || dataContext->addon_->GetResMgr() == nullptr) {
915 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in closeRawFdSync");
916 ResourceManagerAniUtils::AniThrow(env, NOT_FOUND);
917 return;
918 }
919
920 RState state = dataContext->addon_->GetResMgr()->CloseRawFileDescriptor(dataContext->path_);
921 if (state != RState::SUCCESS) {
922 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to close rawfd.");
923 ResourceManagerAniUtils::AniThrow(env, state);
924 return;
925 }
926 }
927
CreateAniArray(ani_env * env,const std::vector<std::string> strs)928 static ani_object CreateAniArray(ani_env *env, const std::vector<std::string> strs)
929 {
930 ani_class cls;
931 if (ANI_OK != env->FindClass(ANI_ARRAY_SIGN, &cls)) {
932 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find class '%{public}s' failed", ANI_ARRAY_SIGN);
933 return nullptr;
934 }
935
936 ani_method ctor;
937 if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", "i:", &ctor)) {
938 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find method '<ctor>' failed");
939 return nullptr;
940 }
941
942 ani_object ret;
943 if (ANI_OK != env->Object_New(cls, ctor, &ret, strs.size())) {
944 RESMGR_HILOGE(RESMGR_ANI_TAG, "New object '%{public}s' failed", ANI_ARRAY_SIGN);
945 return nullptr;
946 }
947
948 ani_method set;
949 if (ANI_OK != env->Class_FindMethod(cls, "$_set", "iC{std.core.Object}:", &set)) {
950 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find method '$_set' failed");
951 return ret;
952 }
953
954 for (size_t i = 0; i < strs.size(); i++) {
955 if (ANI_OK != env->Object_CallMethod_Void(ret, set, i, StringToAniStr(env, strs[i]))) {
956 RESMGR_HILOGE(RESMGR_ANI_TAG, "Call method '$_set' failed");
957 return ret;
958 }
959 }
960 return ret;
961 }
962
GetRawFileListSync(ani_env * env,ani_object object,ani_string path)963 ani_object ResMgrAddon::GetRawFileListSync(ani_env* env, ani_object object, ani_string path)
964 {
965 std::unique_ptr<ResMgrDataContext> dataContext = std::make_unique<ResMgrDataContext>();
966 dataContext->path_ = AniStrToString(env, path);
967 dataContext->addon_ = UnwrapAddon(env, object);
968
969 if (dataContext->addon_ == nullptr || dataContext->addon_->GetResMgr() == nullptr) {
970 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getRawFileListSync");
971 ResourceManagerAniUtils::AniThrow(env, NOT_FOUND);
972 return nullptr;
973 }
974
975 RState state = dataContext->addon_->GetResMgr()->GetRawFileList(dataContext->path_.c_str(),
976 dataContext->arrayValue_);
977 if (state != RState::SUCCESS || dataContext->arrayValue_.empty()) {
978 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get rawfile list.");
979 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_PATH_INVALID);
980 return nullptr;
981 }
982
983 return CreateAniArray(env, dataContext->arrayValue_);
984 }
985
GetMediaContentSyncById(ani_env * env,ani_object object,ani_double resId,ani_object density)986 ani_object ResMgrAddon::GetMediaContentSyncById(ani_env* env, ani_object object,
987 ani_double resId, ani_object density)
988 {
989 std::unique_ptr<ResMgrDataContext> dataContext = std::make_unique<ResMgrDataContext>();
990 dataContext->addon_ = UnwrapAddon(env, object);
991 dataContext->resId_ = resId;
992
993 ani_boolean isUndefined;
994 env->Reference_IsUndefined(density, &isUndefined);
995 if (!isUndefined) {
996 ani_double densityInner;
997 env->Object_CallMethodByName_Double(density, "unboxed", ":D", &densityInner);
998 dataContext->density_ = densityInner;
999 }
1000
1001 std::shared_ptr<ResourceManager> resMgr = nullptr;
1002 uint32_t notUse = 0;
1003 bool ret = GetHapResourceManager(dataContext.get(), resMgr, notUse);
1004 if (!ret || resMgr == nullptr) {
1005 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getMediaContentSyncById");
1006 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
1007 return nullptr;
1008 }
1009
1010 RState state = resMgr->GetMediaDataById(resId, dataContext->len_, dataContext->mediaData, dataContext->density_);
1011 if (state != RState::SUCCESS) {
1012 dataContext->SetErrorMsg("Failed to GetMediaContentSync state", true);
1013 ResourceManagerAniUtils::AniThrow(env, state);
1014 return nullptr;
1015 }
1016 return CreateAniUint8Array(env, *dataContext);
1017 }
1018
GetMediaContentBase64SyncById(ani_env * env,ani_object object,ani_double resId,ani_object density)1019 ani_string ResMgrAddon::GetMediaContentBase64SyncById(ani_env* env, ani_object object,
1020 ani_double resId, ani_object density)
1021 {
1022 std::unique_ptr<ResMgrDataContext> dataContext = std::make_unique<ResMgrDataContext>();
1023 dataContext->addon_ = UnwrapAddon(env, object);
1024 dataContext->resId_ = resId;
1025
1026 ani_boolean isUndefined;
1027 env->Reference_IsUndefined(density, &isUndefined);
1028 if (!isUndefined) {
1029 ani_double densityInner;
1030 env->Object_CallMethodByName_Double(density, "unboxed", ":D", &densityInner);
1031 dataContext->density_ = densityInner;
1032 }
1033
1034 std::shared_ptr<ResourceManager> resMgr = nullptr;
1035 uint32_t notUse = 0;
1036 bool ret = GetHapResourceManager(dataContext.get(), resMgr, notUse);
1037 if (!ret || resMgr == nullptr) {
1038 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getMediaContentBase64SyncById");
1039 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
1040 return nullptr;
1041 }
1042
1043 RState state = resMgr->GetMediaBase64DataById(resId, dataContext->value_, dataContext->density_);
1044 if (state != RState::SUCCESS) {
1045 dataContext->SetErrorMsg("Failed to GetMediaContentBase64Sync state", true);
1046 ResourceManagerAniUtils::AniThrow(env, state);
1047 return nullptr;
1048 }
1049 return CreateAniString(env, *dataContext);
1050 }
1051
GetStringArrayValueSyncById(ani_env * env,ani_object object,ani_double resId)1052 ani_object ResMgrAddon::GetStringArrayValueSyncById(ani_env* env, ani_object object, ani_double resId)
1053 {
1054 std::unique_ptr<ResMgrDataContext> dataContext = std::make_unique<ResMgrDataContext>();
1055 dataContext->addon_ = UnwrapAddon(env, object);
1056 dataContext->resId_ = resId;
1057
1058 std::shared_ptr<ResourceManager> resMgr = nullptr;
1059 uint32_t notUse = 0;
1060 bool ret = GetHapResourceManager(dataContext.get(), resMgr, notUse);
1061 if (!ret || resMgr == nullptr) {
1062 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getStringArrayValueSyncById");
1063 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
1064 return nullptr;
1065 }
1066
1067 RState state = resMgr->GetStringArrayById(resId, dataContext->arrayValue_);
1068 if (state != RState::SUCCESS) {
1069 dataContext->SetErrorMsg("Failed to GetStringArrayValueSync state", true);
1070 ResourceManagerAniUtils::AniThrow(env, state);
1071 return nullptr;
1072 }
1073 return CreateAniArray(env, dataContext->arrayValue_);
1074 }
1075
GetMediaByNameSync(ani_env * env,ani_object object,ani_string resName,ani_object density)1076 ani_object ResMgrAddon::GetMediaByNameSync(ani_env* env, ani_object object, ani_string resName, ani_object density)
1077 {
1078 std::unique_ptr<ResMgrDataContext> dataContext = std::make_unique<ResMgrDataContext>();
1079 dataContext->addon_ = UnwrapAddon(env, object);
1080 dataContext->resName_ = AniStrToString(env, static_cast<ani_ref>(resName));
1081
1082 ani_boolean isUndefined;
1083 env->Reference_IsUndefined(density, &isUndefined);
1084 if (!isUndefined) {
1085 ani_double densityInner;
1086 env->Object_CallMethodByName_Double(density, "unboxed", ":D", &densityInner);
1087 dataContext->density_ = densityInner;
1088 }
1089
1090 std::shared_ptr<ResourceManager> resMgr = nullptr;
1091 uint32_t resId = 0;
1092 bool ret = GetHapResourceManager(dataContext.get(), resMgr, resId);
1093 if (!ret || resMgr == nullptr) {
1094 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getMediaByNameSync");
1095 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
1096 return nullptr;
1097 }
1098
1099 RState state = resMgr->GetMediaDataByName(dataContext->resName_.c_str(),
1100 dataContext->len_, dataContext->mediaData, dataContext->density_);
1101 if (state != RState::SUCCESS) {
1102 dataContext->SetErrorMsg("GetMediaByNameSync failed state", false);
1103 ResourceManagerAniUtils::AniThrow(env, state);
1104 return nullptr;
1105 }
1106 return CreateAniUint8Array(env, *dataContext);
1107 }
1108
GetMediaBase64ByNameSync(ani_env * env,ani_object object,ani_string resName,ani_object density)1109 ani_string ResMgrAddon::GetMediaBase64ByNameSync(ani_env* env, ani_object object,
1110 ani_string resName, ani_object density)
1111 {
1112 std::unique_ptr<ResMgrDataContext> dataContext = std::make_unique<ResMgrDataContext>();
1113 dataContext->addon_ = UnwrapAddon(env, object);
1114 dataContext->resName_ = AniStrToString(env, static_cast<ani_ref>(resName));
1115
1116 ani_boolean isUndefined;
1117 env->Reference_IsUndefined(density, &isUndefined);
1118 if (!isUndefined) {
1119 ani_double densityInner;
1120 env->Object_CallMethodByName_Double(density, "unboxed", ":D", &densityInner);
1121 dataContext->density_ = densityInner;
1122 }
1123
1124 std::shared_ptr<ResourceManager> resMgr = nullptr;
1125 uint32_t resId = 0;
1126 bool ret = GetHapResourceManager(dataContext.get(), resMgr, resId);
1127 if (!ret || resMgr == nullptr) {
1128 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getMediaBase64ByNameSync");
1129 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
1130 return nullptr;
1131 }
1132
1133 RState state = resMgr->GetMediaBase64DataByName(dataContext->resName_.c_str(),
1134 dataContext->value_, dataContext->density_);
1135 if (state != RState::SUCCESS) {
1136 dataContext->SetErrorMsg("Failed to get media data in GetMediaBase64ByNameSync", false);
1137 ResourceManagerAniUtils::AniThrow(env, state);
1138 return nullptr;
1139 }
1140 return CreateAniString(env, *dataContext);
1141 }
1142
GetStringArrayByNameSync(ani_env * env,ani_object object,ani_string resName)1143 ani_object ResMgrAddon::GetStringArrayByNameSync(ani_env* env, ani_object object, ani_string resName)
1144 {
1145 std::unique_ptr<ResMgrDataContext> dataContext = std::make_unique<ResMgrDataContext>();
1146 dataContext->addon_ = UnwrapAddon(env, object);
1147 dataContext->resName_ = AniStrToString(env, static_cast<ani_ref>(resName));
1148
1149 std::shared_ptr<ResourceManager> resMgr = nullptr;
1150 uint32_t resId = 0;
1151 bool ret = GetHapResourceManager(dataContext.get(), resMgr, resId);
1152 if (!ret || resMgr == nullptr) {
1153 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getStringArrayByNameSync");
1154 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
1155 return nullptr;
1156 }
1157
1158 RState state = resMgr->GetStringArrayByName(dataContext->resName_.c_str(), dataContext->arrayValue_);
1159 if (state != RState::SUCCESS) {
1160 dataContext->SetErrorMsg("GetStringArrayByNameSync failed state", false);
1161 ResourceManagerAniUtils::AniThrow(env, state);
1162 return nullptr;
1163 }
1164 return CreateAniArray(env, dataContext->arrayValue_);
1165 }
1166
GetScreenDensityIndex(ScreenDensity value)1167 static int GetScreenDensityIndex(ScreenDensity value)
1168 {
1169 switch (value) {
1170 case ScreenDensity::SCREEN_DENSITY_SDPI: return static_cast<int>(ScreenDensityIndex::SCREEN_DENSITY_ONE);
1171 case ScreenDensity::SCREEN_DENSITY_MDPI: return static_cast<int>(ScreenDensityIndex::SCREEN_DENSITY_TWO);
1172 case ScreenDensity::SCREEN_DENSITY_LDPI: return static_cast<int>(ScreenDensityIndex::SCREEN_DENSITY_THREE);
1173 case ScreenDensity::SCREEN_DENSITY_XLDPI: return static_cast<int>(ScreenDensityIndex::SCREEN_DENSITY_FOUR);
1174 case ScreenDensity::SCREEN_DENSITY_XXLDPI: return static_cast<int>(ScreenDensityIndex::SCREEN_DENSITY_FIVE);
1175 case ScreenDensity::SCREEN_DENSITY_XXXLDPI: return static_cast<int>(ScreenDensityIndex::SCREEN_DENSITY_SIX);
1176 default: return -1;
1177 }
1178 }
1179
SetEnumMember(ani_env * env,ani_object obj,const char * memberName,const char * enumName,const int index)1180 static void SetEnumMember(ani_env *env, ani_object obj, const char* memberName, const char* enumName, const int index)
1181 {
1182 int realIndex = index;
1183 if (realIndex < 0) {
1184 RESMGR_HILOGW(RESMGR_TAG, "SetEnumMember %{public}s: invalid index %{public}d, reset index to 0.",
1185 memberName, index);
1186 realIndex = 0;
1187 }
1188
1189 ani_enum aniEnum;
1190 if (ANI_OK != env->FindEnum(enumName, &aniEnum)) {
1191 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find enum '%{public}s' failed", enumName);
1192 return;
1193 }
1194
1195 ani_enum_item enumItem;
1196 if (ANI_OK != env->Enum_GetEnumItemByIndex(aniEnum, realIndex, &enumItem)) {
1197 RESMGR_HILOGE(RESMGR_ANI_TAG, "Get enumItem '%{public}s' failed", enumName);
1198 return;
1199 }
1200
1201 if (ANI_OK != env->Object_SetPropertyByName_Ref(obj, memberName, enumItem)) {
1202 RESMGR_HILOGE(RESMGR_ANI_TAG, "Set property '%{public}s' failed", enumName);
1203 return;
1204 }
1205 }
1206
GetLocale(std::unique_ptr<ResConfig> & cfg)1207 static std::string GetLocale(std::unique_ptr<ResConfig> &cfg)
1208 {
1209 std::string result;
1210 #ifdef SUPPORT_GRAPHICS
1211 const icu::Locale *localeInfo = cfg->GetLocaleInfo();
1212 if (localeInfo == nullptr) {
1213 return result;
1214 }
1215
1216 const char *lang = localeInfo->getLanguage();
1217 if (lang == nullptr) {
1218 return result;
1219 }
1220 result = lang;
1221
1222 const char *script = localeInfo->getScript();
1223 if (script != nullptr) {
1224 result += std::string("_") + script;
1225 }
1226
1227 const char *region = localeInfo->getCountry();
1228 if (region != nullptr) {
1229 result += std::string("_") + region;
1230 }
1231 #endif
1232 return result;
1233 }
1234
CreateConfig(ani_env * env,std::unique_ptr<ResConfig> & cfg)1235 static ani_object CreateConfig(ani_env* env, std::unique_ptr<ResConfig> &cfg)
1236 {
1237 ani_class cls;
1238 if (ANI_OK != env->FindClass(CONFIGURATION_SIGN, &cls)) {
1239 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find class '%{public}s' failed", CONFIGURATION_SIGN);
1240 return nullptr;
1241 }
1242
1243 ani_method ctor;
1244 if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor)) {
1245 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find method '<ctor>' failed");
1246 return nullptr;
1247 }
1248
1249 ani_object obj;
1250 if (ANI_OK != env->Object_New(cls, ctor, &obj)) {
1251 RESMGR_HILOGE(RESMGR_ANI_TAG, "New object '%{public}s' failed", CONFIGURATION_SIGN);
1252 return nullptr;
1253 }
1254
1255 SetEnumMember(env, obj, "direction", DIRECTION_SIGN, static_cast<int>(cfg->GetDirection()));
1256 SetEnumMember(env, obj, "deviceType", DEVICE_TYPE_SIGN, static_cast<int>(cfg->GetDeviceType()));
1257 SetEnumMember(env, obj, "screenDensity", SCREEN_DENSITY_SIGN, GetScreenDensityIndex(cfg->GetScreenDensityDpi()));
1258 SetEnumMember(env, obj, "colorMode", COLOR_MODE_SIGN, static_cast<int>(cfg->GetColorMode()));
1259
1260 if (ANI_OK != env->Object_SetPropertyByName_Double(obj, "mcc", static_cast<int>(cfg->GetMcc()))) {
1261 RESMGR_HILOGE(RESMGR_ANI_TAG, "Set property 'mcc' failed");
1262 return obj;
1263 }
1264
1265 if (ANI_OK != env->Object_SetPropertyByName_Double(obj, "mnc", static_cast<int>(cfg->GetMnc()))) {
1266 RESMGR_HILOGE(RESMGR_ANI_TAG, "Set property 'mnc' failed");
1267 return obj;
1268 }
1269
1270 std::string value = GetLocale(cfg);
1271 if (ANI_OK != env->Object_SetPropertyByName_Ref(obj, "locale", StringToAniStr(env, value))) {
1272 RESMGR_HILOGE(RESMGR_ANI_TAG, "Set property 'locale' failed");
1273 return obj;
1274 }
1275 return obj;
1276 }
1277
GetConfigurationSync(ani_env * env,ani_object object)1278 ani_object ResMgrAddon::GetConfigurationSync(ani_env* env, ani_object object)
1279 {
1280 auto dataContext = std::make_unique<ResMgrDataContext>();
1281 dataContext->addon_ = UnwrapAddon(env, object);
1282 if (dataContext->addon_ == nullptr || dataContext->addon_->GetResMgr() == nullptr) {
1283 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in GetConfigurationSync");
1284 return nullptr;
1285 }
1286
1287 std::unique_ptr<ResConfig> cfg(CreateResConfig());
1288 if (!cfg) {
1289 dataContext->SetErrorMsg("Failed to create ResConfig object.");
1290 return nullptr;
1291 }
1292 dataContext->addon_->GetResMgr()->GetResConfig(*cfg);
1293 return CreateConfig(env, cfg);
1294 }
1295
GetDeviceCapabilitySync(ani_env * env,ani_object object)1296 ani_object ResMgrAddon::GetDeviceCapabilitySync(ani_env* env, ani_object object)
1297 {
1298 auto dataContext = std::make_unique<ResMgrDataContext>();
1299 dataContext->addon_ = UnwrapAddon(env, object);
1300 if (dataContext->addon_ == nullptr || dataContext->addon_->GetResMgr() == nullptr) {
1301 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in GetConfigurationSync");
1302 return nullptr;
1303 }
1304
1305 std::unique_ptr<ResConfig> cfg(CreateResConfig());
1306 if (!cfg) {
1307 dataContext->SetErrorMsg("Failed to create ResConfig object.");
1308 return nullptr;
1309 }
1310 dataContext->addon_->GetResMgr()->GetResConfig(*cfg);
1311
1312 ani_class cls;
1313 if (ANI_OK != env->FindClass(DEVICE_CAPABILITY_SIGN, &cls)) {
1314 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find class '%{public}s' failed", DEVICE_CAPABILITY_SIGN);
1315 return nullptr;
1316 }
1317
1318 ani_method ctor;
1319 if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor)) {
1320 RESMGR_HILOGE(RESMGR_ANI_TAG, "Find method '<ctor>' failed");
1321 return nullptr;
1322 }
1323
1324 ani_object obj;
1325 if (ANI_OK != env->Object_New(cls, ctor, &obj)) {
1326 RESMGR_HILOGE(RESMGR_ANI_TAG, "New object '%{public}s' failed", DEVICE_CAPABILITY_SIGN);
1327 return nullptr;
1328 }
1329
1330 SetEnumMember(env, obj, "screenDensity", SCREEN_DENSITY_SIGN, GetScreenDensityIndex(cfg->GetScreenDensityDpi()));
1331 SetEnumMember(env, obj, "deviceType", DEVICE_TYPE_SIGN, static_cast<int>(cfg->GetDeviceType()));
1332 return obj;
1333 }
1334
GetLocales(ani_env * env,ani_object object,ani_object includeSystem)1335 ani_object ResMgrAddon::GetLocales(ani_env* env, ani_object object, ani_object includeSystem)
1336 {
1337 auto dataContext = std::make_unique<ResMgrDataContext>();
1338 dataContext->addon_ = UnwrapAddon(env, object);
1339 if (dataContext->addon_ == nullptr || dataContext->addon_->GetResMgr() == nullptr) {
1340 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in GetConfigurationSync");
1341 return nullptr;
1342 }
1343
1344 ani_boolean isUndefined;
1345 env->Reference_IsUndefined(includeSystem, &isUndefined);
1346 if (!isUndefined) {
1347 ani_boolean includeSys;
1348 env->Object_CallMethodByName_Boolean(includeSystem, "unboxed", ":Z", &includeSys);
1349 dataContext->bValue_ = includeSys;
1350 }
1351
1352 dataContext->addon_->GetResMgr()->GetLocales(dataContext->arrayValue_, dataContext->bValue_);
1353 return CreateAniArray(env, dataContext->arrayValue_);
1354 }
1355
GetSymbolById(ani_env * env,ani_object object,ani_double resId)1356 ani_double ResMgrAddon::GetSymbolById(ani_env* env, ani_object object, ani_double resId)
1357 {
1358 std::unique_ptr<ResMgrDataContext> dataContext = std::make_unique<ResMgrDataContext>();
1359 dataContext->addon_ = UnwrapAddon(env, object);
1360 dataContext->resId_ = resId;
1361
1362 std::shared_ptr<ResourceManager> resMgr = nullptr;
1363 uint32_t notUse = 0;
1364 bool ret = GetHapResourceManager(dataContext.get(), resMgr, notUse);
1365 if (!ret || resMgr == nullptr) {
1366 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getSymbolById");
1367 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
1368 return ABNORMAL_NUMBER_RETURN_VALUE;
1369 }
1370
1371 RState state = resMgr->GetSymbolById(resId, dataContext->symbolValue_);
1372 if (state != RState::SUCCESS) {
1373 dataContext->SetErrorMsg("GetSymbol failed state", true);
1374 ResourceManagerAniUtils::AniThrow(env, state);
1375 return ABNORMAL_NUMBER_RETURN_VALUE;
1376 }
1377 return dataContext->symbolValue_;
1378 }
1379
GetSymbolByName(ani_env * env,ani_object object,ani_string resName)1380 ani_double ResMgrAddon::GetSymbolByName(ani_env* env, ani_object object, ani_string resName)
1381 {
1382 std::unique_ptr<ResMgrDataContext> dataContext = std::make_unique<ResMgrDataContext>();
1383 dataContext->addon_ = UnwrapAddon(env, object);
1384 dataContext->resName_ = AniStrToString(env, static_cast<ani_ref>(resName));
1385
1386 std::shared_ptr<ResourceManager> resMgr = nullptr;
1387 uint32_t resId = 0;
1388 bool ret = GetHapResourceManager(dataContext.get(), resMgr, resId);
1389 if (!ret || resMgr == nullptr) {
1390 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getSymbolByName");
1391 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
1392 return ABNORMAL_NUMBER_RETURN_VALUE;
1393 }
1394
1395 RState state = resMgr->GetSymbolByName(dataContext->resName_.c_str(), dataContext->symbolValue_);
1396 if (state != RState::SUCCESS) {
1397 dataContext->SetErrorMsg("GetSymbolByName failed state", false);
1398 ResourceManagerAniUtils::AniThrow(env, state);
1399 return ABNORMAL_NUMBER_RETURN_VALUE;
1400 }
1401 return dataContext->symbolValue_;
1402 }
1403
IsRawDir(ani_env * env,ani_object object,ani_string path)1404 ani_boolean ResMgrAddon::IsRawDir(ani_env* env, ani_object object, ani_string path)
1405 {
1406 std::unique_ptr<ResMgrDataContext> dataContext = std::make_unique<ResMgrDataContext>();
1407 dataContext->path_ = AniStrToString(env, path);
1408 dataContext->addon_ = UnwrapAddon(env, object);
1409
1410 std::shared_ptr<ResourceManager> resMgr = nullptr;
1411 uint32_t resId = 0;
1412 bool ret = GetHapResourceManager(dataContext.get(), resMgr, resId);
1413 if (!ret || resMgr == nullptr) {
1414 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in isRawDir");
1415 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
1416 return false;
1417 }
1418
1419 RState state = resMgr->IsRawDirFromHap(dataContext->path_, dataContext->bValue_);
1420 if (state != RState::SUCCESS) {
1421 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to determine the raw file is directory.");
1422 ResourceManagerAniUtils::AniThrow(env, state);
1423 return false;
1424 }
1425 return dataContext->bValue_;
1426 }
1427
GetEnumMember(ani_env * env,ani_object options,const std::string name,int & member)1428 static bool GetEnumMember(ani_env *env, ani_object options, const std::string name, int& member)
1429 {
1430 ani_ref ref;
1431 if (ANI_OK != env->Object_GetPropertyByName_Ref(options, name.c_str(), &ref)) {
1432 RESMGR_HILOGE(RESMGR_ANI_TAG, "Get property '%{public}s' failed", name.c_str());
1433 return false;
1434 }
1435
1436 ani_boolean isUndefined;
1437 env->Reference_IsUndefined(ref, &isUndefined);
1438 if (isUndefined) {
1439 return false;
1440 }
1441
1442 if (ANI_OK != env->EnumItem_GetValue_Int(static_cast<ani_enum_item>(ref), &member)) {
1443 RESMGR_HILOGE(RESMGR_ANI_TAG, "Enum '%{public}s' get value int failed", name.c_str());
1444 return false;
1445 }
1446 return true;
1447 }
1448
GetNumberMember(ani_env * env,ani_object options,const std::string name,double & value)1449 static bool GetNumberMember(ani_env *env, ani_object options, const std::string name, double& value)
1450 {
1451 if (ANI_OK != env->Object_GetPropertyByName_Double(options, name.c_str(), &value)) {
1452 RESMGR_HILOGE(RESMGR_ANI_TAG, "Get property '%{public}s' failed", name.c_str());
1453 return false;
1454 }
1455 return true;
1456 }
1457
GetEnumParamOfConfig(ani_env * env,std::shared_ptr<ResConfig> configPtr,ani_object configuration)1458 static bool GetEnumParamOfConfig(ani_env* env, std::shared_ptr<ResConfig> configPtr, ani_object configuration)
1459 {
1460 int intEnum;
1461 if (GetEnumMember(env, configuration, "direction", intEnum)) {
1462 configPtr->SetDirection(static_cast<Direction>(intEnum));
1463 }
1464 if (GetEnumMember(env, configuration, "deviceType", intEnum)) {
1465 configPtr->SetDeviceType(static_cast<DeviceType>(intEnum));
1466 }
1467 if (GetEnumMember(env, configuration, "screenDensity", intEnum)) {
1468 configPtr->SetScreenDensityDpi(static_cast<ScreenDensity>(intEnum));
1469 }
1470 if (GetEnumMember(env, configuration, "colorMode", intEnum)) {
1471 configPtr->SetColorMode(static_cast<ColorMode>(intEnum));
1472 }
1473
1474 double value;
1475 if (GetNumberMember(env, configuration, "mcc", value)) {
1476 configPtr->SetMcc(value);
1477 }
1478 if (GetNumberMember(env, configuration, "mnc", value)) {
1479 configPtr->SetMnc(value);
1480 }
1481 return true;
1482 }
1483
GetLocaleOfConfig(ani_env * env,std::shared_ptr<ResConfig> configPtr,ani_object configuration)1484 static bool GetLocaleOfConfig(ani_env* env, std::shared_ptr<ResConfig> configPtr, ani_object configuration)
1485 {
1486 #ifdef SUPPORT_GRAPHICS
1487 ani_ref ret;
1488 if (ANI_OK != env->Object_GetPropertyByName_Ref(configuration, "locale", &ret)) {
1489 RESMGR_HILOGE(RESMGR_ANI_TAG, "Get property 'locale' failed");
1490 return false;
1491 }
1492 if (ret == nullptr) {
1493 RESMGR_HILOGD(RESMGR_JS_TAG, "GetLocaleOfConfig property locale not set");
1494 return true;
1495 }
1496 if (configPtr->SetLocaleInfo(AniStrToString(env, static_cast<ani_string>(ret)).c_str()) != SUCCESS) {
1497 RESMGR_HILOGE(RESMGR_ANI_TAG, "GetLocaleOfConfig failed to SetLocaleInfo");
1498 return false;
1499 }
1500 #endif
1501 return true;
1502 }
1503
GetAddonAndConfig(ani_env * env,ani_object object,ani_object configuration,std::unique_ptr<ResMgrDataContext> & dataContext)1504 static RState GetAddonAndConfig(ani_env* env, ani_object object,
1505 ani_object configuration, std::unique_ptr<ResMgrDataContext> &dataContext)
1506 {
1507 dataContext->addon_ = UnwrapAddon(env, object);
1508 if (dataContext->addon_ == nullptr) {
1509 RESMGR_HILOGE(RESMGR_ANI_TAG, "GetAddonAndConfig failed to get addon");
1510 return ERROR_CODE_INVALID_INPUT_PARAMETER;
1511 }
1512
1513 ani_boolean isUndefined;
1514 env->Reference_IsUndefined(configuration, &isUndefined);
1515 if (isUndefined) {
1516 RESMGR_HILOGD(RESMGR_ANI_TAG, "GetConfigObject, no config");
1517 return SUCCESS;
1518 }
1519
1520 ResConfig *config = CreateDefaultResConfig();
1521 if (config == nullptr) {
1522 RESMGR_HILOGE(RESMGR_ANI_TAG, "GetConfigObject, new config failed");
1523 return ERROR_CODE_INVALID_INPUT_PARAMETER;
1524 }
1525 dataContext->overrideResConfig_.reset(config);
1526
1527 if (!GetEnumParamOfConfig(env, dataContext->overrideResConfig_, configuration)) {
1528 return ERROR_CODE_INVALID_INPUT_PARAMETER;
1529 }
1530 if (!GetLocaleOfConfig(env, dataContext->overrideResConfig_, configuration)) {
1531 return ERROR_CODE_INVALID_INPUT_PARAMETER;
1532 }
1533 return SUCCESS;
1534 }
1535
CreateOverrideAddon(ani_env * env,const std::shared_ptr<ResourceManager> & resMgr)1536 ani_object ResMgrAddon::CreateOverrideAddon(ani_env* env, const std::shared_ptr<ResourceManager>& resMgr)
1537 {
1538 std::shared_ptr<ResMgrAddon> addon = std::make_shared<ResMgrAddon>(bundleName_, resMgr, context_);
1539 addon->isOverrideAddon_ = true;
1540 return WrapResourceManager(env, addon);
1541 }
1542
GetOverrideResourceManager(ani_env * env,ani_object object,ani_object configuration)1543 ani_object ResMgrAddon::GetOverrideResourceManager(ani_env* env, ani_object object, ani_object configuration)
1544 {
1545 auto dataContext = std::make_unique<ResMgrDataContext>();
1546 int32_t state = GetAddonAndConfig(env, object, configuration, dataContext);
1547 if (state != RState::SUCCESS) {
1548 dataContext->SetErrorMsg("Failed to get param in GetOverrideResourceManager", false);
1549 ResourceManagerAniUtils::AniThrow(env, state);
1550 return nullptr;
1551 }
1552
1553 std::shared_ptr<ResourceManager> resMgr = dataContext->addon_->GetResMgr();
1554 if (resMgr == nullptr) {
1555 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in getOverrideResourceManager");
1556 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
1557 return nullptr;
1558 }
1559
1560 std::shared_ptr<ResourceManager> overrideResMgr = resMgr->GetOverrideResourceManager(
1561 dataContext->overrideResConfig_);
1562 if (overrideResMgr == nullptr) {
1563 dataContext->SetErrorMsg("GetOverrideResourceManager, overrideResMgr is null", false);
1564 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_INVALID_INPUT_PARAMETER);
1565 return nullptr;
1566 }
1567
1568 return dataContext->addon_->CreateOverrideAddon(env, overrideResMgr);
1569 }
1570
GetOverrideConfiguration(ani_env * env,ani_object object)1571 ani_object ResMgrAddon::GetOverrideConfiguration(ani_env* env, ani_object object)
1572 {
1573 auto dataContext = std::make_unique<ResMgrDataContext>();
1574 dataContext->addon_ = UnwrapAddon(env, object);
1575 if (dataContext->addon_ == nullptr || dataContext->addon_->GetResMgr() == nullptr) {
1576 RESMGR_HILOGE(RESMGR_ANI_TAG, "GetOverrideConfiguration failed to get resMgr");
1577 return nullptr;
1578 }
1579
1580 std::unique_ptr<ResConfig> cfg(CreateResConfig());
1581 if (!cfg) {
1582 dataContext->SetErrorMsg("Failed to create ResConfig object.");
1583 return nullptr;
1584 }
1585 dataContext->addon_->GetResMgr()->GetOverrideResConfig(*cfg);
1586 return CreateConfig(env, cfg);
1587 }
1588
UpdateOverrideConfiguration(ani_env * env,ani_object object,ani_object configuration)1589 void ResMgrAddon::UpdateOverrideConfiguration(ani_env* env, ani_object object, ani_object configuration)
1590 {
1591 auto dataContext = std::make_unique<ResMgrDataContext>();
1592 int32_t state = GetAddonAndConfig(env, object, configuration, dataContext);
1593 if (state != RState::SUCCESS) {
1594 dataContext->SetErrorMsg("Failed to get param in GetOverrideResourceManager", false);
1595 ResourceManagerAniUtils::AniThrow(env, state);
1596 return;
1597 }
1598
1599 std::shared_ptr<ResourceManager> resMgr = dataContext->addon_->GetResMgr();
1600 if (resMgr == nullptr) {
1601 RESMGR_HILOGE(RESMGR_ANI_TAG, "Failed to get resMgr in updateOverrideConfiguration");
1602 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_RES_NOT_FOUND_BY_ID);
1603 return;
1604 }
1605
1606 state = resMgr->UpdateOverrideResConfig(*dataContext->overrideResConfig_);
1607 if (state != RState::SUCCESS) {
1608 dataContext->SetErrorMsg("UpdateOverrideConfiguration failed due to invalid config", false);
1609 ResourceManagerAniUtils::AniThrow(env, ERROR_CODE_INVALID_INPUT_PARAMETER);
1610 return;
1611 }
1612 }
1613