expo-constants 11.1.0 → 12.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,42 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 12.1.2 — 2021-10-21
14
+
15
+ _This version does not introduce any user-facing changes._
16
+
17
+ ## 12.1.1 — 2021-10-15
18
+
19
+ ### 🛠 Breaking changes
20
+
21
+ - Deprecated `Constants.deviceYearClass`, moved to `expo-device` - `Device.deviceYearClass` ([#14691](https://github.com/expo/expo/pull/14691) by [@EvanBacon](https://github.com/EvanBacon))
22
+ - Deprecated `Constants.platform.ios.model`, moved to `expo-device` - `Device.modelName` ([#14691](https://github.com/expo/expo/pull/14691) by [@EvanBacon](https://github.com/EvanBacon))
23
+
24
+ ### 🎉 New features
25
+
26
+ - Added support for iOS 15.0 devices ([#14640](https://github.com/expo/expo/pull/14640) by [@EvanBacon](https://github.com/EvanBacon))
27
+
28
+ ## 12.1.0 — 2021-10-01
29
+
30
+ ### 🐛 Bug fixes
31
+
32
+ - Don't include fonts from family "System Font" (introduced by iOS 15) ([#14577](https://github.com/expo/expo/pull/14577) by [@brentvatne](https://github.com/brentvatne))
33
+
34
+ ## 12.0.0 — 2021-09-28
35
+
36
+ ### 🛠 Breaking changes
37
+
38
+ - Dropped support for iOS 11.0 ([#14383](https://github.com/expo/expo/pull/14383) by [@cruzach](https://github.com/cruzach))
39
+
40
+ ### 🐛 Bug fixes
41
+
42
+ - Fix building errors from use_frameworks! in Podfile. ([#14523](https://github.com/expo/expo/pull/14523) by [@kudo](https://github.com/kudo))
43
+
44
+ ### 💡 Others
45
+
46
+ - Rewrite Android code to Kotlin. ([#14434](https://github.com/expo/expo/pull/14434) by [@kkafar](https://github.com/kkafar))
47
+ - Updated `@expo/config-plugins` ([#14443](https://github.com/expo/expo/pull/14443) by [@EvanBacon](https://github.com/EvanBacon))
48
+
13
49
  ## 11.1.0 — 2021-09-08
14
50
 
15
51
  ### 🎉 New features
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
3
3
  apply plugin: 'maven'
4
4
 
5
5
  group = 'host.exp.exponent'
6
- version = '11.1.0'
6
+ version = '12.1.2'
7
7
 
8
8
  apply from: "../scripts/get-app-config-android.gradle"
9
9
 
@@ -55,11 +55,15 @@ android {
55
55
  targetCompatibility JavaVersion.VERSION_1_8
56
56
  }
57
57
 
58
+ kotlinOptions {
59
+ jvmTarget = JavaVersion.VERSION_1_8
60
+ }
61
+
58
62
  defaultConfig {
59
63
  minSdkVersion safeExtGet("minSdkVersion", 21)
60
64
  targetSdkVersion safeExtGet("targetSdkVersion", 30)
61
65
  versionCode 33
62
- versionName "11.1.0"
66
+ versionName "12.1.2"
63
67
  }
64
68
  lintOptions {
65
69
  abortOnError false
@@ -0,0 +1,35 @@
1
+ // Copyright 2015-present 650 Industries. All rights reserved.
2
+ package expo.modules.constants
3
+
4
+ import android.content.Context
5
+
6
+ import expo.modules.core.ExportedModule
7
+ import expo.modules.core.ModuleRegistry
8
+ import expo.modules.core.ModuleRegistryDelegate
9
+ import expo.modules.core.Promise
10
+ import expo.modules.interfaces.constants.ConstantsInterface
11
+ import expo.modules.core.interfaces.ExpoMethod
12
+
13
+ class ConstantsModule(
14
+ context: Context,
15
+ private val moduleRegistryDelegate: ModuleRegistryDelegate = ModuleRegistryDelegate()
16
+ ) : ExportedModule(context) {
17
+
18
+ private inline fun <reified T> moduleRegistry() = moduleRegistryDelegate.getFromModuleRegistry<T>()
19
+
20
+ private val constantsService: ConstantsInterface by moduleRegistry()
21
+
22
+ override fun getConstants(): Map<String, Any> = constantsService.constants
23
+
24
+ override fun getName() = "ExponentConstants"
25
+
26
+ override fun onCreate(moduleRegistry: ModuleRegistry) {
27
+ moduleRegistryDelegate.onCreate(moduleRegistry)
28
+ }
29
+
30
+ @ExpoMethod
31
+ fun getWebViewUserAgentAsync(promise: Promise) {
32
+ val userAgent = System.getProperty("http.agent")
33
+ promise.resolve(userAgent)
34
+ }
35
+ }
@@ -0,0 +1,15 @@
1
+ package expo.modules.constants
2
+
3
+ import android.content.Context
4
+
5
+ import expo.modules.core.BasePackage
6
+ import expo.modules.core.interfaces.InternalModule
7
+ import expo.modules.core.ExportedModule
8
+
9
+ class ConstantsPackage : BasePackage() {
10
+ override fun createInternalModules(context: Context): List<InternalModule> =
11
+ listOf(ConstantsService(context))
12
+
13
+ override fun createExportedModules(context: Context): List<ExportedModule> =
14
+ listOf(ConstantsModule(context))
15
+ }
@@ -0,0 +1,134 @@
1
+ package expo.modules.constants
2
+
3
+ import org.apache.commons.io.IOUtils
4
+
5
+ import com.facebook.device.yearclass.YearClass
6
+
7
+ import expo.modules.core.interfaces.InternalModule
8
+ import expo.modules.interfaces.constants.ConstantsInterface
9
+
10
+ import android.os.Build
11
+ import android.util.Log
12
+ import android.content.Context
13
+ import android.content.pm.PackageInfo
14
+ import android.content.pm.PackageManager
15
+
16
+ import java.io.FileNotFoundException
17
+ import java.lang.Exception
18
+ import java.nio.charset.StandardCharsets
19
+ import java.util.*
20
+
21
+ private val TAG = ConstantsService::class.java.simpleName
22
+ private const val CONFIG_FILE_NAME = "app.config"
23
+
24
+ open class ConstantsService(private val context: Context) : InternalModule, ConstantsInterface {
25
+ var statusBarHeightInternal = context.resources.getIdentifier("status_bar_height", "dimen", "android")
26
+ .takeIf { it > 0 }
27
+ ?.let { (context.resources::getDimensionPixelSize)(it) }
28
+ ?.let { pixels -> convertPixelsToDp(pixels.toFloat(), context) }
29
+ ?: 0
30
+
31
+ private val sessionId = UUID.randomUUID().toString()
32
+ private val exponentInstallationId: ExponentInstallationId = ExponentInstallationId(context)
33
+
34
+ enum class ExecutionEnvironment(val string: String) {
35
+ BARE("bare"),
36
+ STANDALONE("standalone"),
37
+ STORE_CLIENT("storeClient");
38
+ }
39
+
40
+ override fun getExportedInterfaces(): List<Class<*>> = listOf(ConstantsInterface::class.java)
41
+
42
+ override fun getConstants(): Map<String, Any?> {
43
+ val constants = mutableMapOf(
44
+ "sessionId" to sessionId,
45
+ "executionEnvironment" to ExecutionEnvironment.BARE.string,
46
+ "statusBarHeight" to statusBarHeightInternal,
47
+ "deviceYearClass" to deviceYearClass,
48
+ "deviceName" to deviceName,
49
+ "isDevice" to isDevice,
50
+ "systemFonts" to systemFonts,
51
+ "systemVersion" to systemVersion,
52
+ "installationId" to getOrCreateInstallationId(),
53
+ "manifest" to appConfig,
54
+ "platform" to mapOf("android" to emptyMap<String, Any>())
55
+ )
56
+
57
+ try {
58
+ val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
59
+ constants["nativeAppVersion"] = pInfo.versionName
60
+
61
+ val versionCode = getLongVersionCode(pInfo).toInt()
62
+ constants["nativeBuildVersion"] = versionCode.toString()
63
+ } catch (e: PackageManager.NameNotFoundException) {
64
+ Log.e(TAG, "Exception: ", e)
65
+ }
66
+
67
+ return constants
68
+ }
69
+
70
+ // Just use package name in vanilla React Native apps.
71
+ override fun getAppScopeKey(): String? = context.packageName
72
+
73
+ override fun getAppOwnership() = "guest"
74
+
75
+ override fun getDeviceName(): String = Build.MODEL
76
+
77
+ override fun getDeviceYearClass() = YearClass.get(context)
78
+
79
+ override fun getIsDevice() = !isRunningOnGenymotion && !isRunningOnStockEmulator
80
+
81
+ override fun getStatusBarHeight() = statusBarHeightInternal
82
+
83
+ override fun getSystemVersion(): String = Build.VERSION.RELEASE
84
+
85
+ open fun getOrCreateInstallationId(): String = exponentInstallationId.getOrCreateUUID()
86
+
87
+ // From https://github.com/dabit3/react-native-fonts
88
+ override fun getSystemFonts() = listOf(
89
+ "normal",
90
+ "notoserif",
91
+ "sans-serif",
92
+ "sans-serif-light",
93
+ "sans-serif-thin",
94
+ "sans-serif-condensed",
95
+ "sans-serif-medium",
96
+ "serif",
97
+ "Roboto",
98
+ "monospace"
99
+ )
100
+
101
+ private val appConfig: String?
102
+ get() {
103
+ try {
104
+ context.assets.open(CONFIG_FILE_NAME).use {
105
+ stream ->
106
+ return IOUtils.toString(stream, StandardCharsets.UTF_8)
107
+ }
108
+ } catch (e: FileNotFoundException) {
109
+ // do nothing, expected in managed apps
110
+ } catch (e: Exception) {
111
+ Log.e(TAG, "Error reading embedded app config", e)
112
+ }
113
+ return null
114
+ }
115
+
116
+ companion object {
117
+ private fun convertPixelsToDp(px: Float, context: Context): Int {
118
+ val resources = context.resources
119
+ val metrics = resources.displayMetrics
120
+ val dp = px / (metrics.densityDpi / 160f)
121
+ return dp.toInt()
122
+ }
123
+
124
+ private val isRunningOnGenymotion: Boolean
125
+ get() = Build.FINGERPRINT.contains("vbox")
126
+
127
+ private val isRunningOnStockEmulator: Boolean
128
+ get() = Build.FINGERPRINT.contains("generic")
129
+
130
+ private fun getLongVersionCode(info: PackageInfo) =
131
+ if (Build.VERSION.SDK_INT >= 28) info.longVersionCode
132
+ else info.versionCode.toLong()
133
+ }
134
+ }
@@ -0,0 +1,112 @@
1
+ package expo.modules.constants
2
+
3
+ import android.util.Log
4
+ import android.content.Context
5
+ import android.content.SharedPreferences
6
+
7
+ import java.util.UUID
8
+ import java.io.File
9
+ import java.io.FileReader
10
+ import java.io.FileWriter
11
+ import java.io.IOException
12
+ import java.io.BufferedReader
13
+ import kotlin.IllegalArgumentException
14
+
15
+ private val TAG = ExponentInstallationId::class.java.simpleName
16
+ private const val PREFERENCES_FILE_NAME = "host.exp.exponent.SharedPreferences"
17
+
18
+ /**
19
+ * An installation ID provider - it solves two purposes:
20
+ * - in installations that have a legacy UUID persisted
21
+ * in shared-across-expo-modules SharedPreferences,
22
+ * migrates the UUID from there to a non-backed-up file,
23
+ * - provides/creates a UUID unique per an installation.
24
+ *
25
+ * Similar class exists in expoview and expo-notifications.
26
+ */
27
+ class ExponentInstallationId internal constructor(private val context: Context) {
28
+ private var uuid: String? = null
29
+
30
+ private val mSharedPreferences: SharedPreferences = context.getSharedPreferences(PREFERENCES_FILE_NAME, Context.MODE_PRIVATE)
31
+
32
+ fun getUUID(): String? {
33
+ // If it has already been cached, return the value.
34
+ if (uuid != null) {
35
+ return uuid
36
+ }
37
+
38
+ // Read from non-backed-up storage
39
+ val uuidFile = nonBackedUpUuidFile
40
+ try {
41
+ FileReader(uuidFile).use { fileReader ->
42
+ BufferedReader(fileReader).use { bufferedReader ->
43
+ // Cache for future calls
44
+ uuid = UUID.fromString(bufferedReader.readLine()).toString()
45
+ }
46
+ }
47
+ } catch (e: Exception) {
48
+ when (e) {
49
+ is IOException, is IllegalArgumentException -> { /* do nothing, try other sources */ }
50
+ else -> throw e
51
+ }
52
+ }
53
+
54
+ // We could have returned inside try clause,
55
+ // but putting it like this here makes it immediately
56
+ // visible.
57
+ if (uuid != null) {
58
+ return uuid
59
+ }
60
+
61
+ // In November 2020 we decided to move installationID (backed by LEGACY_UUID_KEY value) from
62
+ // backed-up SharedPreferences to a non-backed-up text file to fix issues where devices restored
63
+ // from backups have the same installation IDs as the devices where the backup was created.
64
+ val legacyUuid = mSharedPreferences.getString(LEGACY_UUID_KEY, null)
65
+ if (legacyUuid != null) {
66
+ uuid = legacyUuid
67
+
68
+ val uuidHasBeenSuccessfullyMigrated = try {
69
+ FileWriter(uuidFile).use { writer -> writer.write(legacyUuid) }
70
+ true
71
+ } catch (e: IOException) {
72
+ Log.e(TAG, "Error while migrating UUID from legacy storage. $e")
73
+ false
74
+ }
75
+
76
+ // We only remove the value from old storage once it's set and saved in the new storage.
77
+ if (uuidHasBeenSuccessfullyMigrated) {
78
+ mSharedPreferences.edit().remove(LEGACY_UUID_KEY).apply()
79
+ }
80
+ }
81
+
82
+ // Return either value from legacy storage or null
83
+ return uuid
84
+ }
85
+
86
+ fun getOrCreateUUID(): String {
87
+ val uuid = getUUID()
88
+ if (uuid != null) {
89
+ return uuid
90
+ }
91
+
92
+ // We persist the new UUID in "session storage"
93
+ // so that if writing to persistent storage
94
+ // fails subsequent calls to get(orCreate)UUID
95
+ // return the same value.
96
+ this.uuid = UUID.randomUUID().toString()
97
+ try {
98
+ FileWriter(nonBackedUpUuidFile).use { writer -> writer.write(this.uuid) }
99
+ } catch (e: IOException) {
100
+ Log.e(TAG, "Error while writing new UUID. $e")
101
+ }
102
+ return this.uuid!!
103
+ }
104
+
105
+ private val nonBackedUpUuidFile: File
106
+ get() = File(context.noBackupFilesDir, UUID_FILE_NAME)
107
+
108
+ companion object {
109
+ const val LEGACY_UUID_KEY = "uuid"
110
+ const val UUID_FILE_NAME = "expo_installation_uuid.txt"
111
+ }
112
+ }
@@ -39,6 +39,8 @@ if (!rawManifest && ExponentConstants && ExponentConstants.manifest) {
39
39
  }
40
40
  }
41
41
  const { name, appOwnership, ...nativeConstants } = (ExponentConstants || {});
42
+ let warnedAboutDeviceYearClass = false;
43
+ let warnedAboutIosModel = false;
42
44
  let warnedAboutInstallationId = false;
43
45
  let warnedAboutDeviceId = false;
44
46
  let warnedAboutLinkingUrl = false;
@@ -47,6 +49,14 @@ const constants = {
47
49
  // Ensure this is null in bare workflow
48
50
  appOwnership: appOwnership ?? null,
49
51
  // Deprecated fields
52
+ get deviceYearClass() {
53
+ if (!warnedAboutDeviceYearClass) {
54
+ console.warn(`Constants.deviceYearClass has been deprecated in favor of expo-device's Device.deviceYearClass property. This API will be removed in SDK 45.`);
55
+ warnedAboutDeviceYearClass = true;
56
+ }
57
+ return nativeConstants.deviceYearClass;
58
+ },
59
+ // Deprecated fields
50
60
  get installationId() {
51
61
  if (!warnedAboutInstallationId) {
52
62
  console.warn(`Constants.installationId has been deprecated in favor of generating and storing your own ID. Implement it using expo-application's androidId on Android and a storage API such as expo-secure-store on iOS and localStorage on the web. This API will be removed in SDK 44.`);
@@ -110,6 +120,21 @@ const constants = {
110
120
  rawManifest = value;
111
121
  },
112
122
  };
123
+ // Add deprecation warning for `platform.ios.model`
124
+ if (constants?.platform?.ios) {
125
+ const originalModel = nativeConstants.platform.ios.model;
126
+ Object.defineProperty(constants.platform.ios, 'model', {
127
+ get() {
128
+ if (!warnedAboutIosModel) {
129
+ console.warn(`Constants.platform.ios.model has been deprecated in favor of expo-device's Device.modelName property. This API will be removed in SDK 45.`);
130
+ warnedAboutIosModel = true;
131
+ }
132
+ return originalModel;
133
+ },
134
+ // Prevent the warning from being thrown, or the value from being used when the user interacts with the entire object.
135
+ enumerable: false,
136
+ });
137
+ }
113
138
  function isAppManifest(manifest) {
114
139
  return !isManifest(manifest);
115
140
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Constants.js","sourceRoot":"","sources":["../src/Constants.ts"],"names":[],"mappings":"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","sourcesContent":["import { CodedError, NativeModulesProxy } from 'expo-modules-core';\nimport { Platform, NativeModules } from 'react-native';\n\nimport {\n AndroidManifest,\n AppManifest,\n AppOwnership,\n Constants,\n ExecutionEnvironment,\n IOSManifest,\n Manifest,\n NativeConstants,\n PlatformManifest,\n UserInterfaceIdiom,\n WebManifest,\n} from './Constants.types';\nimport ExponentConstants from './ExponentConstants';\n\nexport {\n AndroidManifest,\n AppOwnership,\n Constants,\n ExecutionEnvironment,\n IOSManifest,\n NativeConstants,\n PlatformManifest,\n UserInterfaceIdiom,\n WebManifest,\n};\n\nif (!ExponentConstants) {\n console.warn(\n \"No native ExponentConstants module found, are you sure the expo-constants's module is linked properly?\"\n );\n}\n\nlet rawManifest: AppManifest | Manifest | null = null;\n// If expo-updates defines a non-empty manifest, prefer that one\nif (NativeModulesProxy.ExpoUpdates) {\n let updatesManifest;\n if (NativeModulesProxy.ExpoUpdates.manifest) {\n updatesManifest = NativeModulesProxy.ExpoUpdates.manifest;\n } else if (NativeModulesProxy.ExpoUpdates.manifestString) {\n updatesManifest = JSON.parse(NativeModulesProxy.ExpoUpdates.manifestString);\n }\n if (updatesManifest && Object.keys(updatesManifest).length > 0) {\n rawManifest = updatesManifest;\n }\n}\n\n// If dev-launcher defines a non-empty manifest, prefer that one\nif (NativeModules.EXDevLauncher) {\n let devLauncherManifest;\n if (NativeModules.EXDevLauncher.manifestString) {\n devLauncherManifest = JSON.parse(NativeModules.EXDevLauncher.manifestString);\n }\n\n if (devLauncherManifest && Object.keys(devLauncherManifest).length > 0) {\n rawManifest = devLauncherManifest;\n }\n}\n\n// Fall back to ExponentConstants.manifest if we don't have one from Updates\nif (!rawManifest && ExponentConstants && ExponentConstants.manifest) {\n rawManifest = ExponentConstants.manifest;\n // On Android we pass the manifest in JSON form so this step is necessary\n if (typeof rawManifest === 'string') {\n rawManifest = JSON.parse(rawManifest);\n }\n}\n\nconst { name, appOwnership, ...nativeConstants } = (ExponentConstants || {}) as any;\n\nlet warnedAboutInstallationId = false;\nlet warnedAboutDeviceId = false;\nlet warnedAboutLinkingUrl = false;\n\nconst constants = {\n ...nativeConstants,\n // Ensure this is null in bare workflow\n appOwnership: appOwnership ?? null,\n // Deprecated fields\n get installationId() {\n if (!warnedAboutInstallationId) {\n console.warn(\n `Constants.installationId has been deprecated in favor of generating and storing your own ID. Implement it using expo-application's androidId on Android and a storage API such as expo-secure-store on iOS and localStorage on the web. This API will be removed in SDK 44.`\n );\n warnedAboutInstallationId = true;\n }\n return nativeConstants.installationId;\n },\n // Legacy aliases\n get deviceId() {\n if (!warnedAboutDeviceId) {\n console.warn(\n `Constants.deviceId has been deprecated in favor of generating and storing your own ID. This API will be removed in SDK 44.`\n );\n warnedAboutDeviceId = true;\n }\n return nativeConstants.installationId;\n },\n get linkingUrl() {\n if (!warnedAboutLinkingUrl) {\n console.warn(\n `Constants.linkingUrl has been renamed to Constants.linkingUri. Consider using the Linking API directly. Constants.linkingUrl will be removed in SDK 44.`\n );\n warnedAboutLinkingUrl = true;\n }\n return nativeConstants.linkingUri;\n },\n get manifest(): AppManifest | null {\n const maybeManifest = getManifest();\n if (!maybeManifest || !isAppManifest(maybeManifest)) {\n return null;\n }\n return maybeManifest;\n },\n get manifest2(): Manifest | null {\n const maybeManifest = getManifest();\n if (!maybeManifest || !isManifest(maybeManifest)) {\n return null;\n }\n return maybeManifest;\n },\n /**\n * Use `manifest` property by default.\n * This property is only used for internal purposes.\n * It behaves similarly to the original one, but suppresses warning upon no manifest available.\n * `expo-asset` uses it to prevent users from seeing mentioned warning.\n */\n get __unsafeNoWarnManifest(): AppManifest | Manifest | null {\n const maybeManifest = getManifest(true);\n if (!maybeManifest || !isAppManifest(maybeManifest)) {\n return null;\n }\n return maybeManifest;\n },\n get __unsafeNoWarnManifest2(): Manifest | Manifest | null {\n const maybeManifest = getManifest(true);\n if (!maybeManifest || !isManifest(maybeManifest)) {\n return null;\n }\n return maybeManifest;\n },\n get __rawManifest_TEST(): AppManifest | Manifest | null {\n return rawManifest;\n },\n set __rawManifest_TEST(value: AppManifest | Manifest | null) {\n rawManifest = value;\n },\n} as Constants;\n\nfunction isAppManifest(manifest: AppManifest | Manifest): manifest is AppManifest {\n return !isManifest(manifest);\n}\n\nfunction isManifest(manifest: AppManifest | Manifest): manifest is Manifest {\n return 'metadata' in manifest;\n}\n\nfunction getManifest(suppressWarning = false): AppManifest | Manifest | null {\n if (!rawManifest) {\n const invalidManifestType = rawManifest === null ? 'null' : 'undefined';\n if (\n nativeConstants.executionEnvironment === ExecutionEnvironment.Bare &&\n Platform.OS !== 'web'\n ) {\n if (!suppressWarning) {\n console.warn(\n `Constants.manifest is ${invalidManifestType} because the embedded app.config could not be read. Ensure that you have installed the expo-constants build scripts if you need to read from Constants.manifest.`\n );\n }\n } else if (\n nativeConstants.executionEnvironment === ExecutionEnvironment.StoreClient ||\n nativeConstants.executionEnvironment === ExecutionEnvironment.Standalone\n ) {\n // If we somehow get here, this is a truly exceptional state to be in.\n // Constants.manifest should *always* be defined in those contexts.\n throw new CodedError(\n 'ERR_CONSTANTS_MANIFEST_UNAVAILABLE',\n `Constants.manifest is ${invalidManifestType}, must be an object.`\n );\n }\n }\n return rawManifest;\n}\n\nexport default constants as Constants;\n"]}
1
+ {"version":3,"file":"Constants.js","sourceRoot":"","sources":["../src/Constants.ts"],"names":[],"mappings":"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","sourcesContent":["import { CodedError, NativeModulesProxy } from 'expo-modules-core';\nimport { Platform, NativeModules } from 'react-native';\n\nimport {\n AndroidManifest,\n AppManifest,\n AppOwnership,\n Constants,\n ExecutionEnvironment,\n IOSManifest,\n Manifest,\n NativeConstants,\n PlatformManifest,\n UserInterfaceIdiom,\n WebManifest,\n} from './Constants.types';\nimport ExponentConstants from './ExponentConstants';\n\nexport {\n AndroidManifest,\n AppOwnership,\n Constants,\n ExecutionEnvironment,\n IOSManifest,\n NativeConstants,\n PlatformManifest,\n UserInterfaceIdiom,\n WebManifest,\n};\n\nif (!ExponentConstants) {\n console.warn(\n \"No native ExponentConstants module found, are you sure the expo-constants's module is linked properly?\"\n );\n}\n\nlet rawManifest: AppManifest | Manifest | null = null;\n// If expo-updates defines a non-empty manifest, prefer that one\nif (NativeModulesProxy.ExpoUpdates) {\n let updatesManifest;\n if (NativeModulesProxy.ExpoUpdates.manifest) {\n updatesManifest = NativeModulesProxy.ExpoUpdates.manifest;\n } else if (NativeModulesProxy.ExpoUpdates.manifestString) {\n updatesManifest = JSON.parse(NativeModulesProxy.ExpoUpdates.manifestString);\n }\n if (updatesManifest && Object.keys(updatesManifest).length > 0) {\n rawManifest = updatesManifest;\n }\n}\n\n// If dev-launcher defines a non-empty manifest, prefer that one\nif (NativeModules.EXDevLauncher) {\n let devLauncherManifest;\n if (NativeModules.EXDevLauncher.manifestString) {\n devLauncherManifest = JSON.parse(NativeModules.EXDevLauncher.manifestString);\n }\n\n if (devLauncherManifest && Object.keys(devLauncherManifest).length > 0) {\n rawManifest = devLauncherManifest;\n }\n}\n\n// Fall back to ExponentConstants.manifest if we don't have one from Updates\nif (!rawManifest && ExponentConstants && ExponentConstants.manifest) {\n rawManifest = ExponentConstants.manifest;\n // On Android we pass the manifest in JSON form so this step is necessary\n if (typeof rawManifest === 'string') {\n rawManifest = JSON.parse(rawManifest);\n }\n}\n\nconst { name, appOwnership, ...nativeConstants } = (ExponentConstants || {}) as any;\n\nlet warnedAboutDeviceYearClass = false;\nlet warnedAboutIosModel = false;\nlet warnedAboutInstallationId = false;\nlet warnedAboutDeviceId = false;\nlet warnedAboutLinkingUrl = false;\n\nconst constants = {\n ...nativeConstants,\n // Ensure this is null in bare workflow\n appOwnership: appOwnership ?? null,\n // Deprecated fields\n get deviceYearClass() {\n if (!warnedAboutDeviceYearClass) {\n console.warn(\n `Constants.deviceYearClass has been deprecated in favor of expo-device's Device.deviceYearClass property. This API will be removed in SDK 45.`\n );\n warnedAboutDeviceYearClass = true;\n }\n return nativeConstants.deviceYearClass;\n },\n // Deprecated fields\n get installationId() {\n if (!warnedAboutInstallationId) {\n console.warn(\n `Constants.installationId has been deprecated in favor of generating and storing your own ID. Implement it using expo-application's androidId on Android and a storage API such as expo-secure-store on iOS and localStorage on the web. This API will be removed in SDK 44.`\n );\n warnedAboutInstallationId = true;\n }\n return nativeConstants.installationId;\n },\n // Legacy aliases\n get deviceId() {\n if (!warnedAboutDeviceId) {\n console.warn(\n `Constants.deviceId has been deprecated in favor of generating and storing your own ID. This API will be removed in SDK 44.`\n );\n warnedAboutDeviceId = true;\n }\n return nativeConstants.installationId;\n },\n get linkingUrl() {\n if (!warnedAboutLinkingUrl) {\n console.warn(\n `Constants.linkingUrl has been renamed to Constants.linkingUri. Consider using the Linking API directly. Constants.linkingUrl will be removed in SDK 44.`\n );\n warnedAboutLinkingUrl = true;\n }\n return nativeConstants.linkingUri;\n },\n get manifest(): AppManifest | null {\n const maybeManifest = getManifest();\n if (!maybeManifest || !isAppManifest(maybeManifest)) {\n return null;\n }\n return maybeManifest;\n },\n get manifest2(): Manifest | null {\n const maybeManifest = getManifest();\n if (!maybeManifest || !isManifest(maybeManifest)) {\n return null;\n }\n return maybeManifest;\n },\n /**\n * Use `manifest` property by default.\n * This property is only used for internal purposes.\n * It behaves similarly to the original one, but suppresses warning upon no manifest available.\n * `expo-asset` uses it to prevent users from seeing mentioned warning.\n */\n get __unsafeNoWarnManifest(): AppManifest | Manifest | null {\n const maybeManifest = getManifest(true);\n if (!maybeManifest || !isAppManifest(maybeManifest)) {\n return null;\n }\n return maybeManifest;\n },\n get __unsafeNoWarnManifest2(): Manifest | Manifest | null {\n const maybeManifest = getManifest(true);\n if (!maybeManifest || !isManifest(maybeManifest)) {\n return null;\n }\n return maybeManifest;\n },\n get __rawManifest_TEST(): AppManifest | Manifest | null {\n return rawManifest;\n },\n set __rawManifest_TEST(value: AppManifest | Manifest | null) {\n rawManifest = value;\n },\n} as Constants;\n\n// Add deprecation warning for `platform.ios.model`\nif (constants?.platform?.ios) {\n const originalModel = nativeConstants.platform.ios.model;\n Object.defineProperty(constants.platform.ios, 'model', {\n get() {\n if (!warnedAboutIosModel) {\n console.warn(\n `Constants.platform.ios.model has been deprecated in favor of expo-device's Device.modelName property. This API will be removed in SDK 45.`\n );\n warnedAboutIosModel = true;\n }\n return originalModel;\n },\n // Prevent the warning from being thrown, or the value from being used when the user interacts with the entire object.\n enumerable: false,\n });\n}\n\nfunction isAppManifest(manifest: AppManifest | Manifest): manifest is AppManifest {\n return !isManifest(manifest);\n}\n\nfunction isManifest(manifest: AppManifest | Manifest): manifest is Manifest {\n return 'metadata' in manifest;\n}\n\nfunction getManifest(suppressWarning = false): AppManifest | Manifest | null {\n if (!rawManifest) {\n const invalidManifestType = rawManifest === null ? 'null' : 'undefined';\n if (\n nativeConstants.executionEnvironment === ExecutionEnvironment.Bare &&\n Platform.OS !== 'web'\n ) {\n if (!suppressWarning) {\n console.warn(\n `Constants.manifest is ${invalidManifestType} because the embedded app.config could not be read. Ensure that you have installed the expo-constants build scripts if you need to read from Constants.manifest.`\n );\n }\n } else if (\n nativeConstants.executionEnvironment === ExecutionEnvironment.StoreClient ||\n nativeConstants.executionEnvironment === ExecutionEnvironment.Standalone\n ) {\n // If we somehow get here, this is a truly exceptional state to be in.\n // Constants.manifest should *always* be defined in those contexts.\n throw new CodedError(\n 'ERR_CONSTANTS_MANIFEST_UNAVAILABLE',\n `Constants.manifest is ${invalidManifestType}, must be an object.`\n );\n }\n }\n return rawManifest;\n}\n\nexport default constants as Constants;\n"]}
@@ -17,6 +17,9 @@ export declare enum UserInterfaceIdiom {
17
17
  export interface IOSManifest {
18
18
  buildNumber: string;
19
19
  platform: string;
20
+ /**
21
+ * @deprecated Moved to `expo-device` - `Device.modelName`
22
+ */
20
23
  model: string | null;
21
24
  userInterfaceIdiom: UserInterfaceIdiom;
22
25
  systemVersion: string;
@@ -133,6 +136,9 @@ export interface NativeConstants {
133
136
  appOwnership: AppOwnership | null;
134
137
  debugMode: boolean;
135
138
  deviceName?: string;
139
+ /**
140
+ * @deprecated Moved to `expo-device` - `Device.deviceYearClass`
141
+ */
136
142
  deviceYearClass: number | null;
137
143
  executionEnvironment: ExecutionEnvironment;
138
144
  experienceUrl: string;
@@ -1 +1 @@
1
- {"version":3,"file":"Constants.types.js","sourceRoot":"","sources":["../src/Constants.types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,YAIX;AAJD,WAAY,YAAY;IACtB,yCAAyB,CAAA;IACzB,6BAAa,CAAA;IACb,+BAAe,CAAA;AACjB,CAAC,EAJW,YAAY,KAAZ,YAAY,QAIvB;AAED,MAAM,CAAN,IAAY,oBAIX;AAJD,WAAY,oBAAoB;IAC9B,qCAAa,CAAA;IACb,iDAAyB,CAAA;IACzB,mDAA2B,CAAA;AAC7B,CAAC,EAJW,oBAAoB,KAApB,oBAAoB,QAI/B;AAED,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,yCAAmB,CAAA;IACnB,uCAAiB,CAAA;IACjB,iDAA2B,CAAA;AAC7B,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B","sourcesContent":["import { ExpoConfig } from '@expo/config-types';\n\nexport enum AppOwnership {\n Standalone = 'standalone',\n Expo = 'expo',\n Guest = 'guest',\n}\n\nexport enum ExecutionEnvironment {\n Bare = 'bare',\n Standalone = 'standalone',\n StoreClient = 'storeClient',\n}\n\nexport enum UserInterfaceIdiom {\n Handset = 'handset',\n Tablet = 'tablet',\n Unsupported = 'unsupported',\n}\n\nexport interface IOSManifest {\n buildNumber: string;\n platform: string;\n model: string | null;\n userInterfaceIdiom: UserInterfaceIdiom;\n systemVersion: string;\n [key: string]: any;\n}\n\nexport interface AndroidManifest {\n versionCode: number;\n [key: string]: any;\n}\n\nexport interface WebManifest {\n [key: string]: any;\n}\n\nexport interface ManifestAsset {\n url: string;\n}\n\n/**\n * A modern manifest.\n */\nexport type Manifest = {\n id: string;\n createdAt: string;\n runtimeVersion: string;\n launchAsset: ManifestAsset;\n assets: ManifestAsset[];\n metadata: object;\n extra?: ClientScopingConfig & {\n expoClient?: ExpoClientConfig;\n expoGo?: ExpoGoConfig;\n eas?: EASConfig;\n };\n};\n\nexport type EASConfig = {\n /**\n * The ID for this project if it's using EAS. UUID. This value will not change when a project is transferred\n * between accounts or renamed.\n */\n projectId?: string;\n};\n\nexport type ClientScopingConfig = {\n /**\n * An opaque unique string for scoping client-side data to this project. This value\n * will not change when a project is transferred between accounts or renamed.\n */\n scopeKey?: string;\n};\n\nexport type ExpoGoConfig = {\n mainModuleName?: string;\n debuggerHost?: string;\n logUrl?: string;\n developer?: {\n tool?: string;\n [key: string]: any;\n };\n packagerOpts?: {\n hostType?: string;\n dev?: boolean;\n strict?: boolean;\n minify?: boolean;\n urlType?: string;\n urlRandomness?: string;\n lanType?: string;\n [key: string]: any;\n };\n};\n\nexport type ExpoClientConfig = ExpoConfig & {\n /** Published Apps Only */\n releaseId?: string;\n revisionId?: string;\n releaseChannel?: string;\n bundleUrl: string;\n hostUri?: string;\n publishedTime?: string;\n\n /**\n * The Expo account name and slug for this project.\n * @deprecated - Prefer `projectId` or `originalFullName` instead for identification and `scopeKey` for\n * scoping due to immutability.\n */\n id?: string;\n\n /**\n * The original Expo account name and slug for this project. Formatted like `@username/slug`.\n * When unauthenticated, the username is `@anonymous`. For published projects, this value\n * will not change when a project is transferred between accounts or renamed.\n */\n originalFullName?: string;\n\n /**\n * The Expo account name and slug used for display purposes. Formatted like `@username/slug`.\n * When unauthenticated, the username is `@anonymous`. For published projects, this value\n * may change when a project is transferred between accounts or renamed.\n */\n currentFullName?: string;\n};\n\n/**\n * A classic manifest https://docs.expo.io/guides/how-expo-works/#expo-manifest\n */\nexport type AppManifest = ExpoClientConfig &\n ExpoGoConfig &\n EASConfig &\n ClientScopingConfig & {\n [key: string]: any;\n };\n\nexport interface PlatformManifest {\n ios?: IOSManifest;\n android?: AndroidManifest;\n web?: WebManifest;\n detach?: {\n scheme?: string;\n [key: string]: any;\n };\n logUrl?: string;\n scheme?: string;\n hostUri?: string;\n developer?: string;\n [key: string]: any;\n}\n\nexport interface NativeConstants {\n name: 'ExponentConstants';\n appOwnership: AppOwnership | null;\n debugMode: boolean;\n deviceName?: string;\n deviceYearClass: number | null;\n executionEnvironment: ExecutionEnvironment;\n experienceUrl: string;\n // only nullable on web\n expoRuntimeVersion: string | null;\n /**\n * The version string of the Expo client currently running.\n * Returns `null` in bare workflow and web.\n */\n expoVersion: string | null;\n isDetached?: boolean;\n intentUri?: string;\n /**\n * @deprecated Constants.installationId is deprecated in favor of generating your own ID and\n * storing it. This API will be removed in SDK 44.\n */\n installationId: string;\n isDevice: boolean;\n isHeadless: boolean;\n linkingUri: string;\n nativeAppVersion: string | null;\n nativeBuildVersion: string | null;\n /**\n * Classic manifest for Expo apps using classic updates.\n * Returns `null` in bare workflow and when `manifest2` is non-null.\n */\n manifest: AppManifest | null;\n /**\n * New manifest for Expo apps using modern Expo Updates.\n * Returns `null` in bare workflow and when `manifest` is non-null.\n */\n manifest2: Manifest | null;\n sessionId: string;\n statusBarHeight: number;\n systemFonts: string[];\n systemVersion?: number;\n platform?: PlatformManifest;\n [key: string]: any;\n\n getWebViewUserAgentAsync: () => Promise<string | null>;\n}\n\nexport interface Constants extends NativeConstants {\n /**\n * @deprecated Constants.deviceId is deprecated in favor of generating your own ID and storing it.\n * This API will be removed in SDK 44.\n */\n deviceId?: string;\n /**\n * @deprecated Constants.linkingUrl has been renamed to Constants.linkingUri. Consider using the\n * Linking API directly. Constants.linkingUrl will be removed in SDK 44.\n */\n linkingUrl?: string;\n /**\n * @warning do not use this property. Use `manifest` by default.\n *\n * In certain cases accessing manifest via this property\n * suppresses important warning about missing manifest.\n */\n __unsafeNoWarnManifest?: AppManifest;\n /**\n * @warning do not use this property. Use `manifest2` by default.\n *\n * In certain cases accessing manifest via this property\n * suppresses important warning about missing manifest.\n */\n __unsafeNoWarnManifest2?: Manifest;\n}\n"]}
1
+ {"version":3,"file":"Constants.types.js","sourceRoot":"","sources":["../src/Constants.types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAN,IAAY,YAIX;AAJD,WAAY,YAAY;IACtB,yCAAyB,CAAA;IACzB,6BAAa,CAAA;IACb,+BAAe,CAAA;AACjB,CAAC,EAJW,YAAY,KAAZ,YAAY,QAIvB;AAED,MAAM,CAAN,IAAY,oBAIX;AAJD,WAAY,oBAAoB;IAC9B,qCAAa,CAAA;IACb,iDAAyB,CAAA;IACzB,mDAA2B,CAAA;AAC7B,CAAC,EAJW,oBAAoB,KAApB,oBAAoB,QAI/B;AAED,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,yCAAmB,CAAA;IACnB,uCAAiB,CAAA;IACjB,iDAA2B,CAAA;AAC7B,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B","sourcesContent":["import { ExpoConfig } from '@expo/config-types';\n\nexport enum AppOwnership {\n Standalone = 'standalone',\n Expo = 'expo',\n Guest = 'guest',\n}\n\nexport enum ExecutionEnvironment {\n Bare = 'bare',\n Standalone = 'standalone',\n StoreClient = 'storeClient',\n}\n\nexport enum UserInterfaceIdiom {\n Handset = 'handset',\n Tablet = 'tablet',\n Unsupported = 'unsupported',\n}\n\nexport interface IOSManifest {\n buildNumber: string;\n platform: string;\n /**\n * @deprecated Moved to `expo-device` - `Device.modelName`\n */\n model: string | null;\n userInterfaceIdiom: UserInterfaceIdiom;\n systemVersion: string;\n [key: string]: any;\n}\n\nexport interface AndroidManifest {\n versionCode: number;\n [key: string]: any;\n}\n\nexport interface WebManifest {\n [key: string]: any;\n}\n\nexport interface ManifestAsset {\n url: string;\n}\n\n/**\n * A modern manifest.\n */\nexport type Manifest = {\n id: string;\n createdAt: string;\n runtimeVersion: string;\n launchAsset: ManifestAsset;\n assets: ManifestAsset[];\n metadata: object;\n extra?: ClientScopingConfig & {\n expoClient?: ExpoClientConfig;\n expoGo?: ExpoGoConfig;\n eas?: EASConfig;\n };\n};\n\nexport type EASConfig = {\n /**\n * The ID for this project if it's using EAS. UUID. This value will not change when a project is transferred\n * between accounts or renamed.\n */\n projectId?: string;\n};\n\nexport type ClientScopingConfig = {\n /**\n * An opaque unique string for scoping client-side data to this project. This value\n * will not change when a project is transferred between accounts or renamed.\n */\n scopeKey?: string;\n};\n\nexport type ExpoGoConfig = {\n mainModuleName?: string;\n debuggerHost?: string;\n logUrl?: string;\n developer?: {\n tool?: string;\n [key: string]: any;\n };\n packagerOpts?: {\n hostType?: string;\n dev?: boolean;\n strict?: boolean;\n minify?: boolean;\n urlType?: string;\n urlRandomness?: string;\n lanType?: string;\n [key: string]: any;\n };\n};\n\nexport type ExpoClientConfig = ExpoConfig & {\n /** Published Apps Only */\n releaseId?: string;\n revisionId?: string;\n releaseChannel?: string;\n bundleUrl: string;\n hostUri?: string;\n publishedTime?: string;\n\n /**\n * The Expo account name and slug for this project.\n * @deprecated - Prefer `projectId` or `originalFullName` instead for identification and `scopeKey` for\n * scoping due to immutability.\n */\n id?: string;\n\n /**\n * The original Expo account name and slug for this project. Formatted like `@username/slug`.\n * When unauthenticated, the username is `@anonymous`. For published projects, this value\n * will not change when a project is transferred between accounts or renamed.\n */\n originalFullName?: string;\n\n /**\n * The Expo account name and slug used for display purposes. Formatted like `@username/slug`.\n * When unauthenticated, the username is `@anonymous`. For published projects, this value\n * may change when a project is transferred between accounts or renamed.\n */\n currentFullName?: string;\n};\n\n/**\n * A classic manifest https://docs.expo.io/guides/how-expo-works/#expo-manifest\n */\nexport type AppManifest = ExpoClientConfig &\n ExpoGoConfig &\n EASConfig &\n ClientScopingConfig & {\n [key: string]: any;\n };\n\nexport interface PlatformManifest {\n ios?: IOSManifest;\n android?: AndroidManifest;\n web?: WebManifest;\n detach?: {\n scheme?: string;\n [key: string]: any;\n };\n logUrl?: string;\n scheme?: string;\n hostUri?: string;\n developer?: string;\n [key: string]: any;\n}\n\nexport interface NativeConstants {\n name: 'ExponentConstants';\n appOwnership: AppOwnership | null;\n debugMode: boolean;\n deviceName?: string;\n /**\n * @deprecated Moved to `expo-device` - `Device.deviceYearClass`\n */\n deviceYearClass: number | null;\n executionEnvironment: ExecutionEnvironment;\n experienceUrl: string;\n // only nullable on web\n expoRuntimeVersion: string | null;\n /**\n * The version string of the Expo client currently running.\n * Returns `null` in bare workflow and web.\n */\n expoVersion: string | null;\n isDetached?: boolean;\n intentUri?: string;\n /**\n * @deprecated Constants.installationId is deprecated in favor of generating your own ID and\n * storing it. This API will be removed in SDK 44.\n */\n installationId: string;\n isDevice: boolean;\n isHeadless: boolean;\n linkingUri: string;\n nativeAppVersion: string | null;\n nativeBuildVersion: string | null;\n /**\n * Classic manifest for Expo apps using classic updates.\n * Returns `null` in bare workflow and when `manifest2` is non-null.\n */\n manifest: AppManifest | null;\n /**\n * New manifest for Expo apps using modern Expo Updates.\n * Returns `null` in bare workflow and when `manifest` is non-null.\n */\n manifest2: Manifest | null;\n sessionId: string;\n statusBarHeight: number;\n systemFonts: string[];\n systemVersion?: number;\n platform?: PlatformManifest;\n [key: string]: any;\n\n getWebViewUserAgentAsync: () => Promise<string | null>;\n}\n\nexport interface Constants extends NativeConstants {\n /**\n * @deprecated Constants.deviceId is deprecated in favor of generating your own ID and storing it.\n * This API will be removed in SDK 44.\n */\n deviceId?: string;\n /**\n * @deprecated Constants.linkingUrl has been renamed to Constants.linkingUri. Consider using the\n * Linking API directly. Constants.linkingUrl will be removed in SDK 44.\n */\n linkingUrl?: string;\n /**\n * @warning do not use this property. Use `manifest` by default.\n *\n * In certain cases accessing manifest via this property\n * suppresses important warning about missing manifest.\n */\n __unsafeNoWarnManifest?: AppManifest;\n /**\n * @warning do not use this property. Use `manifest2` by default.\n *\n * In certain cases accessing manifest via this property\n * suppresses important warning about missing manifest.\n */\n __unsafeNoWarnManifest2?: Manifest;\n}\n"]}
@@ -130,10 +130,20 @@ EX_REGISTER_MODULE();
130
130
  NSArray<NSString *> *familyNames = [UIFont familyNames];
131
131
  NSMutableArray<NSString *> *fontNames = [NSMutableArray array];
132
132
  for (NSString *familyName in familyNames) {
133
- [fontNames addObject:familyName];
134
- [fontNames addObjectsFromArray:[UIFont fontNamesForFamilyName:familyName]];
133
+ // "System Font" is added to [UIFont familyNames] in iOS 15, and the font names that
134
+ // correspond with it are dot prefixed .SFUI-* fonts which log the following warning
135
+ // when passed in to [UIFont fontNamesForFamilyName:name]:
136
+ // CoreText note: Client requested name “.SFUI-HeavyItalic”, it will get TimesNewRomanPSMT rather than the intended font.
137
+ // All system UI font access should be through proper APIs such as CTFontCreateUIFontForLanguage() or +[UIFont systemFontOfSize:]
138
+ //
139
+ if (![familyName isEqualToString:@"System Font"]) {
140
+ [fontNames addObject:familyName];
141
+ [fontNames addObjectsFromArray:[UIFont fontNamesForFamilyName:familyName]];
142
+ }
135
143
  }
136
- return [fontNames sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
144
+
145
+ // Remove duplciates and sort alphabetically
146
+ return [[[NSSet setWithArray:fontNames] allObjects] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
137
147
  }
138
148
 
139
149
  # pragma mark - device info
@@ -187,21 +197,13 @@ EX_REGISTER_MODULE();
187
197
  @"Watch6,4": @"Apple Watch Series 6",
188
198
 
189
199
  // iPhone
190
- @"iPhone1,1": @"iPhone",
191
- @"iPhone1,2": @"iPhone 3G",
192
- @"iPhone2,1": @"iPhone 3GS",
193
- @"iPhone3,1": @"iPhone 4",
194
- @"iPhone3,2": @"iPhone 4",
195
- @"iPhone3,3": @"iPhone 4 (CDMA)",
196
- @"iPhone4,1": @"iPhone 4S",
197
- @"iPhone5,1": @"iPhone 5 (GSM)",
198
- @"iPhone5,2": @"iPhone 5 (GSM+CDMA)",
199
- @"iPhone5,3": @"iPhone 5C (GSM)",
200
- @"iPhone5,4": @"iPhone 5C (GSM+CDMA)",
200
+ // iOS 12+
201
201
  @"iPhone6,1": @"iPhone 5S (GSM)",
202
202
  @"iPhone6,2": @"iPhone 5S (GSM+CDMA)",
203
203
  @"iPhone7,1": @"iPhone 6 Plus",
204
204
  @"iPhone7,2": @"iPhone 6",
205
+
206
+ // iOS 13+
205
207
  @"iPhone8,1": @"iPhone 6s",
206
208
  @"iPhone8,2": @"iPhone 6s Plus",
207
209
  @"iPhone8,4": @"iPhone SE",
@@ -228,6 +230,11 @@ EX_REGISTER_MODULE();
228
230
  @"iPhone13,3": @"iPhone 12 Pro",
229
231
  @"iPhone13,4": @"iPhone 12 Pro Max",
230
232
 
233
+ @"iPhone14,2": @"iPhone 13 Pro",
234
+ @"iPhone14,3": @"iPhone 13 Pro Max",
235
+ @"iPhone14,4": @"iPhone 13 Mini",
236
+ @"iPhone14,5": @"iPhone 13",
237
+
231
238
  // iPod
232
239
  @"iPod1,1": @"iPod Touch",
233
240
  @"iPod2,1": @"iPod Touch 2G",
@@ -287,11 +294,25 @@ EX_REGISTER_MODULE();
287
294
  @"iPad8,6": @"iPad Pro 12.9-inch (3rd generation)",
288
295
  @"iPad8,7": @"iPad Pro 12.9-inch (3rd generation)",
289
296
  @"iPad8,8": @"iPad Pro 12.9-inch (3rd generation)",
290
- @"iPad11,1": @"iPad Mini 5",
291
- @"iPad11,2": @"iPad Mini 5",
292
- @"iPad11,3": @"iPad Air (3rd generation)",
297
+ @"iPad11,1": @"iPad Mini (5th generation) (WiFi)",
298
+ @"iPad11,2": @"iPad Mini (5th generation)",
299
+ @"iPad11,3": @"iPad Air (3rd generation) (WiFi)",
293
300
  @"iPad11,4": @"iPad Air (3rd generation)",
294
301
 
302
+ @"iPad11,6": @"iPad (8th generation)",
303
+ @"iPad11,7": @"iPad (8th generation)",
304
+ @"iPad13,1": @"iPad Air (4th generation) (WiFi)",
305
+ @"iPad13,2": @"iPad Air (4th generation) (WiFi+Cellular)",
306
+ @"iPad13,4": @"iPad Pro 11 inch (3th generation)",
307
+ @"iPad13,5": @"iPad Pro 11 inch (3th generation)",
308
+ @"iPad13,6": @"iPad Pro 11 inch (3th generation)",
309
+ @"iPad13,7": @"iPad Pro 11 inch (3th generation)",
310
+ @"iPad13,8": @"iPad Pro 12.9 inch (5th generation)",
311
+ @"iPad13,9": @"iPad Pro 12.9 inch (5th generation)",
312
+ @"iPad13,10": @"iPad Pro 12.9 inch (5th generation)",
313
+ @"iPad13,11": @"iPad Pro 12.9 inch (5th generation)",
314
+ @"iPad14,1": @"iPad Mini (6th generation) (WiFi)",
315
+ @"iPad14,2": @"iPad Mini (6th generation) (WiFi+Cellular)",
295
316
  // Simulator
296
317
  @"i386": @"Simulator",
297
318
  @"arm64": @"Simulator",
@@ -322,30 +343,6 @@ EX_REGISTER_MODULE();
322
343
 
323
344
  // TODO: apple TV and apple watch
324
345
  NSDictionary *mapping = @{
325
- // iPhone 1
326
- @"iPhone1,1": @2007,
327
-
328
- // iPhone 3G
329
- @"iPhone1,2": @2008,
330
-
331
- // iPhone 3GS
332
- @"iPhone2,1": @2009,
333
-
334
- // iPhone 4
335
- @"iPhone3,1": @2010,
336
- @"iPhone3,2": @2010,
337
- @"iPhone3,3": @2010,
338
-
339
- // iPhone 4S
340
- @"iPhone4,1": @2011,
341
-
342
- // iPhone 5
343
- @"iPhone5,1": @2012,
344
- @"iPhone5,2": @2012,
345
-
346
- // iPhone 5S and 5C
347
- @"iPhone5,3": @2013,
348
- @"iPhone5,4": @2013,
349
346
  @"iPhone6,1": @2013,
350
347
  @"iPhone6,2": @2013,
351
348
 
@@ -371,7 +368,16 @@ EX_REGISTER_MODULE();
371
368
  @"iPhone12,1": @2019, // iPhone 11
372
369
  @"iPhone12,3": @2019, // iPhone 11 Pro
373
370
  @"iPhone12,5": @2019, // iPhone 11 Pro Max
374
-
371
+ @"iPhone12,8": @2020, // iPhone SE 2nd Gen
372
+ @"iPhone13,1": @2020, // iPhone 12 mini
373
+ @"iPhone13,2": @2020, // iPhone 12
374
+ @"iPhone13,3": @2020, // iPhone 12 Pro
375
+ @"iPhone13,4": @2020, // iPhone 12 Pro Max
376
+ @"iPhone14,2": @2021, // iPhone 13 Pro
377
+ @"iPhone14,3": @2021, // iPhone 13 Pro Max
378
+ @"iPhone14,4": @2021, // iPhone 13 Mini
379
+ @"iPhone14,5": @2021, // iPhone 13
380
+
375
381
  // iPod
376
382
  @"iPod1,1": @2007,
377
383
  @"iPod2,1": @2008,
@@ -435,6 +441,20 @@ EX_REGISTER_MODULE();
435
441
  @"iPad11,2": @2019, // iPad Mini 5th Gen
436
442
  @"iPad11,3": @2019, // iPad Air 3rd Gen (WiFi)
437
443
  @"iPad11,4": @2019, // iPad Air 3rd Gen
444
+ @"iPad11,6": @2020, // iPad 8th Gen
445
+ @"iPad11,7": @2020, // iPad 8th Gen
446
+ @"iPad13,1": @2020, // iPad Air 4th Gen (WiFi)
447
+ @"iPad13,2": @2020, // iPad Air 4th Gen (WiFi+Cellular)
448
+ @"iPad13,4": @2021, // iPad Pro 11-inch 3rd Gen
449
+ @"iPad13,5": @2021, // iPad Pro 11-inch 3rd Gen
450
+ @"iPad13,6": @2021, // iPad Pro 11-inch 3rd Gen
451
+ @"iPad13,7": @2021, // iPad Pro 11-inch 3rd Gen
452
+ @"iPad13,8": @2021, // iPad Pro 12.9-inch 5th Gen
453
+ @"iPad13,9": @2021, // iPad Pro 12.9-inch 5th Gen
454
+ @"iPad13,10": @2021, // iPad Pro 12.9-inch 5th Gen
455
+ @"iPad13,11": @2021, // iPad Pro 12.9-inch 5th Gen
456
+ @"iPad14,1": @2021, // iPad mini (6th generation) (WiFi)
457
+ @"iPad14,2": @2021 // iPad mini (6th generation) (WiFi + cellular)
438
458
  };
439
459
 
440
460
  NSNumber *deviceYear = mapping[platform];
@@ -10,8 +10,9 @@ Pod::Spec.new do |s|
10
10
  s.license = package['license']
11
11
  s.author = package['author']
12
12
  s.homepage = package['homepage']
13
- s.platform = :ios, '11.0'
13
+ s.platform = :ios, '12.0'
14
14
  s.source = { git: 'https://github.com/expo/expo.git' }
15
+ s.static_framework = true
15
16
 
16
17
  s.dependency 'ExpoModulesCore'
17
18
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-constants",
3
- "version": "11.1.0",
3
+ "version": "12.1.2",
4
4
  "description": "Provides system information that remains constant throughout the lifetime of your app.",
5
5
  "main": "build/Constants.js",
6
6
  "types": "build/Constants.d.ts",
@@ -34,12 +34,12 @@
34
34
  "preset": "expo-module-scripts"
35
35
  },
36
36
  "dependencies": {
37
- "@expo/config": "^4.0.0",
38
- "expo-modules-core": "~0.3.0",
37
+ "@expo/config": "^5.0.9",
38
+ "expo-modules-core": "~0.4.4",
39
39
  "uuid": "^3.3.2"
40
40
  },
41
41
  "devDependencies": {
42
42
  "expo-module-scripts": "^2.0.0"
43
43
  },
44
- "gitHead": "fe23a511edf816a3fea58d74856c2749a9de1463"
44
+ "gitHead": "4fa0497a180ae707fa860cb03858630ab7af19f4"
45
45
  }
@@ -2,29 +2,10 @@
2
2
 
3
3
  set -eo pipefail
4
4
 
5
- if [[ "$SKIP_BUNDLING" ]]; then
6
- echo "SKIP_BUNDLING enabled; skipping get-app-config-ios.sh."
7
- exit 0;
8
- elif [[ "$CONFIGURATION" == *Debug* ]]; then
9
- if [[ "$FORCE_BUNDLING" ]]; then
10
- echo "FORCE_BUNDLING enabled; continuing get-app-config-ios.sh."
11
- else
12
- exit 0;
13
- fi
14
- fi
15
-
16
- DEST="$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH"
5
+ DEST="$CONFIGURATION_BUILD_DIR"
6
+ RESOURCE_BUNDLE_NAME="EXConstants.bundle"
17
7
  NODE_BINARY=${NODE_BINARY:-node}
18
8
 
19
- # ref: https://github.com/facebook/react-native/blob/c974cbff04a8d90ac0f856dbada3fc5a75c75b49/scripts/react-native-xcode.sh#L59-L65
20
- # Path to expo-constants folder inside node_modules
21
- EXPO_CONSTANTS_PACKAGE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
22
- # If PROJECT_ROOT is not specified, fallback to use Xcode PROJECT_DIR
23
- PROJECT_ROOT=${PROJECT_ROOT:-"$PROJECT_DIR"}
24
- PROJECT_ROOT=${PROJECT_ROOT:-"$EXPO_CONSTANTS_PACKAGE_DIR/../.."}
25
-
26
- cd "$PROJECT_ROOT" || exit
27
-
28
9
  if ! [ -x "$(command -v "$NODE_BINARY")" ]; then
29
10
  echo 'Error: cannot find the node binary. Try setting the NODE_BINARY variable in the ' \
30
11
  '"Bundle React Native code and images" Build Phase to the absolute path to your node binary. ' \
@@ -32,10 +13,23 @@ if ! [ -x "$(command -v "$NODE_BINARY")" ]; then
32
13
  exit 1
33
14
  fi
34
15
 
35
- # For traditional main project build phases integration, will be no-op to prevent duplicated app.config creation.
36
- DIR_BASENAME=$(basename "$PROJECT_ROOT")
37
- if [ "x$DIR_BASENAME" != "xPods" ]; then
16
+ # For classic main project build phases integration, will be no-op to prevent duplicated app.config creation.
17
+ #
18
+ # `$PROJECT_DIR` is passed by Xcode as the directory to the xcodeproj file.
19
+ # in classic main project setup it is something like /path/to/app/ios
20
+ # in new style pod project setup it is something like /path/to/app/ios/Pods
21
+ PROJECT_DIR_BASENAME=$(basename $PROJECT_DIR)
22
+ if [ "x$PROJECT_DIR_BASENAME" != "xPods" ]; then
38
23
  exit 0
39
24
  fi
40
25
 
41
- "$NODE_BINARY" "${EXPO_CONSTANTS_PACKAGE_DIR}/scripts/getAppConfig.js" "$PROJECT_ROOT/.." "$DEST/EXConstants.bundle"
26
+ # ref: https://github.com/facebook/react-native/blob/c974cbff04a8d90ac0f856dbada3fc5a75c75b49/scripts/react-native-xcode.sh#L59-L65
27
+ # Path to expo-constants folder inside node_modules
28
+ EXPO_CONSTANTS_PACKAGE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
29
+ # If PROJECT_ROOT is not specified, fallback to use Xcode PROJECT_DIR
30
+ PROJECT_ROOT=${PROJECT_ROOT:-"$PROJECT_DIR/../.."}
31
+ PROJECT_ROOT=${PROJECT_ROOT:-"$EXPO_CONSTANTS_PACKAGE_DIR/../.."}
32
+
33
+ cd "$PROJECT_ROOT" || exit
34
+
35
+ "$NODE_BINARY" "${EXPO_CONSTANTS_PACKAGE_DIR}/scripts/getAppConfig.js" "$PROJECT_ROOT" "$DEST/$RESOURCE_BUNDLE_NAME"
package/src/Constants.ts CHANGED
@@ -71,6 +71,8 @@ if (!rawManifest && ExponentConstants && ExponentConstants.manifest) {
71
71
 
72
72
  const { name, appOwnership, ...nativeConstants } = (ExponentConstants || {}) as any;
73
73
 
74
+ let warnedAboutDeviceYearClass = false;
75
+ let warnedAboutIosModel = false;
74
76
  let warnedAboutInstallationId = false;
75
77
  let warnedAboutDeviceId = false;
76
78
  let warnedAboutLinkingUrl = false;
@@ -80,6 +82,16 @@ const constants = {
80
82
  // Ensure this is null in bare workflow
81
83
  appOwnership: appOwnership ?? null,
82
84
  // Deprecated fields
85
+ get deviceYearClass() {
86
+ if (!warnedAboutDeviceYearClass) {
87
+ console.warn(
88
+ `Constants.deviceYearClass has been deprecated in favor of expo-device's Device.deviceYearClass property. This API will be removed in SDK 45.`
89
+ );
90
+ warnedAboutDeviceYearClass = true;
91
+ }
92
+ return nativeConstants.deviceYearClass;
93
+ },
94
+ // Deprecated fields
83
95
  get installationId() {
84
96
  if (!warnedAboutInstallationId) {
85
97
  console.warn(
@@ -150,6 +162,24 @@ const constants = {
150
162
  },
151
163
  } as Constants;
152
164
 
165
+ // Add deprecation warning for `platform.ios.model`
166
+ if (constants?.platform?.ios) {
167
+ const originalModel = nativeConstants.platform.ios.model;
168
+ Object.defineProperty(constants.platform.ios, 'model', {
169
+ get() {
170
+ if (!warnedAboutIosModel) {
171
+ console.warn(
172
+ `Constants.platform.ios.model has been deprecated in favor of expo-device's Device.modelName property. This API will be removed in SDK 45.`
173
+ );
174
+ warnedAboutIosModel = true;
175
+ }
176
+ return originalModel;
177
+ },
178
+ // Prevent the warning from being thrown, or the value from being used when the user interacts with the entire object.
179
+ enumerable: false,
180
+ });
181
+ }
182
+
153
183
  function isAppManifest(manifest: AppManifest | Manifest): manifest is AppManifest {
154
184
  return !isManifest(manifest);
155
185
  }
@@ -21,6 +21,9 @@ export enum UserInterfaceIdiom {
21
21
  export interface IOSManifest {
22
22
  buildNumber: string;
23
23
  platform: string;
24
+ /**
25
+ * @deprecated Moved to `expo-device` - `Device.modelName`
26
+ */
24
27
  model: string | null;
25
28
  userInterfaceIdiom: UserInterfaceIdiom;
26
29
  systemVersion: string;
@@ -154,6 +157,9 @@ export interface NativeConstants {
154
157
  appOwnership: AppOwnership | null;
155
158
  debugMode: boolean;
156
159
  deviceName?: string;
160
+ /**
161
+ * @deprecated Moved to `expo-device` - `Device.deviceYearClass`
162
+ */
157
163
  deviceYearClass: number | null;
158
164
  executionEnvironment: ExecutionEnvironment;
159
165
  experienceUrl: string;
@@ -1,44 +0,0 @@
1
- // Copyright 2015-present 650 Industries. All rights reserved.
2
-
3
- package expo.modules.constants;
4
-
5
- import android.content.Context;
6
-
7
- import java.util.Map;
8
-
9
- import expo.modules.core.ExportedModule;
10
- import expo.modules.core.ModuleRegistry;
11
- import expo.modules.core.Promise;
12
- import expo.modules.core.interfaces.ExpoMethod;
13
-
14
- import expo.modules.interfaces.constants.ConstantsInterface;
15
-
16
- public class ConstantsModule extends ExportedModule {
17
- private ModuleRegistry mModuleRegistry;
18
-
19
- public ConstantsModule(Context context) {
20
- super(context);
21
- }
22
-
23
- @Override
24
- public Map<String, Object> getConstants() {
25
- ConstantsInterface constantsService = mModuleRegistry.getModule(ConstantsInterface.class);
26
- return constantsService.getConstants();
27
- }
28
-
29
- @Override
30
- public String getName() {
31
- return "ExponentConstants";
32
- }
33
-
34
- @Override
35
- public void onCreate(ModuleRegistry moduleRegistry) {
36
- mModuleRegistry = moduleRegistry;
37
- }
38
-
39
- @ExpoMethod
40
- public void getWebViewUserAgentAsync(Promise promise) {
41
- String userAgent = System.getProperty("http.agent");
42
- promise.resolve(userAgent);
43
- }
44
- }
@@ -1,22 +0,0 @@
1
- package expo.modules.constants;
2
-
3
- import android.content.Context;
4
-
5
- import java.util.Collections;
6
- import java.util.List;
7
-
8
- import expo.modules.core.ExportedModule;
9
- import expo.modules.core.BasePackage;
10
- import expo.modules.core.interfaces.InternalModule;
11
-
12
- public class ConstantsPackage extends BasePackage {
13
- @Override
14
- public List<InternalModule> createInternalModules(Context context) {
15
- return Collections.singletonList((InternalModule) new ConstantsService(context));
16
- }
17
-
18
- @Override
19
- public List<ExportedModule> createExportedModules(Context context) {
20
- return Collections.singletonList((ExportedModule) new ConstantsModule(context));
21
- }
22
- }
@@ -1,188 +0,0 @@
1
- package expo.modules.constants;
2
-
3
- import android.content.Context;
4
- import android.content.pm.PackageInfo;
5
- import android.content.pm.PackageManager;
6
- import android.content.res.Resources;
7
- import android.os.Build;
8
- import androidx.annotation.Nullable;
9
- import android.util.DisplayMetrics;
10
- import android.util.Log;
11
-
12
- import com.facebook.device.yearclass.YearClass;
13
-
14
- import java.io.FileNotFoundException;
15
- import java.io.InputStream;
16
- import java.nio.charset.StandardCharsets;
17
- import java.util.ArrayList;
18
- import java.util.Collections;
19
- import java.util.HashMap;
20
- import java.util.List;
21
- import java.util.Map;
22
- import java.util.UUID;
23
-
24
- import org.apache.commons.io.IOUtils;
25
- import expo.modules.core.interfaces.InternalModule;
26
-
27
- import expo.modules.interfaces.constants.ConstantsInterface;
28
-
29
- public class ConstantsService implements InternalModule, ConstantsInterface {
30
- private static final String TAG = ConstantsService.class.getSimpleName();
31
-
32
- protected Context mContext;
33
- protected int mStatusBarHeight = 0;
34
- private String mSessionId = UUID.randomUUID().toString();
35
- private ExponentInstallationId mExponentInstallationId;
36
- private static final String CONFIG_FILE_NAME = "app.config";
37
-
38
- public enum ExecutionEnvironment {
39
- BARE("bare"),
40
- STANDALONE("standalone"),
41
- STORE_CLIENT("storeClient");
42
-
43
- private final String mString;
44
-
45
- ExecutionEnvironment(String string) {
46
- mString = string;
47
- }
48
-
49
- public String getString() {
50
- return mString;
51
- }
52
- }
53
-
54
- private static int convertPixelsToDp(float px, Context context) {
55
- Resources resources = context.getResources();
56
- DisplayMetrics metrics = resources.getDisplayMetrics();
57
- float dp = px / (metrics.densityDpi / 160f);
58
- return (int) dp;
59
- }
60
-
61
- public ConstantsService(Context context) {
62
- super();
63
- mContext = context;
64
- mExponentInstallationId = new ExponentInstallationId(mContext);
65
-
66
- int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
67
-
68
- if (resourceId > 0) {
69
- int statusBarHeightPixels = context.getResources().getDimensionPixelSize(resourceId);
70
- // Convert from pixels to dip
71
- mStatusBarHeight = convertPixelsToDp(statusBarHeightPixels, context);
72
- }
73
- }
74
-
75
- @Override
76
- public List<Class> getExportedInterfaces() {
77
- return Collections.singletonList((Class) ConstantsInterface.class);
78
- }
79
-
80
- @Nullable
81
- public Map<String, Object> getConstants() {
82
- Map<String, Object> constants = new HashMap<>();
83
-
84
- constants.put("sessionId", mSessionId);
85
- constants.put("executionEnvironment", ExecutionEnvironment.BARE.getString());
86
- constants.put("statusBarHeight", getStatusBarHeight());
87
- constants.put("deviceYearClass", getDeviceYearClass());
88
- constants.put("deviceName", getDeviceName());
89
- constants.put("isDevice", getIsDevice());
90
- constants.put("systemFonts", getSystemFonts());
91
- constants.put("systemVersion", getSystemVersion());
92
- constants.put("installationId", getOrCreateInstallationId());
93
- constants.put("manifest", getAppConfig());
94
-
95
- PackageManager packageManager = mContext.getPackageManager();
96
- try {
97
- PackageInfo pInfo = packageManager.getPackageInfo(mContext.getPackageName(), 0);
98
- constants.put("nativeAppVersion", pInfo.versionName);
99
-
100
- int versionCode = (int)getLongVersionCode(pInfo);
101
- constants.put("nativeBuildVersion", Integer.toString(versionCode));
102
- } catch (PackageManager.NameNotFoundException e) {
103
- Log.e(TAG, "Exception: ", e);
104
- }
105
-
106
- Map<String, Object> platform = new HashMap<>();
107
- Map<String, Object> androidPlatform = new HashMap<>();
108
-
109
- platform.put("android", androidPlatform);
110
- constants.put("platform", platform);
111
- return constants;
112
- }
113
-
114
- public String getAppScopeKey() {
115
- // Just use package name in vanilla React Native apps.
116
- return mContext.getPackageName();
117
- }
118
-
119
- public String getAppOwnership() {
120
- return "guest";
121
- }
122
-
123
- public String getDeviceName() {
124
- return Build.MODEL;
125
- }
126
-
127
- public int getDeviceYearClass() {
128
- return YearClass.get(mContext);
129
- }
130
-
131
- public boolean getIsDevice() {
132
- return !isRunningOnGenymotion() && !isRunningOnStockEmulator();
133
- }
134
-
135
- public int getStatusBarHeight() {
136
- return mStatusBarHeight;
137
- }
138
-
139
- public String getSystemVersion() {
140
- return Build.VERSION.RELEASE;
141
- }
142
-
143
- public String getOrCreateInstallationId() {
144
- return mExponentInstallationId.getOrCreateUUID();
145
- }
146
-
147
- public List<String> getSystemFonts() {
148
- // From https://github.com/dabit3/react-native-fonts
149
- List<String> result = new ArrayList<>();
150
- result.add("normal");
151
- result.add("notoserif");
152
- result.add("sans-serif");
153
- result.add("sans-serif-light");
154
- result.add("sans-serif-thin");
155
- result.add("sans-serif-condensed");
156
- result.add("sans-serif-medium");
157
- result.add("serif");
158
- result.add("Roboto");
159
- result.add("monospace");
160
- return result;
161
- }
162
-
163
- private static boolean isRunningOnGenymotion() {
164
- return Build.FINGERPRINT.contains("vbox");
165
- }
166
-
167
- private static boolean isRunningOnStockEmulator() {
168
- return Build.FINGERPRINT.contains("generic");
169
- }
170
-
171
- private static long getLongVersionCode(PackageInfo info) {
172
- if (Build.VERSION.SDK_INT >= 28) {
173
- return info.getLongVersionCode();
174
- }
175
- return info.versionCode;
176
- }
177
-
178
- private @Nullable String getAppConfig() {
179
- try (InputStream stream = mContext.getAssets().open(CONFIG_FILE_NAME)) {
180
- return IOUtils.toString(stream, StandardCharsets.UTF_8);
181
- } catch (FileNotFoundException e) {
182
- // do nothing, expected in managed apps
183
- } catch (Exception e) {
184
- Log.e(TAG, "Error reading embedded app config", e);
185
- }
186
- return null;
187
- }
188
- }
@@ -1,110 +0,0 @@
1
- package expo.modules.constants;
2
-
3
- import android.content.Context;
4
- import android.content.SharedPreferences;
5
- import android.util.Log;
6
-
7
- import java.io.BufferedReader;
8
- import java.io.File;
9
- import java.io.FileReader;
10
- import java.io.FileWriter;
11
- import java.io.IOException;
12
- import java.util.UUID;
13
-
14
- /**
15
- * An installation ID provider - it solves two purposes:
16
- * - in installations that have a legacy UUID persisted
17
- * in shared-across-expo-modules SharedPreferences,
18
- * migrates the UUID from there to a non-backed-up file,
19
- * - provides/creates a UUID unique per an installation.
20
- *
21
- * Similar class exists in expoview and expo-notifications.
22
- */
23
- public class ExponentInstallationId {
24
- private static final String TAG = ExponentInstallationId.class.getSimpleName();
25
-
26
- public static final String LEGACY_UUID_KEY = "uuid";
27
- public static final String UUID_FILE_NAME = "expo_installation_uuid.txt";
28
- private static final String PREFERENCES_FILE_NAME = "host.exp.exponent.SharedPreferences";
29
-
30
- private String mUuid;
31
- private Context mContext;
32
- private SharedPreferences mSharedPreferences;
33
-
34
- /* package */ ExponentInstallationId(Context context) {
35
- mContext = context;
36
- mSharedPreferences = context.getSharedPreferences(PREFERENCES_FILE_NAME, Context.MODE_PRIVATE);
37
- }
38
-
39
- public String getUUID() {
40
- // If it has already been cached, return the value.
41
- if (mUuid != null) {
42
- return mUuid;
43
- }
44
-
45
- // Read from non-backed-up storage
46
- File uuidFile = getNonBackedUpUuidFile();
47
- try (FileReader fileReader = new FileReader(uuidFile);
48
- BufferedReader bufferedReader = new BufferedReader(fileReader)) {
49
- // Cache for future calls
50
- mUuid = UUID.fromString(bufferedReader.readLine()).toString();
51
- } catch (IOException | IllegalArgumentException e) {
52
- // do nothing, try other sources
53
- }
54
-
55
- // We could have returned inside try clause,
56
- // but putting it like this here makes it immediately
57
- // visible.
58
- if (mUuid != null) {
59
- return mUuid;
60
- }
61
-
62
- // In November 2020 we decided to move installationID (backed by LEGACY_UUID_KEY value) from backed-up SharedPreferences
63
- // to a non-backed-up text file to fix issues where devices restored from backups have the same installation IDs
64
- // as the devices where the backup was created.
65
- String legacyUuid = mSharedPreferences.getString(LEGACY_UUID_KEY, null);
66
- if (legacyUuid != null) {
67
- mUuid = legacyUuid;
68
-
69
- boolean uuidHasBeenSuccessfullyMigrated = true;
70
-
71
- try (FileWriter writer = new FileWriter(uuidFile)) {
72
- writer.write(legacyUuid);
73
- } catch (IOException e) {
74
- uuidHasBeenSuccessfullyMigrated = false;
75
- Log.e(TAG, "Error while migrating UUID from legacy storage. " + e);
76
- }
77
-
78
- // We only remove the value from old storage once it's set and saved in the new storage.
79
- if (uuidHasBeenSuccessfullyMigrated) {
80
- mSharedPreferences.edit().remove(LEGACY_UUID_KEY).apply();
81
- }
82
- }
83
-
84
- // Return either value from legacy storage or null
85
- return mUuid;
86
- }
87
-
88
- public String getOrCreateUUID() {
89
- String uuid = getUUID();
90
- if (uuid != null) {
91
- return uuid;
92
- }
93
-
94
- // We persist the new UUID in "session storage"
95
- // so that if writing to persistent storage
96
- // fails subsequent calls to get(orCreate)UUID
97
- // return the same value.
98
- mUuid = UUID.randomUUID().toString();
99
- try (FileWriter writer = new FileWriter(getNonBackedUpUuidFile())) {
100
- writer.write(mUuid);
101
- } catch (IOException e) {
102
- Log.e(TAG, "Error while writing new UUID. " + e);
103
- }
104
- return mUuid;
105
- }
106
-
107
- private File getNonBackedUpUuidFile() {
108
- return new File(mContext.getNoBackupFilesDir(), UUID_FILE_NAME);
109
- }
110
- }