• 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 
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", &param);
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