| 1 | 
           efrain | 
           1 | 
           /*
  | 
        
        
            | 
            | 
           2 | 
            * Copyright 2019 Google
  | 
        
        
            | 
            | 
           3 | 
            *
  | 
        
        
            | 
            | 
           4 | 
            * Licensed under the Apache License, Version 2.0 (the "License");
  | 
        
        
            | 
            | 
           5 | 
            * you may not use this file except in compliance with the License.
  | 
        
        
            | 
            | 
           6 | 
            * You may obtain a copy of the License at
  | 
        
        
            | 
            | 
           7 | 
            *
  | 
        
        
            | 
            | 
           8 | 
            *      http://www.apache.org/licenses/LICENSE-2.0
  | 
        
        
            | 
            | 
           9 | 
            *
  | 
        
        
            | 
            | 
           10 | 
            * Unless required by applicable law or agreed to in writing, software
  | 
        
        
            | 
            | 
           11 | 
            * distributed under the License is distributed on an "AS IS" BASIS,
  | 
        
        
            | 
            | 
           12 | 
            * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  | 
        
        
            | 
            | 
           13 | 
            * See the License for the specific language governing permissions and
  | 
        
        
            | 
            | 
           14 | 
            * limitations under the License.
  | 
        
        
            | 
            | 
           15 | 
            */
  | 
        
        
            | 
            | 
           16 | 
              | 
        
        
            | 
            | 
           17 | 
           #import "FirebaseRemoteConfig/Sources/RCNDevice.h"
  | 
        
        
            | 
            | 
           18 | 
              | 
        
        
            | 
            | 
           19 | 
           #import <sys/utsname.h>
  | 
        
        
            | 
            | 
           20 | 
              | 
        
        
            | 
            | 
           21 | 
           #import <GoogleUtilities/GULAppEnvironmentUtil.h>
  | 
        
        
            | 
            | 
           22 | 
           #import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h"
  | 
        
        
            | 
            | 
           23 | 
           #import "FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h"
  | 
        
        
            | 
            | 
           24 | 
           #import "FirebaseRemoteConfig/Sources/RCNConfigConstants.h"
  | 
        
        
            | 
            | 
           25 | 
              | 
        
        
            | 
            | 
           26 | 
           #define STR(x) STR_EXPAND(x)
  | 
        
        
            | 
            | 
           27 | 
           #define STR_EXPAND(x) #x
  | 
        
        
            | 
            | 
           28 | 
              | 
        
        
            | 
            | 
           29 | 
           static NSString *const RCNDeviceContextKeyVersion = @"app_version";
  | 
        
        
            | 
            | 
           30 | 
           static NSString *const RCNDeviceContextKeyBuild = @"app_build";
  | 
        
        
            | 
            | 
           31 | 
           static NSString *const RCNDeviceContextKeyOSVersion = @"os_version";
  | 
        
        
            | 
            | 
           32 | 
           static NSString *const RCNDeviceContextKeyDeviceLocale = @"device_locale";
  | 
        
        
            | 
            | 
           33 | 
           static NSString *const RCNDeviceContextKeyLocaleLanguage = @"locale_language";
  | 
        
        
            | 
            | 
           34 | 
           static NSString *const RCNDeviceContextKeyGMPProjectIdentifier = @"GMP_project_Identifier";
  | 
        
        
            | 
            | 
           35 | 
              | 
        
        
            | 
            | 
           36 | 
           NSString *FIRRemoteConfigAppVersion() {
  | 
        
        
            | 
            | 
           37 | 
             return [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"];
  | 
        
        
            | 
            | 
           38 | 
           }
  | 
        
        
            | 
            | 
           39 | 
              | 
        
        
            | 
            | 
           40 | 
           NSString *FIRRemoteConfigAppBuildVersion() {
  | 
        
        
            | 
            | 
           41 | 
             return [[NSBundle mainBundle] infoDictionary][@"CFBundleVersion"];
  | 
        
        
            | 
            | 
           42 | 
           }
  | 
        
        
            | 
            | 
           43 | 
              | 
        
        
            | 
            | 
           44 | 
           NSString *FIRRemoteConfigPodVersion() {
  | 
        
        
            | 
            | 
           45 | 
             return FIRFirebaseVersion();
  | 
        
        
            | 
            | 
           46 | 
           }
  | 
        
        
            | 
            | 
           47 | 
              | 
        
        
            | 
            | 
           48 | 
           RCNDeviceModel FIRRemoteConfigDeviceSubtype() {
  | 
        
        
            | 
            | 
           49 | 
             NSString *model = [GULAppEnvironmentUtil deviceModel];
  | 
        
        
            | 
            | 
           50 | 
             if ([model hasPrefix:@"iPhone"]) {
  | 
        
        
            | 
            | 
           51 | 
               return RCNDeviceModelPhone;
  | 
        
        
            | 
            | 
           52 | 
             }
  | 
        
        
            | 
            | 
           53 | 
             if ([model isEqualToString:@"iPad"]) {
  | 
        
        
            | 
            | 
           54 | 
               return RCNDeviceModelTablet;
  | 
        
        
            | 
            | 
           55 | 
             }
  | 
        
        
            | 
            | 
           56 | 
             return RCNDeviceModelOther;
  | 
        
        
            | 
            | 
           57 | 
           }
  | 
        
        
            | 
            | 
           58 | 
              | 
        
        
            | 
            | 
           59 | 
           NSString *FIRRemoteConfigDeviceCountry() {
  | 
        
        
            | 
            | 
           60 | 
             return [[[NSLocale currentLocale] objectForKey:NSLocaleCountryCode] lowercaseString];
  | 
        
        
            | 
            | 
           61 | 
           }
  | 
        
        
            | 
            | 
           62 | 
              | 
        
        
            | 
            | 
           63 | 
           NSDictionary<NSString *, NSArray *> *FIRRemoteConfigFirebaseLocaleMap(void) {
  | 
        
        
            | 
            | 
           64 | 
             return @{
  | 
        
        
            | 
            | 
           65 | 
               // Albanian
  | 
        
        
            | 
            | 
           66 | 
               @"sq" : @[ @"sq_AL" ],
  | 
        
        
            | 
            | 
           67 | 
               // Belarusian
  | 
        
        
            | 
            | 
           68 | 
               @"be" : @[ @"be_BY" ],
  | 
        
        
            | 
            | 
           69 | 
               // Bulgarian
  | 
        
        
            | 
            | 
           70 | 
               @"bg" : @[ @"bg_BG" ],
  | 
        
        
            | 
            | 
           71 | 
               // Catalan
  | 
        
        
            | 
            | 
           72 | 
               @"ca" : @[ @"ca", @"ca_ES" ],
  | 
        
        
            | 
            | 
           73 | 
               // Croatian
  | 
        
        
            | 
            | 
           74 | 
               @"hr" : @[ @"hr", @"hr_HR" ],
  | 
        
        
            | 
            | 
           75 | 
               // Czech
  | 
        
        
            | 
            | 
           76 | 
               @"cs" : @[ @"cs", @"cs_CZ" ],
  | 
        
        
            | 
            | 
           77 | 
               // Danish
  | 
        
        
            | 
            | 
           78 | 
               @"da" : @[ @"da", @"da_DK" ],
  | 
        
        
            | 
            | 
           79 | 
               // Estonian
  | 
        
        
            | 
            | 
           80 | 
               @"et" : @[ @"et_EE" ],
  | 
        
        
            | 
            | 
           81 | 
               // Finnish
  | 
        
        
            | 
            | 
           82 | 
               @"fi" : @[ @"fi", @"fi_FI" ],
  | 
        
        
            | 
            | 
           83 | 
               // Hebrew
  | 
        
        
            | 
            | 
           84 | 
               @"he" : @[ @"he", @"iw_IL" ],
  | 
        
        
            | 
            | 
           85 | 
               // Hindi
  | 
        
        
            | 
            | 
           86 | 
               @"hi" : @[ @"hi_IN" ],
  | 
        
        
            | 
            | 
           87 | 
               // Hungarian
  | 
        
        
            | 
            | 
           88 | 
               @"hu" : @[ @"hu", @"hu_HU" ],
  | 
        
        
            | 
            | 
           89 | 
               // Icelandic
  | 
        
        
            | 
            | 
           90 | 
               @"is" : @[ @"is_IS" ],
  | 
        
        
            | 
            | 
           91 | 
               // Indonesian
  | 
        
        
            | 
            | 
           92 | 
               @"id" : @[ @"id", @"in_ID", @"id_ID" ],
  | 
        
        
            | 
            | 
           93 | 
               // Irish
  | 
        
        
            | 
            | 
           94 | 
               @"ga" : @[ @"ga_IE" ],
  | 
        
        
            | 
            | 
           95 | 
               // Korean
  | 
        
        
            | 
            | 
           96 | 
               @"ko" : @[ @"ko", @"ko_KR", @"ko-KR" ],
  | 
        
        
            | 
            | 
           97 | 
               // Latvian
  | 
        
        
            | 
            | 
           98 | 
               @"lv" : @[ @"lv_LV" ],
  | 
        
        
            | 
            | 
           99 | 
               // Lithuanian
  | 
        
        
            | 
            | 
           100 | 
               @"lt" : @[ @"lt_LT" ],
  | 
        
        
            | 
            | 
           101 | 
               // Macedonian
  | 
        
        
            | 
            | 
           102 | 
               @"mk" : @[ @"mk_MK" ],
  | 
        
        
            | 
            | 
           103 | 
               // Malay
  | 
        
        
            | 
            | 
           104 | 
               @"ms" : @[ @"ms_MY" ],
  | 
        
        
            | 
            | 
           105 | 
               // Maltese
  | 
        
        
            | 
            | 
           106 | 
               @"mt" : @[ @"mt_MT" ],
  | 
        
        
            | 
            | 
           107 | 
               // Polish
  | 
        
        
            | 
            | 
           108 | 
               @"pl" : @[ @"pl", @"pl_PL", @"pl-PL" ],
  | 
        
        
            | 
            | 
           109 | 
               // Romanian
  | 
        
        
            | 
            | 
           110 | 
               @"ro" : @[ @"ro", @"ro_RO" ],
  | 
        
        
            | 
            | 
           111 | 
               // Russian
  | 
        
        
            | 
            | 
           112 | 
               @"ru" : @[ @"ru_RU", @"ru", @"ru_BY", @"ru_KZ", @"ru-RU" ],
  | 
        
        
            | 
            | 
           113 | 
               // Slovak
  | 
        
        
            | 
            | 
           114 | 
               @"sk" : @[ @"sk", @"sk_SK" ],
  | 
        
        
            | 
            | 
           115 | 
               // Slovenian
  | 
        
        
            | 
            | 
           116 | 
               @"sl" : @[ @"sl_SI" ],
  | 
        
        
            | 
            | 
           117 | 
               // Swedish
  | 
        
        
            | 
            | 
           118 | 
               @"sv" : @[ @"sv", @"sv_SE", @"sv-SE" ],
  | 
        
        
            | 
            | 
           119 | 
               // Turkish
  | 
        
        
            | 
            | 
           120 | 
               @"tr" : @[ @"tr", @"tr-TR", @"tr_TR" ],
  | 
        
        
            | 
            | 
           121 | 
               // Ukrainian
  | 
        
        
            | 
            | 
           122 | 
               @"uk" : @[ @"uk", @"uk_UA" ],
  | 
        
        
            | 
            | 
           123 | 
               // Vietnamese
  | 
        
        
            | 
            | 
           124 | 
               @"vi" : @[ @"vi", @"vi_VN" ],
  | 
        
        
            | 
            | 
           125 | 
               // The following are groups of locales or locales that sub-divide a
  | 
        
        
            | 
            | 
           126 | 
               // language).
  | 
        
        
            | 
            | 
           127 | 
               // Arabic
  | 
        
        
            | 
            | 
           128 | 
               @"ar" : @[
  | 
        
        
            | 
            | 
           129 | 
                 @"ar",    @"ar_DZ", @"ar_BH", @"ar_EG", @"ar_IQ", @"ar_JO", @"ar_KW",
  | 
        
        
            | 
            | 
           130 | 
                 @"ar_LB", @"ar_LY", @"ar_MA", @"ar_OM", @"ar_QA", @"ar_SA", @"ar_SD",
  | 
        
        
            | 
            | 
           131 | 
                 @"ar_SY", @"ar_TN", @"ar_AE", @"ar_YE", @"ar_GB", @"ar-IQ", @"ar_US"
  | 
        
        
            | 
            | 
           132 | 
               ],
  | 
        
        
            | 
            | 
           133 | 
               // Simplified Chinese
  | 
        
        
            | 
            | 
           134 | 
               @"zh_Hans" : @[ @"zh_CN", @"zh_SG", @"zh-Hans" ],
  | 
        
        
            | 
            | 
           135 | 
               // Traditional Chinese
  | 
        
        
            | 
            | 
           136 | 
               // Remove zh_HK until console added to the list. Otherwise client sends
  | 
        
        
            | 
            | 
           137 | 
               // zh_HK and server/console falls back to zh.
  | 
        
        
            | 
            | 
           138 | 
               // @"zh_Hant" : @[ @"zh_HK", @"zh_TW", @"zh-Hant", @"zh-HK", @"zh-TW" ],
  | 
        
        
            | 
            | 
           139 | 
               @"zh_Hant" : @[ @"zh_TW", @"zh-Hant", @"zh-TW" ],
  | 
        
        
            | 
            | 
           140 | 
               // Dutch
  | 
        
        
            | 
            | 
           141 | 
               @"nl" : @[ @"nl", @"nl_BE", @"nl_NL", @"nl-NL" ],
  | 
        
        
            | 
            | 
           142 | 
               // English
  | 
        
        
            | 
            | 
           143 | 
               @"en" : @[
  | 
        
        
            | 
            | 
           144 | 
                 @"en",    @"en_AU", @"en_CA", @"en_IN", @"en_IE", @"en_MT", @"en_NZ", @"en_PH",
  | 
        
        
            | 
            | 
           145 | 
                 @"en_SG", @"en_ZA", @"en_GB", @"en_US", @"en_AE", @"en-AE", @"en_AS", @"en-AU",
  | 
        
        
            | 
            | 
           146 | 
                 @"en_BD", @"en-CA", @"en_EG", @"en_ES", @"en_GB", @"en-GB", @"en_HK", @"en_ID",
  | 
        
        
            | 
            | 
           147 | 
                 @"en-IN", @"en_NG", @"en-PH", @"en_PK", @"en-SG", @"en-US"
  | 
        
        
            | 
            | 
           148 | 
               ],
  | 
        
        
            | 
            | 
           149 | 
               // French
  | 
        
        
            | 
            | 
           150 | 
               @"fr" :
  | 
        
        
            | 
            | 
           151 | 
                   @[ @"fr", @"fr_BE", @"fr_CA", @"fr_FR", @"fr_LU", @"fr_CH", @"fr-CA", @"fr-FR", @"fr_MA" ],
  | 
        
        
            | 
            | 
           152 | 
               // German
  | 
        
        
            | 
            | 
           153 | 
               @"de" : @[ @"de", @"de_AT", @"de_DE", @"de_LU", @"de_CH", @"de-DE" ],
  | 
        
        
            | 
            | 
           154 | 
               // Greek
  | 
        
        
            | 
            | 
           155 | 
               @"el" : @[ @"el", @"el_CY", @"el_GR" ],
  | 
        
        
            | 
            | 
           156 | 
               // Italian
  | 
        
        
            | 
            | 
           157 | 
               @"it" : @[ @"it", @"it_IT", @"it_CH", @"it-IT" ],
  | 
        
        
            | 
            | 
           158 | 
               // Japanese
  | 
        
        
            | 
            | 
           159 | 
               @"ja" : @[ @"ja", @"ja_JP", @"ja_JP_JP", @"ja-JP" ],
  | 
        
        
            | 
            | 
           160 | 
               // Norwegian
  | 
        
        
            | 
            | 
           161 | 
               @"no" : @[ @"nb", @"no_NO", @"no_NO_NY", @"nb_NO" ],
  | 
        
        
            | 
            | 
           162 | 
               // Brazilian Portuguese
  | 
        
        
            | 
            | 
           163 | 
               @"pt_BR" : @[ @"pt_BR", @"pt-BR" ],
  | 
        
        
            | 
            | 
           164 | 
               // European Portuguese
  | 
        
        
            | 
            | 
           165 | 
               @"pt_PT" : @[ @"pt", @"pt_PT", @"pt-PT" ],
  | 
        
        
            | 
            | 
           166 | 
               // Serbian
  | 
        
        
            | 
            | 
           167 | 
               @"sr" : @[ @"sr_BA", @"sr_ME", @"sr_RS", @"sr_Latn_BA", @"sr_Latn_ME", @"sr_Latn_RS" ],
  | 
        
        
            | 
            | 
           168 | 
               // European Spanish
  | 
        
        
            | 
            | 
           169 | 
               @"es_ES" : @[ @"es", @"es_ES", @"es-ES" ],
  | 
        
        
            | 
            | 
           170 | 
               // Mexican Spanish
  | 
        
        
            | 
            | 
           171 | 
               @"es_MX" : @[ @"es-MX", @"es_MX", @"es_US", @"es-US" ],
  | 
        
        
            | 
            | 
           172 | 
               // Latin American Spanish
  | 
        
        
            | 
            | 
           173 | 
               @"es_419" : @[
  | 
        
        
            | 
            | 
           174 | 
                 @"es_AR", @"es_BO", @"es_CL", @"es_CO", @"es_CR", @"es_DO", @"es_EC",
  | 
        
        
            | 
            | 
           175 | 
                 @"es_SV", @"es_GT", @"es_HN", @"es_NI", @"es_PA", @"es_PY", @"es_PE",
  | 
        
        
            | 
            | 
           176 | 
                 @"es_PR", @"es_UY", @"es_VE", @"es-AR", @"es-CL", @"es-CO"
  | 
        
        
            | 
            | 
           177 | 
               ],
  | 
        
        
            | 
            | 
           178 | 
               // Thai
  | 
        
        
            | 
            | 
           179 | 
               @"th" : @[ @"th", @"th_TH", @"th_TH_TH" ],
  | 
        
        
            | 
            | 
           180 | 
             };
  | 
        
        
            | 
            | 
           181 | 
           }
  | 
        
        
            | 
            | 
           182 | 
              | 
        
        
            | 
            | 
           183 | 
           NSArray<NSString *> *FIRRemoteConfigAppManagerLocales(void) {
  | 
        
        
            | 
            | 
           184 | 
             NSMutableArray *locales = [NSMutableArray array];
  | 
        
        
            | 
            | 
           185 | 
             NSDictionary<NSString *, NSArray *> *localesMap = FIRRemoteConfigFirebaseLocaleMap();
  | 
        
        
            | 
            | 
           186 | 
             for (NSString *key in localesMap) {
  | 
        
        
            | 
            | 
           187 | 
               [locales addObjectsFromArray:localesMap[key]];
  | 
        
        
            | 
            | 
           188 | 
             }
  | 
        
        
            | 
            | 
           189 | 
             return locales;
  | 
        
        
            | 
            | 
           190 | 
           }
  | 
        
        
            | 
            | 
           191 | 
           NSString *FIRRemoteConfigDeviceLocale(void) {
  | 
        
        
            | 
            | 
           192 | 
             NSArray<NSString *> *locales = FIRRemoteConfigAppManagerLocales();
  | 
        
        
            | 
            | 
           193 | 
             NSArray<NSString *> *preferredLocalizations =
  | 
        
        
            | 
            | 
           194 | 
                 [NSBundle preferredLocalizationsFromArray:locales
  | 
        
        
            | 
            | 
           195 | 
                                            forPreferences:[NSLocale preferredLanguages]];
  | 
        
        
            | 
            | 
           196 | 
             NSString *legalDocsLanguage = [preferredLocalizations firstObject];
  | 
        
        
            | 
            | 
           197 | 
             // Use en as the default language
  | 
        
        
            | 
            | 
           198 | 
             return legalDocsLanguage ? legalDocsLanguage : @"en";
  | 
        
        
            | 
            | 
           199 | 
           }
  | 
        
        
            | 
            | 
           200 | 
              | 
        
        
            | 
            | 
           201 | 
           NSString *FIRRemoteConfigTimezone(void) {
  | 
        
        
            | 
            | 
           202 | 
             NSTimeZone *timezone = [NSTimeZone systemTimeZone];
  | 
        
        
            | 
            | 
           203 | 
             return timezone.name;
  | 
        
        
            | 
            | 
           204 | 
           }
  | 
        
        
            | 
            | 
           205 | 
              | 
        
        
            | 
            | 
           206 | 
           NSMutableDictionary *FIRRemoteConfigDeviceContextWithProjectIdentifier(
  | 
        
        
            | 
            | 
           207 | 
               NSString *GMPProjectIdentifier) {
  | 
        
        
            | 
            | 
           208 | 
             NSMutableDictionary *deviceContext = [[NSMutableDictionary alloc] init];
  | 
        
        
            | 
            | 
           209 | 
             deviceContext[RCNDeviceContextKeyVersion] = FIRRemoteConfigAppVersion();
  | 
        
        
            | 
            | 
           210 | 
             deviceContext[RCNDeviceContextKeyBuild] = FIRRemoteConfigAppBuildVersion();
  | 
        
        
            | 
            | 
           211 | 
             deviceContext[RCNDeviceContextKeyOSVersion] = [GULAppEnvironmentUtil systemVersion];
  | 
        
        
            | 
            | 
           212 | 
             deviceContext[RCNDeviceContextKeyDeviceLocale] = FIRRemoteConfigDeviceLocale();
  | 
        
        
            | 
            | 
           213 | 
             // NSDictionary setObjectForKey will fail if there's no GMP project ID, must check ahead.
  | 
        
        
            | 
            | 
           214 | 
             if (GMPProjectIdentifier) {
  | 
        
        
            | 
            | 
           215 | 
               deviceContext[RCNDeviceContextKeyGMPProjectIdentifier] = GMPProjectIdentifier;
  | 
        
        
            | 
            | 
           216 | 
             }
  | 
        
        
            | 
            | 
           217 | 
             return deviceContext;
  | 
        
        
            | 
            | 
           218 | 
           }
  | 
        
        
            | 
            | 
           219 | 
              | 
        
        
            | 
            | 
           220 | 
           BOOL FIRRemoteConfigHasDeviceContextChanged(NSDictionary *deviceContext,
  | 
        
        
            | 
            | 
           221 | 
                                                       NSString *GMPProjectIdentifier) {
  | 
        
        
            | 
            | 
           222 | 
             if (![deviceContext[RCNDeviceContextKeyVersion] isEqual:FIRRemoteConfigAppVersion()]) {
  | 
        
        
            | 
            | 
           223 | 
               return YES;
  | 
        
        
            | 
            | 
           224 | 
             }
  | 
        
        
            | 
            | 
           225 | 
             if (![deviceContext[RCNDeviceContextKeyBuild] isEqual:FIRRemoteConfigAppBuildVersion()]) {
  | 
        
        
            | 
            | 
           226 | 
               return YES;
  | 
        
        
            | 
            | 
           227 | 
             }
  | 
        
        
            | 
            | 
           228 | 
             if (![deviceContext[RCNDeviceContextKeyOSVersion]
  | 
        
        
            | 
            | 
           229 | 
                     isEqual:[GULAppEnvironmentUtil systemVersion]]) {
  | 
        
        
            | 
            | 
           230 | 
               return YES;
  | 
        
        
            | 
            | 
           231 | 
             }
  | 
        
        
            | 
            | 
           232 | 
             if (![deviceContext[RCNDeviceContextKeyDeviceLocale] isEqual:FIRRemoteConfigDeviceLocale()]) {
  | 
        
        
            | 
            | 
           233 | 
               return YES;
  | 
        
        
            | 
            | 
           234 | 
             }
  | 
        
        
            | 
            | 
           235 | 
             // GMP project id is optional.
  | 
        
        
            | 
            | 
           236 | 
             if (deviceContext[RCNDeviceContextKeyGMPProjectIdentifier] &&
  | 
        
        
            | 
            | 
           237 | 
                 ![deviceContext[RCNDeviceContextKeyGMPProjectIdentifier] isEqual:GMPProjectIdentifier]) {
  | 
        
        
            | 
            | 
           238 | 
               return YES;
  | 
        
        
            | 
            | 
           239 | 
             }
  | 
        
        
            | 
            | 
           240 | 
             return NO;
  | 
        
        
            | 
            | 
           241 | 
           }
  |