1 /*
2 * Copyright (c) 2021-2022 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 #include "res_config_impl.h"
16 #ifdef SUPPORT_GRAPHICS
17 #include <unicode/localebuilder.h>
18 #include <unicode/locid.h>
19 #include <unicode/utypes.h>
20 #endif
21 #include "locale_matcher.h"
22 #include "res_locale.h"
23 #include "utils/utils.h"
24 #ifdef SUPPORT_GRAPHICS
25 using icu::Locale;
26 using icu::LocaleBuilder;
27 #endif
28 namespace OHOS {
29 namespace Global {
30 namespace Resource {
31
32 static const std::vector<std::pair<float, ScreenDensity>> resolutions = {
33 { 0.0, ScreenDensity::SCREEN_DENSITY_NOT_SET },
34 { 120.0, ScreenDensity::SCREEN_DENSITY_SDPI },
35 { 160.0, ScreenDensity::SCREEN_DENSITY_MDPI },
36 { 240.0, ScreenDensity::SCREEN_DENSITY_LDPI },
37 { 320.0, ScreenDensity::SCREEN_DENSITY_XLDPI },
38 { 480.0, ScreenDensity::SCREEN_DENSITY_XXLDPI },
39 { 640.0, ScreenDensity::SCREEN_DENSITY_XXXLDPI },
40 };
41
ResConfigImpl()42 ResConfigImpl::ResConfigImpl()
43 : resLocale_(nullptr),
44 direction_(DIRECTION_NOT_SET),
45 density_(SCREEN_DENSITY_NOT_SET),
46 screenDensityDpi_(SCREEN_DENSITY_NOT_SET),
47 colorMode_(LIGHT),
48 mcc_(MCC_UNDEFINED),
49 mnc_(MNC_UNDEFINED),
50 deviceType_(DEVICE_NOT_SET),
51 inputDevice_(INPUTDEVICE_NOT_SET),
52 #ifdef SUPPORT_GRAPHICS
53 resPreferredLocale_(nullptr),
54 preferredLocaleInfo_(nullptr),
55 localeInfo_(nullptr),
56 #endif
57 isCompletedScript_(false)
58 {}
59
60 #ifdef SUPPORT_GRAPHICS
SetPreferredLocaleInfo(Locale & preferredLocaleInfo)61 RState ResConfigImpl::SetPreferredLocaleInfo(Locale &preferredLocaleInfo)
62 {
63 const char *language = preferredLocaleInfo.getLanguage();
64 const char *script = preferredLocaleInfo.getScript();
65 const char *region = preferredLocaleInfo.getCountry();
66 if (Utils::IsStrEmpty(language)) {
67 delete this->resPreferredLocale_;
68 delete this->preferredLocaleInfo_;
69 this->resPreferredLocale_ = nullptr;
70 this->preferredLocaleInfo_ = nullptr;
71 return SUCCESS;
72 }
73 RState state = BuildResLocale(language, script, region, &this->resPreferredLocale_);
74 if (state != SUCCESS) {
75 return state;
76 }
77 return BuildLocaleInfo(this->resPreferredLocale_, &this->preferredLocaleInfo_);
78 }
79
SetLocaleInfo(Locale & localeInfo)80 RState ResConfigImpl::SetLocaleInfo(Locale &localeInfo)
81 {
82 return this->SetLocaleInfo(localeInfo.getLanguage(), localeInfo.getScript(), localeInfo.getCountry());
83 }
84 #endif
85
BuildResLocale(const char * language,const char * script,const char * region,ResLocale ** resLocale)86 RState ResConfigImpl::BuildResLocale(const char *language, const char *script,
87 const char *region, ResLocale **resLocale)
88 {
89 RState state = SUCCESS;
90 ResLocale *temp = ResLocale::BuildFromParts(language, script, region, state);
91 if (state != SUCCESS) {
92 return state;
93 }
94 if (script == nullptr || script[0] == '\0') {
95 if (!LocaleMatcher::Normalize(temp)) {
96 delete temp;
97 temp = nullptr;
98 return NOT_ENOUGH_MEM;
99 }
100 }
101 delete *resLocale;
102 *resLocale = temp;
103 return state;
104 }
105
BuildLocaleInfo(const ResLocale * resLocale,Locale ** localeInfo)106 RState ResConfigImpl::BuildLocaleInfo(const ResLocale *resLocale, Locale **localeInfo)
107 {
108 UErrorCode errCode = U_ZERO_ERROR;
109 Locale temp = icu::LocaleBuilder().setLanguage(resLocale->GetLanguage())
110 .setRegion(resLocale->GetRegion()).setScript(resLocale->GetScript()).build(errCode);
111 if (!U_SUCCESS(errCode)) {
112 return NOT_ENOUGH_MEM;
113 }
114 delete *localeInfo;
115 *localeInfo = new Locale(temp);
116 return SUCCESS;
117 }
118
SetLocaleInfo(const char * language,const char * script,const char * region)119 RState ResConfigImpl::SetLocaleInfo(const char *language,
120 const char *script,
121 const char *region)
122 {
123 #ifdef SUPPORT_GRAPHICS
124 RState state = SUCCESS;
125 if (Utils::IsStrEmpty(language)) {
126 delete this->resLocale_;
127 delete this->localeInfo_;
128 this->resLocale_ = nullptr;
129 this->localeInfo_ = nullptr;
130 return state;
131 }
132 this->isCompletedScript_ = false;
133 state = BuildResLocale(language, script, region, &this->resLocale_);
134 if (state != SUCCESS) {
135 return state;
136 }
137 state = BuildLocaleInfo(this->resLocale_, &this->localeInfo_);
138 if (state != SUCCESS) {
139 return state;
140 }
141 this->isCompletedScript_ = true;
142 return state;
143 #else
144 return NOT_SUPPORT_SEP;
145 #endif
146 }
147
SetDeviceType(DeviceType deviceType)148 void ResConfigImpl::SetDeviceType(DeviceType deviceType)
149 {
150 this->deviceType_ = deviceType;
151 }
152
SetDirection(Direction direction)153 void ResConfigImpl::SetDirection(Direction direction)
154 {
155 this->direction_ = direction;
156 }
157
SetColorMode(ColorMode colorMode)158 void ResConfigImpl::SetColorMode(ColorMode colorMode)
159 {
160 this->colorMode_ = colorMode;
161 }
162
SetInputDevice(InputDevice inputDevice)163 void ResConfigImpl::SetInputDevice(InputDevice inputDevice)
164 {
165 this->inputDevice_ = inputDevice;
166 }
167
SetMcc(uint32_t mcc)168 void ResConfigImpl::SetMcc(uint32_t mcc)
169 {
170 this->mcc_ = mcc;
171 }
172
SetMnc(uint32_t mnc)173 void ResConfigImpl::SetMnc(uint32_t mnc)
174 {
175 this->mnc_ = mnc;
176 }
177
ConvertDensity(float density)178 ScreenDensity ResConfigImpl::ConvertDensity(float density)
179 {
180 float deviceDpi = density * Utils::DPI_BASE;
181 auto resolution = SCREEN_DENSITY_NOT_SET;
182 for (const auto& [dpi, value] : resolutions) {
183 resolution = value;
184 if (deviceDpi <= dpi) {
185 break;
186 }
187 }
188 return resolution;
189 }
190
SetScreenDensity(float screenDensity)191 void ResConfigImpl::SetScreenDensity(float screenDensity)
192 {
193 this->density_ = screenDensity;
194 this->screenDensityDpi_ = ConvertDensity(screenDensity);
195 }
196
197 #ifdef SUPPORT_GRAPHICS
GetResPreferredLocale() const198 const ResLocale *ResConfigImpl::GetResPreferredLocale() const
199 {
200 return this->resPreferredLocale_;
201 }
202
GetPreferredLocaleInfo() const203 const Locale *ResConfigImpl::GetPreferredLocaleInfo() const
204 {
205 return this->preferredLocaleInfo_;
206 }
207
GetLocaleInfo() const208 const Locale *ResConfigImpl::GetLocaleInfo() const
209 {
210 return localeInfo_;
211 }
212 #endif
213
GetResLocale() const214 const ResLocale *ResConfigImpl::GetResLocale() const
215 {
216 return this->resLocale_;
217 }
218
GetDirection() const219 Direction ResConfigImpl::GetDirection() const
220 {
221 return this->direction_;
222 }
223
GetScreenDensity() const224 float ResConfigImpl::GetScreenDensity() const
225 {
226 return this->density_;
227 }
228
GetColorMode() const229 ColorMode ResConfigImpl::GetColorMode() const
230 {
231 return this->colorMode_;
232 }
233
GetInputDevice() const234 InputDevice ResConfigImpl::GetInputDevice() const
235 {
236 return this->inputDevice_;
237 }
238
GetMcc() const239 uint32_t ResConfigImpl::GetMcc() const
240 {
241 return this->mcc_;
242 }
243
GetMnc() const244 uint32_t ResConfigImpl::GetMnc() const
245 {
246 return this->mnc_;
247 }
248
GetDeviceType() const249 DeviceType ResConfigImpl::GetDeviceType() const
250 {
251 return this->deviceType_;
252 }
253
254 #ifdef SUPPORT_GRAPHICS
CopyLocale(Locale ** currentLocaleInfo,ResLocale ** currentResLocale,const Locale * otherLocaleInfo)255 bool ResConfigImpl::CopyLocale(Locale **currentLocaleInfo, ResLocale **currentResLocale,
256 const Locale *otherLocaleInfo)
257 {
258 bool needCopy = false;
259 if (*currentLocaleInfo == nullptr && otherLocaleInfo != nullptr) {
260 needCopy = true;
261 }
262 if (*currentLocaleInfo != nullptr && otherLocaleInfo == nullptr) {
263 delete *currentResLocale;
264 delete *currentLocaleInfo;
265 *currentResLocale = nullptr;
266 *currentLocaleInfo = nullptr;
267 return true;
268 }
269 if (*currentResLocale != nullptr && otherLocaleInfo != nullptr) {
270 uint64_t encodedLocale = Utils::EncodeLocale(
271 (*currentResLocale)->GetLanguage(),
272 (*currentResLocale)->GetScript(), (*currentResLocale)->GetRegion());
273 uint64_t otherEncodedLocale = Utils::EncodeLocale(
274 otherLocaleInfo->getLanguage(),
275 otherLocaleInfo->getScript(), otherLocaleInfo->getCountry());
276 if (encodedLocale != otherEncodedLocale) {
277 needCopy = true;
278 }
279 }
280 if (needCopy) {
281 ResLocale *temp = new(std::nothrow) ResLocale;
282 if (temp == nullptr) {
283 return false;
284 }
285 RState rs = temp->CopyFromLocaleInfo(otherLocaleInfo);
286 if (rs != SUCCESS) {
287 delete temp;
288 return false;
289 }
290 UErrorCode errCode = U_ZERO_ERROR;
291 Locale tempLocale = icu::LocaleBuilder().setLocale(*otherLocaleInfo).build(errCode);
292
293 if (!U_SUCCESS(errCode)) {
294 delete temp;
295 return false;
296 }
297 delete *currentResLocale;
298 delete *currentLocaleInfo;
299 *currentResLocale = temp;
300 *currentLocaleInfo = new Locale(tempLocale);
301 }
302 return true;
303 }
304 #endif
305
306 #ifdef SUPPORT_GRAPHICS
CopyPreferredLocale(ResConfig & other)307 bool ResConfigImpl::CopyPreferredLocale(ResConfig &other)
308 {
309 return CopyLocale(&this->preferredLocaleInfo_, &this->resPreferredLocale_, other.GetPreferredLocaleInfo());
310 }
311 #endif
312
CopyLocale(ResConfig & other)313 bool ResConfigImpl::CopyLocale(ResConfig &other)
314 {
315 #ifdef SUPPORT_GRAPHICS
316 return CopyLocale(&this->localeInfo_, &this->resLocale_, other.GetLocaleInfo());
317 #else
318 return false;
319 #endif
320 }
Copy(ResConfig & other)321 bool ResConfigImpl::Copy(ResConfig &other)
322 {
323 if (!this->CopyLocale(other)) {
324 return false;
325 }
326 #ifdef SUPPORT_GRAPHICS
327 if (!this->CopyPreferredLocale(other)) {
328 return false;
329 }
330 #endif
331 if (this->GetDeviceType() != other.GetDeviceType()) {
332 this->SetDeviceType(other.GetDeviceType());
333 }
334 if (this->GetDirection() != other.GetDirection()) {
335 this->SetDirection(other.GetDirection());
336 }
337 if (this->GetColorMode() != other.GetColorMode()) {
338 this->SetColorMode(other.GetColorMode());
339 }
340 if (this->GetInputDevice() != other.GetInputDevice()) {
341 this->SetInputDevice(other.GetInputDevice());
342 }
343 if (this->GetMcc() != other.GetMcc()) {
344 this->SetMcc(other.GetMcc());
345 }
346 if (this->GetMnc() != other.GetMnc()) {
347 this->SetMnc(other.GetMnc());
348 }
349 if (this->GetScreenDensity() != other.GetScreenDensity()) {
350 this->SetScreenDensity(other.GetScreenDensity());
351 }
352 return true;
353 }
354
Match(const ResConfigImpl * other) const355 bool ResConfigImpl::Match(const ResConfigImpl *other) const
356 {
357 if (other == nullptr) {
358 return false;
359 }
360 if (!IsMccMncMatch(other->mcc_, other->mnc_)) {
361 return false;
362 }
363
364 bool isPreferredLocaleMatch = false;
365 #ifdef SUPPORT_GRAPHICS
366 if (this->resPreferredLocale_ != nullptr) {
367 isPreferredLocaleMatch = LocaleMatcher::Match(this->resPreferredLocale_, other->GetResLocale());
368 }
369 #endif
370
371 if (!isPreferredLocaleMatch && !(LocaleMatcher::Match(this->resLocale_, other->GetResLocale()))) {
372 return false;
373 }
374 if (!IsDirectionMatch(other->direction_)) {
375 return false;
376 }
377 if (!IsDeviceTypeMatch(other->deviceType_)) {
378 return false;
379 }
380 if (!IsColorModeMatch(other->colorMode_)) {
381 return false;
382 }
383 if (!IsInputDeviceMatch(other->inputDevice_)) {
384 return false;
385 }
386 return true;
387 }
388
IsMccMncMatch(uint32_t mcc,uint32_t mnc) const389 bool ResConfigImpl::IsMccMncMatch(uint32_t mcc, uint32_t mnc) const
390 {
391 if (this->mcc_ != MCC_UNDEFINED && this->mnc_ != MNC_UNDEFINED) {
392 if (mcc != MCC_UNDEFINED && mnc != MNC_UNDEFINED) {
393 if (this->mcc_ != mcc || this->mnc_ != mnc) {
394 return false;
395 }
396 }
397 } else if (this->mcc_ != MCC_UNDEFINED && this->mnc_ == MNC_UNDEFINED) {
398 if (mcc != MCC_UNDEFINED && this->mcc_ != mcc) {
399 return false;
400 }
401 }
402 return true;
403 }
404
IsDirectionMatch(Direction direction) const405 bool ResConfigImpl::IsDirectionMatch(Direction direction) const
406 {
407 if (this->direction_ != DIRECTION_NOT_SET && direction != DIRECTION_NOT_SET) {
408 if (this->direction_ != direction) {
409 return false;
410 }
411 }
412 return true;
413 }
414
IsDeviceTypeMatch(DeviceType deviceType) const415 bool ResConfigImpl::IsDeviceTypeMatch(DeviceType deviceType) const
416 {
417 if (this->deviceType_ != DEVICE_NOT_SET && deviceType != DEVICE_NOT_SET) {
418 if (this->deviceType_ != deviceType) {
419 return false;
420 }
421 }
422 return true;
423 }
424
IsColorModeMatch(ColorMode colorMode) const425 bool ResConfigImpl::IsColorModeMatch(ColorMode colorMode) const
426 {
427 if (this->colorMode_ != COLOR_MODE_NOT_SET && colorMode != COLOR_MODE_NOT_SET) {
428 if (this->colorMode_ != colorMode) {
429 return false;
430 }
431 }
432 return true;
433 }
434
IsInputDeviceMatch(InputDevice inputDevice) const435 bool ResConfigImpl::IsInputDeviceMatch(InputDevice inputDevice) const
436 {
437 if (this->inputDevice_ == INPUTDEVICE_NOT_SET && inputDevice != INPUTDEVICE_NOT_SET) {
438 return false;
439 }
440 // reserve for future InputDevice expansion
441 if (this->inputDevice_ != INPUTDEVICE_NOT_SET && inputDevice != INPUTDEVICE_NOT_SET) {
442 if (this->inputDevice_ != inputDevice) {
443 return false;
444 }
445 }
446 return true;
447 }
448
449 /**
450 * compare this and target
451 * if this more match request,then return true
452 * else
453 * return false
454 *
455 */
IsMoreSuitable(const ResConfigImpl * other,const ResConfigImpl * request,uint32_t density) const456 bool ResConfigImpl::IsMoreSuitable(const ResConfigImpl *other,
457 const ResConfigImpl *request, uint32_t density) const
458 {
459 if (request != nullptr && other != nullptr) {
460 int ret = IsMccMncMoreSuitable(other->mcc_, other->mnc_, request->mcc_, request->mnc_);
461 if (ret != 0) {
462 return ret > 0;
463 }
464 #ifdef SUPPORT_GRAPHICS
465 if (request->GetResPreferredLocale() != nullptr) {
466 int8_t preferredResult = LocaleMatcher::IsMoreSuitable(this->GetResLocale(), other->GetResLocale(),
467 request->GetResPreferredLocale());
468 if (preferredResult != 0) {
469 return preferredResult > 0;
470 }
471 }
472 #endif
473 int8_t result = LocaleMatcher::IsMoreSuitable(this->GetResLocale(), other->GetResLocale(),
474 request->GetResLocale());
475 if (result != 0) {
476 return result > 0;
477 }
478 /**
479 * direction must full match.
480 * when request is set direction and this is not equal other.
481 * this or other oriention is not set.
482 */
483 if (this->direction_ != other->direction_ &&
484 request->direction_ != Direction::DIRECTION_NOT_SET) {
485 return this->direction_ != Direction::DIRECTION_NOT_SET;
486 }
487 if (this->deviceType_ != other->deviceType_ &&
488 request->deviceType_ != DeviceType::DEVICE_NOT_SET) {
489 return this->deviceType_ != DeviceType::DEVICE_NOT_SET;
490 }
491 if (this->colorMode_ != other->colorMode_ &&
492 request->colorMode_ != ColorMode::COLOR_MODE_NOT_SET) {
493 return this->colorMode_ != ColorMode::COLOR_MODE_NOT_SET;
494 }
495 if (this->inputDevice_ != other->inputDevice_ &&
496 request->inputDevice_ != InputDevice::INPUTDEVICE_NOT_SET) {
497 return this->inputDevice_ != InputDevice::INPUTDEVICE_NOT_SET;
498 }
499 ret = IsDensityMoreSuitable(other->screenDensityDpi_, request->screenDensityDpi_, density);
500 if (ret != 0) {
501 return ret > 0;
502 }
503 }
504 return this->IsMoreSpecificThan(other, density);
505 }
506
507 /**
508 * compare this and target mcc/mnc
509 * if this more match other,then return 1, else if other more match this, return -1,
510 * else
511 * return 0
512 *
513 */
IsMccMncMoreSuitable(uint32_t otherMcc,uint32_t otherMnc,uint32_t requestMcc,uint32_t requestMnc) const514 int ResConfigImpl::IsMccMncMoreSuitable(uint32_t otherMcc, uint32_t otherMnc, uint32_t requestMcc,
515 uint32_t requestMnc) const
516 {
517 int ret = 0;
518 bool defined = requestMcc != MCC_UNDEFINED && requestMnc != MNC_UNDEFINED;
519 bool mccDefined = requestMcc != MCC_UNDEFINED && requestMnc == MNC_UNDEFINED;
520 bool isMccOrMncDiff = this->mcc_ != otherMcc || this->mnc_ != otherMnc;
521 bool isMccDiff = this->mcc_ != otherMcc;
522 if (defined && isMccOrMncDiff) {
523 if ((this->mcc_ != MCC_UNDEFINED) && (this->mnc_ != MNC_UNDEFINED)) {
524 // the mcc/mnc of this resConfig is suitable than other resConfig
525 ret = 1;
526 } else {
527 // the mcc/mnc of other resConfig mcc/mnc is suitable than this resConfig
528 ret = -1;
529 }
530 } else if (mccDefined && isMccDiff) {
531 if (this->mcc_ != MCC_UNDEFINED) {
532 // the mcc of this resConfig is suitable than other resConfig
533 ret = 1;
534 } else {
535 // the mcc of other resConfig is suitable than this resConfig
536 ret = -1;
537 }
538 }
539 return ret;
540 }
541
542 /**
543 * compare this and target density
544 * if this more match other,then return 1, else if other more match this, return -1,
545 * else
546 * return 0
547 *
548 */
IsDensityMoreSuitable(ScreenDensity otherDensity,ScreenDensity requestDensity,uint32_t density) const549 int ResConfigImpl::IsDensityMoreSuitable(ScreenDensity otherDensity, ScreenDensity requestDensity,
550 uint32_t density) const
551 {
552 int ret = 0;
553 int thisDistance;
554 int otherDistance;
555 if (density == ScreenDensity::SCREEN_DENSITY_NOT_SET) {
556 if (requestDensity != ScreenDensity::SCREEN_DENSITY_NOT_SET &&
557 this->screenDensityDpi_ != otherDensity) {
558 thisDistance = this->screenDensityDpi_ - requestDensity;
559 otherDistance = otherDensity - requestDensity;
560 if (IsDensityMoreSuitable(thisDistance, otherDistance)) {
561 // the density of this resConfig is suitable than other resConfig
562 ret = 1;
563 } else {
564 // the density of other resConfig is suitable than this resConfig
565 ret = -1;
566 }
567 }
568 } else {
569 if (this->screenDensityDpi_ != otherDensity) {
570 thisDistance = static_cast<int>(this->screenDensityDpi_ - density);
571 otherDistance = static_cast<int>(otherDensity - density);
572 if (IsDensityMoreSuitable(thisDistance, otherDistance)) {
573 // the density of this resConfig is suitable than other resConfig
574 ret = 1;
575 } else {
576 // the density of other resConfig is suitable than this resConfig
577 ret = -1;
578 }
579 }
580 }
581 return ret;
582 }
583
IsDensityMoreSuitable(int thisDistance,int otherDistance) const584 bool ResConfigImpl::IsDensityMoreSuitable(int thisDistance, int otherDistance) const
585 {
586 if (thisDistance >= 0 && otherDistance >= 0) {
587 return (thisDistance <= otherDistance);
588 }
589 if (thisDistance > 0) {
590 return true;
591 }
592 if (otherDistance > 0) {
593 return false;
594 }
595 return (thisDistance >= otherDistance);
596 }
597
~ResConfigImpl()598 ResConfigImpl::~ResConfigImpl()
599 {
600 if (resLocale_ != nullptr) {
601 delete resLocale_;
602 resLocale_ = nullptr;
603 }
604 if (resPreferredLocale_ != nullptr) {
605 delete resPreferredLocale_;
606 resPreferredLocale_ = nullptr;
607 }
608 #ifdef SUPPORT_GRAPHICS
609 if (localeInfo_ != nullptr) {
610 delete localeInfo_;
611 localeInfo_ = nullptr;
612 }
613 if (preferredLocaleInfo_ != nullptr) {
614 delete preferredLocaleInfo_;
615 preferredLocaleInfo_ = nullptr;
616 }
617 #endif
618 }
619
CompleteScript()620 void ResConfigImpl::CompleteScript()
621 {
622 if (isCompletedScript_) {
623 return;
624 }
625 if (LocaleMatcher::Normalize(this->resLocale_)) {
626 isCompletedScript_ = true;
627 }
628 }
629
IsCompletedScript() const630 bool ResConfigImpl::IsCompletedScript() const
631 {
632 return isCompletedScript_;
633 }
634
IsMoreSpecificThan(const ResConfigImpl * other,uint32_t density) const635 bool ResConfigImpl::IsMoreSpecificThan(const ResConfigImpl *other, uint32_t density) const
636 {
637 if (other == nullptr) {
638 return true;
639 }
640 if (this->mcc_ != MCC_UNDEFINED && this->mnc_ != MNC_UNDEFINED) {
641 if (this->mcc_ != other->mcc_ || this->mnc_ != other->mnc_) {
642 return false;
643 }
644 } else if (this->mcc_ != MCC_UNDEFINED && this->mnc_ == MNC_UNDEFINED) {
645 if (this->mcc_ != other->mcc_) {
646 return true;
647 }
648 }
649 int8_t result = LocaleMatcher::IsMoreSpecificThan(
650 this->GetResLocale(),
651 (other == nullptr) ? nullptr : other->GetResLocale());
652 if (result > 0) {
653 return true;
654 }
655 if (result < 0) {
656 return false;
657 }
658 if (this->direction_ != other->direction_) {
659 return (this->direction_ != Direction::DIRECTION_NOT_SET);
660 }
661 if (this->deviceType_ != other->deviceType_) {
662 return (this->deviceType_ != DeviceType::DEVICE_NOT_SET);
663 }
664 if (this->colorMode_ != other->colorMode_) {
665 return (this->colorMode_ != ColorMode::COLOR_MODE_NOT_SET);
666 }
667 if (this->inputDevice_ != other->inputDevice_) {
668 return (this->inputDevice_ == InputDevice::INPUTDEVICE_NOT_SET);
669 }
670 int ret = IsDensityMoreSpecificThan(other->screenDensityDpi_, density);
671 if (ret != 0) {
672 return ret > 0;
673 }
674
675 return true;
676 }
677
IsDensityMoreSpecificThan(ScreenDensity otherDensity,uint32_t density) const678 int ResConfigImpl::IsDensityMoreSpecificThan(ScreenDensity otherDensity, uint32_t density) const
679 {
680 int ret = 0;
681 if (density == SCREEN_DENSITY_NOT_SET) {
682 if (this->screenDensityDpi_ != otherDensity) {
683 if (this->screenDensityDpi_ != ScreenDensity::SCREEN_DENSITY_NOT_SET) {
684 // the density of this resConfig is suitable than other resConfig
685 ret = 1;
686 } else {
687 // the density of other resConfig is suitable than this resConfig
688 ret = -1;
689 }
690 }
691 } else {
692 if ((this->screenDensityDpi_ != ScreenDensity::SCREEN_DENSITY_NOT_SET) &&
693 (otherDensity == ScreenDensity::SCREEN_DENSITY_NOT_SET)) {
694 // the density of this resConfig is suitable than other resConfig
695 ret = 1;
696 }
697 if ((this->screenDensityDpi_ == ScreenDensity::SCREEN_DENSITY_NOT_SET) &&
698 (otherDensity != ScreenDensity::SCREEN_DENSITY_NOT_SET)) {
699 // the density of other resConfig is suitable than this resConfig
700 ret = -1;
701 }
702 if (this->screenDensityDpi_ != otherDensity) {
703 int thisDistance = static_cast<int>(this->screenDensityDpi_ - density);
704 int otherDistance = static_cast<int>(otherDensity - density);
705 if (IsDensityMoreSuitable(thisDistance, otherDistance)) {
706 // the density of this resConfig is suitable than other resConfig
707 ret = 1;
708 } else {
709 // the density of other resConfig is suitable than this resConfig
710 ret = -1;
711 }
712 }
713 }
714 return ret;
715 }
716
CreateResConfig()717 ResConfig *CreateResConfig()
718 {
719 ResConfigImpl *temp = new(std::nothrow) ResConfigImpl;
720 return temp;
721 }
722 } // namespace Resource
723 } // namespace Global
724 } // namespace OHOS