expo-updates 0.18.15 → 0.18.16

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,13 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 0.18.16 — 2023-10-05
14
+
15
+ ### 🐛 Bug fixes
16
+
17
+ - Add missing export in checkForUpdateAsync result. (by [@douglowder](https://github.com/douglowder)) ([#24503](https://github.com/expo/expo/pull/24503) by [@douglowder](https://github.com/douglowder))
18
+ - [Android] embedded loader should load images at all scales. ([#24549](https://github.com/expo/expo/pull/24549) by [@douglowder](https://github.com/douglowder))
19
+
13
20
  ## 0.18.15 — 2023-10-05
14
21
 
15
22
  ### 🐛 Bug fixes
@@ -4,7 +4,7 @@ apply plugin: 'kotlin-kapt'
4
4
  apply plugin: 'maven-publish'
5
5
 
6
6
  group = 'host.exp.exponent'
7
- version = '0.18.15'
7
+ version = '0.18.16'
8
8
 
9
9
  // Utility method to derive boolean values from the environment or from Java properties,
10
10
  // and return them as strings to be used in BuildConfig fields
@@ -95,7 +95,7 @@ android {
95
95
  minSdkVersion safeExtGet("minSdkVersion", 21)
96
96
  targetSdkVersion safeExtGet("targetSdkVersion", 33)
97
97
  versionCode 31
98
- versionName '0.18.15'
98
+ versionName '0.18.16'
99
99
  consumerProguardFiles("proguard-rules.pro")
100
100
  testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
101
101
 
@@ -134,8 +134,18 @@ object UpdatesUtils {
134
134
  }
135
135
 
136
136
  // only rename after the hash has been verified
137
- if (!tmpFile.renameTo(destination)) {
138
- throw IOException("File download was successful, but failed to move from temporary to permanent location " + destination.absolutePath)
137
+ // Since renameTo() does not expose detailed errors, and can fail if source and destination
138
+ // are not on the same mount point, we do a copyTo followed by delete
139
+ try {
140
+ tmpFile.copyTo(destination)
141
+ } catch (e: NoSuchFileException) {
142
+ throw IOException("File download was successful, but temp file ${tmpFile.absolutePath} does not exist")
143
+ } catch (e: FileAlreadyExistsException) {
144
+ throw IOException("File download was successful, but file already exists at ${destination.absolutePath}")
145
+ } catch (e: Exception) {
146
+ throw IOException("File download was successful, but an exception occurred: $e")
147
+ } finally {
148
+ tmpFile.delete()
139
149
  }
140
150
 
141
151
  return hash
@@ -22,11 +22,6 @@ import java.util.*
22
22
  * update. The benefits of this include (a) a single code path for launching most updates and (b)
23
23
  * assets included in embedded updates and copied into the cache in this way do not need to be
24
24
  * redownloaded if included in future updates.
25
- *
26
- * However, if a visual asset is included at multiple scales in an embedded update, we don't have
27
- * access to and must skip copying scales that don't match the resolution of the current device. In
28
- * this case, we cannot fully copy the embedded update, and instead launch it from the original
29
- * location. We still copy the assets we can so they don't need to be redownloaded in the future.
30
25
  */
31
26
  class EmbeddedLoader internal constructor(
32
27
  private val context: Context,
@@ -37,7 +32,6 @@ class EmbeddedLoader internal constructor(
37
32
  ) : Loader(
38
33
  context, configuration, database, updatesDirectory, loaderFiles
39
34
  ) {
40
- private val pixelDensity = context.resources.displayMetrics.density
41
35
 
42
36
  constructor(
43
37
  context: Context,
@@ -98,29 +92,6 @@ class EmbeddedLoader internal constructor(
98
92
  }
99
93
  }
100
94
 
101
- override fun shouldSkipAsset(assetEntity: AssetEntity): Boolean {
102
- return if (assetEntity.scales == null || assetEntity.scale == null) {
103
- false
104
- } else pickClosestScale(assetEntity.scales!!) != assetEntity.scale
105
- }
106
-
107
- // https://developer.android.com/guide/topics/resources/providing-resources.html#BestMatch
108
- // If a perfect match is not available, the OS will pick the next largest scale.
109
- // If only smaller scales are available, the OS will choose the largest available one.
110
- private fun pickClosestScale(scales: Array<Float>): Float {
111
- var closestScale = Float.MAX_VALUE
112
- var largestScale = 0f
113
- for (scale in scales) {
114
- if (scale >= pixelDensity && scale < closestScale) {
115
- closestScale = scale
116
- }
117
- if (scale > largestScale) {
118
- largestScale = scale
119
- }
120
- }
121
- return if (closestScale < Float.MAX_VALUE) closestScale else largestScale
122
- }
123
-
124
95
  companion object {
125
96
  private val TAG = EmbeddedLoader::class.java.simpleName
126
97
 
@@ -34,7 +34,6 @@ abstract class Loader protected constructor(
34
34
  private var callback: LoaderCallback? = null
35
35
  private var assetTotal = 0
36
36
  private var erroredAssetList = mutableListOf<AssetEntity>()
37
- private var skippedAssetList = mutableListOf<AssetEntity>()
38
37
  private var existingAssetList = mutableListOf<AssetEntity>()
39
38
  private var finishedAssetList = mutableListOf<AssetEntity>()
40
39
 
@@ -89,8 +88,6 @@ abstract class Loader protected constructor(
89
88
  callback: AssetDownloadCallback
90
89
  )
91
90
 
92
- protected abstract fun shouldSkipAsset(assetEntity: AssetEntity): Boolean
93
-
94
91
  // lifecycle methods for class
95
92
  fun start(callback: LoaderCallback) {
96
93
  if (this.callback != null) {
@@ -129,7 +126,6 @@ abstract class Loader protected constructor(
129
126
  callback = null
130
127
  assetTotal = 0
131
128
  erroredAssetList = mutableListOf()
132
- skippedAssetList = mutableListOf()
133
129
  existingAssetList = mutableListOf()
134
130
  finishedAssetList = mutableListOf()
135
131
  }
@@ -219,17 +215,13 @@ abstract class Loader protected constructor(
219
215
  }
220
216
 
221
217
  private enum class AssetLoadResult {
222
- FINISHED, ALREADY_EXISTS, ERRORED, SKIPPED
218
+ FINISHED, ALREADY_EXISTS, ERRORED
223
219
  }
224
220
 
225
221
  private fun downloadAllAssets(assetList: List<AssetEntity>) {
226
222
  assetTotal = assetList.size
227
223
  for (assetEntityCur in assetList) {
228
224
  var assetEntity = assetEntityCur
229
- if (shouldSkipAsset(assetEntity)) {
230
- handleAssetDownloadCompleted(assetEntity, AssetLoadResult.SKIPPED)
231
- continue
232
- }
233
225
 
234
226
  val matchingDbEntry = database.assetDao().loadAssetWithKey(assetEntity.key)
235
227
  if (matchingDbEntry != null) {
@@ -279,7 +271,6 @@ abstract class Loader protected constructor(
279
271
  AssetLoadResult.FINISHED -> finishedAssetList.add(assetEntity)
280
272
  AssetLoadResult.ALREADY_EXISTS -> existingAssetList.add(assetEntity)
281
273
  AssetLoadResult.ERRORED -> erroredAssetList.add(assetEntity)
282
- AssetLoadResult.SKIPPED -> skippedAssetList.add(assetEntity)
283
274
  else -> throw AssertionError("Missing implementation for AssetLoadResult value")
284
275
  }
285
276
 
@@ -290,7 +281,7 @@ abstract class Loader protected constructor(
290
281
  assetTotal
291
282
  )
292
283
 
293
- if (finishedAssetList.size + erroredAssetList.size + existingAssetList.size + skippedAssetList.size == assetTotal) {
284
+ if (finishedAssetList.size + erroredAssetList.size + existingAssetList.size == assetTotal) {
294
285
  try {
295
286
  for (asset in existingAssetList) {
296
287
  val existingAssetFound = database.assetDao()
@@ -313,7 +304,7 @@ abstract class Loader protected constructor(
313
304
  database.assetDao().insertAssets(finishedAssetList, updateEntity!!)
314
305
 
315
306
  if (erroredAssetList.size == 0) {
316
- database.updateDao().markUpdateFinished(updateEntity!!, skippedAssetList.size != 0)
307
+ database.updateDao().markUpdateFinished(updateEntity!!)
317
308
  }
318
309
  } catch (e: Exception) {
319
310
  finishWithError("Error while adding new update to database", e)
@@ -55,10 +55,6 @@ class RemoteLoader internal constructor(
55
55
  mFileDownloader.downloadAsset(assetEntity, updatesDirectory, configuration, context, callback)
56
56
  }
57
57
 
58
- override fun shouldSkipAsset(assetEntity: AssetEntity): Boolean {
59
- return false
60
- }
61
-
62
58
  companion object {
63
59
  private val TAG = RemoteLoader::class.java.simpleName
64
60
  }
@@ -35,7 +35,7 @@
35
35
  "simulator": {
36
36
  "type": "ios.simulator",
37
37
  "device": {
38
- "type": "iPhone 14"
38
+ "type": "iPhone 15"
39
39
  }
40
40
  },
41
41
  "emulator": {
@@ -484,7 +484,7 @@ async function initAsync(
484
484
  CI: '1',
485
485
  },
486
486
  cwd: projectRoot,
487
- stdio: 'ignore',
487
+ stdio: 'inherit',
488
488
  });
489
489
 
490
490
  // We are done with template tarball
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-updates",
3
- "version": "0.18.15",
3
+ "version": "0.18.16",
4
4
  "description": "Fetches and manages remotely-hosted assets and updates to your app's JS bundle.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -64,5 +64,5 @@
64
64
  "peerDependencies": {
65
65
  "expo": "*"
66
66
  },
67
- "gitHead": "d2b91e83b2845467865b2ec3b975edba0a5d6995"
67
+ "gitHead": "19fbbb907b3439da37dbe21c372fba3226594a37"
68
68
  }