expo-updates 0.22.0 → 0.24.0
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 +66 -0
- package/android/build.gradle +6 -4
- package/android/src/main/java/expo/modules/updates/DisabledUpdatesController.kt +132 -0
- package/android/src/main/java/expo/modules/updates/EnabledUpdatesController.kt +296 -0
- package/android/src/main/java/expo/modules/updates/IUpdatesController.kt +121 -0
- package/android/src/main/java/expo/modules/updates/UpdatesConfiguration.kt +58 -21
- package/android/src/main/java/expo/modules/updates/UpdatesController.kt +50 -592
- package/android/src/main/java/expo/modules/updates/UpdatesDevLauncherController.kt +178 -85
- package/android/src/main/java/expo/modules/updates/UpdatesModule.kt +181 -495
- package/android/src/main/java/expo/modules/updates/UpdatesPackage.kt +0 -10
- package/android/src/main/java/expo/modules/updates/UpdatesUtils.kt +14 -39
- package/android/src/main/java/expo/modules/updates/db/BuildData.kt +5 -2
- package/android/src/main/java/expo/modules/updates/db/dao/UpdateDao.kt +2 -2
- package/android/src/main/java/expo/modules/updates/errorrecovery/ErrorRecovery.kt +15 -5
- package/android/src/main/java/expo/modules/updates/launcher/DatabaseLauncher.kt +37 -21
- package/android/src/main/java/expo/modules/updates/launcher/NoDatabaseLauncher.kt +5 -30
- package/android/src/main/java/expo/modules/updates/loader/EmbeddedLoader.kt +2 -2
- package/android/src/main/java/expo/modules/updates/loader/FileDownloader.kt +3 -3
- package/android/src/main/java/expo/modules/updates/loader/Loader.kt +1 -1
- package/android/src/main/java/expo/modules/updates/loader/LoaderTask.kt +33 -26
- package/android/src/main/java/expo/modules/updates/loader/RemoteLoader.kt +4 -9
- package/android/src/main/java/expo/modules/updates/manifest/BareUpdateManifest.kt +3 -4
- package/android/src/main/java/expo/modules/updates/manifest/EmbeddedManifest.kt +2 -2
- package/android/src/main/java/expo/modules/updates/manifest/LegacyUpdateManifest.kt +2 -2
- package/android/src/main/java/expo/modules/updates/manifest/ManifestFactory.kt +5 -9
- package/android/src/main/java/expo/modules/updates/manifest/ManifestMetadata.kt +3 -3
- package/android/src/main/java/expo/modules/updates/manifest/NewUpdateManifest.kt +2 -2
- package/android/src/main/java/expo/modules/updates/procedures/CheckForUpdateProcedure.kt +181 -0
- package/android/src/main/java/expo/modules/updates/procedures/FetchUpdateProcedure.kt +117 -0
- package/android/src/main/java/expo/modules/updates/procedures/RelaunchProcedure.kt +111 -0
- package/android/src/main/java/expo/modules/updates/procedures/StartupProcedure.kt +323 -0
- package/android/src/main/java/expo/modules/updates/procedures/StateMachineProcedure.kt +39 -0
- package/android/src/main/java/expo/modules/updates/procedures/StateMachineSerialExecutorQueue.kt +75 -0
- package/android/src/main/java/expo/modules/updates/statemachine/UpdatesStateMachine.kt +29 -8
- package/build/Updates.d.ts +20 -6
- package/build/Updates.d.ts.map +1 -1
- package/build/Updates.js +20 -6
- package/build/Updates.js.map +1 -1
- package/build/Updates.types.d.ts +3 -1
- package/build/Updates.types.d.ts.map +1 -1
- package/build/Updates.types.js +3 -1
- package/build/Updates.types.js.map +1 -1
- package/build/UpdatesEmitter.d.ts +3 -1
- package/build/UpdatesEmitter.d.ts.map +1 -1
- package/build/UpdatesEmitter.js +3 -1
- package/build/UpdatesEmitter.js.map +1 -1
- package/build/UpdatesHooks.d.ts +3 -1
- package/build/UpdatesHooks.d.ts.map +1 -1
- package/build/UpdatesHooks.js +3 -1
- package/build/UpdatesHooks.js.map +1 -1
- package/e2e/README.md +5 -5
- package/e2e/fixtures/App-apitest.tsx +86 -108
- package/e2e/fixtures/App-updates-disabled.tsx +107 -0
- package/e2e/fixtures/App.tsx +98 -92
- package/e2e/fixtures/E2ETestModule.swift +0 -2
- package/e2e/fixtures/Updates-disabled.e2e.ts +49 -0
- package/e2e/fixtures/Updates-startup.e2e.ts +92 -0
- package/e2e/fixtures/Updates.e2e.ts +79 -15
- package/e2e/fixtures/UpdatesE2ETestModule.kt +27 -27
- package/e2e/fixtures/project_files/.detoxrc.json +5 -3
- package/e2e/fixtures/project_files/assetsInUpdates/coffee-prep.jpg +0 -0
- package/e2e/fixtures/project_files/e2e/tests/utils/server.ts +21 -8
- package/e2e/fixtures/project_files/eas-hooks/eas-build-on-success.sh +17 -6
- package/e2e/fixtures/project_files/eas-hooks/eas-build-pre-install.sh +1 -1
- package/e2e/fixtures/project_files/eas.json +36 -3
- package/e2e/fixtures/project_files/embeddedAssets/Abel_400Regular.ttf +0 -0
- package/e2e/fixtures/project_files/embeddedAssets/HankenGrotesk_300Light.ttf +0 -0
- package/e2e/fixtures/project_files/embeddedAssets/coffee-prep.jpg +0 -0
- package/e2e/fixtures/project_files/embeddedAssets/dougheadshot.jpg +0 -0
- package/e2e/fixtures/project_files/scripts/files/App.tsx.embedded +183 -0
- package/e2e/fixtures/project_files/scripts/files/App.tsx.update1 +189 -0
- package/e2e/fixtures/project_files/scripts/files/App.tsx.update2 +189 -0
- package/e2e/fixtures/project_files/scripts/{generate-test-update-bundles.js → generate-test-update-bundles.ts} +32 -21
- package/e2e/fixtures/project_files/scripts/reset-app.ts +29 -0
- package/e2e/setup/create-disabled-eas-project.ts +45 -0
- package/e2e/setup/{create-eas-project-tv.js → create-eas-project-tv.ts} +6 -3
- package/e2e/setup/{create-eas-project.js → create-eas-project.ts} +6 -3
- package/e2e/setup/create-startup-eas-project.ts +43 -0
- package/e2e/setup/{create-updates-test.js → create-updates-test.ts} +14 -5
- package/e2e/setup/{project.js → project.ts} +379 -153
- package/expo-module.config.json +3 -0
- package/ios/EXUpdates/AppController.swift +155 -645
- package/ios/EXUpdates/AppLauncher/AppLauncher.swift +1 -1
- package/ios/EXUpdates/AppLauncher/AppLauncherNoDatabase.swift +7 -25
- package/ios/EXUpdates/AppLauncher/AppLauncherWithDatabase.swift +18 -29
- package/ios/EXUpdates/AppLoader/AppLoader.swift +17 -9
- package/ios/EXUpdates/AppLoader/AppLoaderTask.swift +24 -41
- package/ios/EXUpdates/AppLoader/EmbeddedAppLoader.swift +6 -31
- package/ios/EXUpdates/AppLoader/FileDownloader.swift +3 -3
- package/ios/EXUpdates/AppLoader/RemoteAppLoader.swift +1 -2
- package/ios/EXUpdates/AppLoader/UpdateResponse.swift +0 -5
- package/ios/EXUpdates/Database/UpdatesBuildData.swift +2 -8
- package/ios/EXUpdates/Database/UpdatesDatabase.swift +0 -9
- package/ios/EXUpdates/Database/UpdatesReaper.swift +1 -1
- package/ios/EXUpdates/DevLauncherAppController.swift +318 -0
- package/ios/EXUpdates/DisabledAppController.swift +117 -0
- package/ios/EXUpdates/EnabledAppController.swift +339 -0
- package/ios/EXUpdates/ErrorRecovery.swift +15 -21
- package/ios/EXUpdates/Exceptions.swift +16 -6
- package/ios/EXUpdates/Logging/UpdatesLogReader.swift +7 -5
- package/ios/EXUpdates/Procedures/CheckForUpdateProcedure.swift +154 -0
- package/ios/EXUpdates/Procedures/FetchUpdateProcedure.swift +135 -0
- package/ios/EXUpdates/Procedures/RelaunchProcedure.swift +97 -0
- package/ios/EXUpdates/Procedures/StartupProcedure.swift +352 -0
- package/ios/EXUpdates/Procedures/StateMachineProcedure.swift +83 -0
- package/ios/EXUpdates/Procedures/StateMachineSerialExecutorQueue.swift +90 -0
- package/ios/EXUpdates/ReactDelegateHandler/ExpoUpdatesAppDelegateSubscriber.swift +1 -1
- package/ios/EXUpdates/ReactDelegateHandler/ExpoUpdatesReactDelegateHandler.swift +3 -2
- package/ios/EXUpdates/Update/BareUpdate.swift +3 -3
- package/ios/EXUpdates/Update/LegacyUpdate.swift +2 -2
- package/ios/EXUpdates/Update/NewUpdate.swift +1 -1
- package/ios/EXUpdates/Update/Update.swift +6 -14
- package/ios/EXUpdates/UpdatesConfig.swift +66 -33
- package/ios/EXUpdates/UpdatesModule.swift +74 -125
- package/ios/EXUpdates/UpdatesStateMachine.swift +38 -18
- package/ios/EXUpdates/UpdatesUtils.swift +17 -329
- package/ios/EXUpdates.podspec +1 -1
- package/ios/Tests/AppLauncherWithDatabaseSpec.swift +24 -48
- package/ios/Tests/CertificateChainSpec.swift +1 -1
- package/ios/Tests/CodeSigningAlgorithmSpec.swift +1 -1
- package/ios/Tests/CodeSigningConfigurationSpec.swift +1 -1
- package/ios/Tests/DatabaseInitializationSpec.swift +1 -1
- package/ios/Tests/DatabaseIntegrityCheckSpec.swift +5 -3
- package/ios/Tests/ErrorRecoverySpec.swift +73 -28
- package/ios/Tests/FileDownloaderManifestParsingSpec.swift +33 -17
- package/ios/Tests/FileDownloaderSpec.swift +13 -11
- package/ios/Tests/LegacyUpdateSpec.swift +30 -11
- package/ios/Tests/NewUpdateSpec.swift +16 -15
- package/ios/Tests/ReaperSelectionPolicyDevelopmentClientSpec.swift +21 -11
- package/ios/Tests/ReaperSelectionPolicyFilterAwareSpec.swift +9 -5
- package/ios/Tests/ResponseHeaderDataSpec.swift +1 -1
- package/ios/Tests/SelectionPolicyFilterAwareSpec.swift +3 -2
- package/ios/Tests/SignatureHeaderInfoSpec.swift +1 -1
- package/ios/Tests/StringStringDictionarySerializerSpec.swift +1 -1
- package/ios/Tests/UpdateAssetSpec.swift +1 -1
- package/ios/Tests/UpdateSpec.swift +15 -28
- package/ios/Tests/UpdatesBuildDataSpec.swift +18 -14
- package/ios/Tests/UpdatesConfigSpec.swift +25 -15
- package/ios/Tests/UpdatesDatabaseSpec.swift +4 -3
- package/ios/Tests/UpdatesStateMachineSpec.swift +49 -41
- package/package.json +8 -8
- package/src/Updates.ts +21 -6
- package/src/Updates.types.ts +3 -1
- package/src/UpdatesEmitter.ts +3 -1
- package/src/UpdatesHooks.ts +3 -1
- package/android/src/main/java/expo/modules/updates/UpdatesInterface.kt +0 -39
- package/android/src/main/java/expo/modules/updates/UpdatesService.kt +0 -76
- package/e2e/fixtures/project_files/detox.config.js +0 -77
- package/ios/EXUpdates/DevLauncherController.swift +0 -243
- package/ios/EXUpdates/EXUpdatesService.h +0 -40
- package/ios/EXUpdates/EXUpdatesService.m +0 -117
- /package/e2e/fixtures/{test.png → project_files/includedAssets/test.png} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,71 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 0.24.0 — 2023-12-12
|
|
14
|
+
|
|
15
|
+
### 🛠 Breaking changes
|
|
16
|
+
|
|
17
|
+
- Add state machine procedure serial runner. ([#25386](https://github.com/expo/expo/pull/25386), [#25431](https://github.com/expo/expo/pull/25431) by [@wschurman](https://github.com/wschurman))
|
|
18
|
+
|
|
19
|
+
### 🎉 New features
|
|
20
|
+
|
|
21
|
+
- [Android] Asset exclusion on Android part 2. ([#25504](https://github.com/expo/expo/pull/25504) by [@douglowder](https://github.com/douglowder))
|
|
22
|
+
- Added support for React Native 0.73.0. ([#24971](https://github.com/expo/expo/pull/24971), [#25453](https://github.com/expo/expo/pull/25453) by [@gabrieldonadel](https://github.com/gabrieldonadel))
|
|
23
|
+
|
|
24
|
+
### 🐛 Bug fixes
|
|
25
|
+
|
|
26
|
+
- [Android] Fix interaction between reload JS API and ErrorRecovery. ([#25651](https://github.com/expo/expo/pull/25651) by [@wschurman](https://github.com/wschurman))
|
|
27
|
+
- [Android] Fix wait notify bug in launch asset when enabled. ([#25676](https://github.com/expo/expo/pull/25676) by [@wschurman](https://github.com/wschurman))
|
|
28
|
+
|
|
29
|
+
### 💡 Others
|
|
30
|
+
|
|
31
|
+
- Update E2E tests to use local copies of `@expo/metro-config`, `@expo/env`, `@expo/config`. ([#25430](https://github.com/expo/expo/pull/25430) by [@EvanBacon](https://github.com/EvanBacon))
|
|
32
|
+
- Add e2e tests for disabled mode. ([#25301](https://github.com/expo/expo/pull/25301) by [@wschurman](https://github.com/wschurman))
|
|
33
|
+
- Modify E2E manual test for asset exclusion. ([#25406](https://github.com/expo/expo/pull/25406) by [@douglowder](https://github.com/douglowder))
|
|
34
|
+
- Move tvOS compile test out of updates E2E test matrix. ([#25438](https://github.com/expo/expo/pull/25438) by [@douglowder](https://github.com/douglowder))
|
|
35
|
+
- Assert valid state transitions in debug. ([#25474](https://github.com/expo/expo/pull/25474) by [@wschurman](https://github.com/wschurman))
|
|
36
|
+
- Improve JS API error messages and documentation for Expo Go and Dev Client. ([#25751](https://github.com/expo/expo/pull/25751) by [@wschurman](https://github.com/wschurman))
|
|
37
|
+
|
|
38
|
+
## 0.23.0 — 2023-11-14
|
|
39
|
+
|
|
40
|
+
### 🛠 Breaking changes
|
|
41
|
+
|
|
42
|
+
- Bumped iOS deployment target to 13.4. ([#25063](https://github.com/expo/expo/pull/25063) by [@gabrieldonadel](https://github.com/gabrieldonadel))
|
|
43
|
+
- Split updates controllers depending on configuration, changing native public API. ([#25085](https://github.com/expo/expo/pull/25085), [#25192](https://github.com/expo/expo/pull/25192) by [@wschurman](https://github.com/wschurman))
|
|
44
|
+
- On `Android` bump `compileSdkVersion` and `targetSdkVersion` to `34`. ([#24708](https://github.com/expo/expo/pull/24708) by [@alanjhughes](https://github.com/alanjhughes))
|
|
45
|
+
|
|
46
|
+
### 🎉 New features
|
|
47
|
+
|
|
48
|
+
- [iOS] Make asset exclusion work. ([#25216](https://github.com/expo/expo/pull/25216) by [@douglowder](https://github.com/douglowder))
|
|
49
|
+
- [Android] Asset exclusion on Android part 1. ([#25277](https://github.com/expo/expo/pull/25277) by [@douglowder](https://github.com/douglowder))
|
|
50
|
+
|
|
51
|
+
### 🐛 Bug fixes
|
|
52
|
+
|
|
53
|
+
- [iOS] Fix the E2E tests. ([#24865](https://github.com/expo/expo/pull/24865) by [@douglowder](https://github.com/douglowder))
|
|
54
|
+
- [Android] Simplify UpdatesUtils.parseDateString, fix UpdatesLoggingTest. ([#24951](https://github.com/expo/expo/pull/24951) by [@douglowder](https://github.com/douglowder))
|
|
55
|
+
- [iOS] Fix expo-localization tvOS compile, add CI. ([#25082](https://github.com/expo/expo/pull/25082) by [@douglowder](https://github.com/douglowder))
|
|
56
|
+
- Fix instrumentation tests. ([#25367](https://github.com/expo/expo/pull/25367) by [@wschurman](https://github.com/wschurman))
|
|
57
|
+
|
|
58
|
+
### 💡 Others
|
|
59
|
+
|
|
60
|
+
- Android: Stub expo-updates in Expo Go and remove service pattern. ([#24890](https://github.com/expo/expo/pull/24890) by [@wschurman](https://github.com/wschurman))
|
|
61
|
+
- iOS: Refactor responsibility of app controller. ([#24934](https://github.com/expo/expo/pull/24934), [#24949](https://github.com/expo/expo/pull/24949) by [@wschurman](https://github.com/wschurman))
|
|
62
|
+
- Android: Refactor responsibility of app controller. ([#24954](https://github.com/expo/expo/pull/24954), [#24975](https://github.com/expo/expo/pull/24975), [#25043](https://github.com/expo/expo/pull/25043) by [@wschurman](https://github.com/wschurman))
|
|
63
|
+
- Android: Backport ExpoGoUpdatesModule to SDK 49. ([#24974](https://github.com/expo/expo/pull/24974) by [@wschurman](https://github.com/wschurman))
|
|
64
|
+
- Remove unused `storedUpdateIdsWithConfiguration` method. ([#25194](https://github.com/expo/expo/pull/25194) by [@wschurman](https://github.com/wschurman))
|
|
65
|
+
- Remove ability for embedded manifests to be legacy manifests. ([#25195](https://github.com/expo/expo/pull/25195) by [@wschurman](https://github.com/wschurman))
|
|
66
|
+
- Convert e2e setup scripts to typescript. ([#25271](https://github.com/expo/expo/pull/25271) by [@wschurman](https://github.com/wschurman))
|
|
67
|
+
|
|
68
|
+
### ⚠️ Notices
|
|
69
|
+
|
|
70
|
+
- Deprecated `useUpdateEvents()` and `addListener()` in favor of the new `useUpdates()` API. ([#25345](https://github.com/expo/expo/pull/25345) by [@douglowder](https://github.com/douglowder))
|
|
71
|
+
|
|
72
|
+
## 0.18.17 — 2023-10-25
|
|
73
|
+
|
|
74
|
+
### 🐛 Bug fixes
|
|
75
|
+
|
|
76
|
+
- [Android] Simplify UpdatesUtils.parseDateString, fix UpdatesLoggingTest. ([#24951](https://github.com/expo/expo/pull/24951) by [@douglowder](https://github.com/douglowder))
|
|
77
|
+
|
|
13
78
|
## 0.22.0 — 2023-10-17
|
|
14
79
|
|
|
15
80
|
### 🐛 Bug fixes
|
|
@@ -20,6 +85,7 @@
|
|
|
20
85
|
### 💡 Others
|
|
21
86
|
|
|
22
87
|
- Transpile for Node 18 (LTS). ([#24471](https://github.com/expo/expo/pull/24471) by [@EvanBacon](https://github.com/EvanBacon))
|
|
88
|
+
- iOS: Stub expo-updates in Expo Go and remove service pattern. ([#24860](https://github.com/expo/expo/pull/24860) by [@wschurman](https://github.com/wschurman))
|
|
23
89
|
|
|
24
90
|
## 0.18.16 — 2023-10-05
|
|
25
91
|
|
package/android/build.gradle
CHANGED
|
@@ -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.
|
|
7
|
+
version = '0.24.0'
|
|
8
8
|
|
|
9
9
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
10
10
|
if (expoModulesCorePlugin.exists()) {
|
|
@@ -89,11 +89,11 @@ if (!safeExtGet("expoProvidesDefaultConfig", false)) {
|
|
|
89
89
|
android {
|
|
90
90
|
// Remove this if and it's contents, when support for SDK49 is dropped
|
|
91
91
|
if (!safeExtGet("expoProvidesDefaultConfig", false)) {
|
|
92
|
-
compileSdkVersion safeExtGet("compileSdkVersion",
|
|
92
|
+
compileSdkVersion safeExtGet("compileSdkVersion", 34)
|
|
93
93
|
|
|
94
94
|
defaultConfig {
|
|
95
95
|
minSdkVersion safeExtGet("minSdkVersion", 23)
|
|
96
|
-
targetSdkVersion safeExtGet("targetSdkVersion",
|
|
96
|
+
targetSdkVersion safeExtGet("targetSdkVersion", 34)
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
publishing {
|
|
@@ -122,7 +122,7 @@ android {
|
|
|
122
122
|
namespace "expo.modules.updates"
|
|
123
123
|
defaultConfig {
|
|
124
124
|
versionCode 31
|
|
125
|
-
versionName '0.
|
|
125
|
+
versionName '0.24.0'
|
|
126
126
|
consumerProguardFiles("proguard-rules.pro")
|
|
127
127
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
128
128
|
|
|
@@ -174,6 +174,8 @@ dependencies {
|
|
|
174
174
|
implementation("commons-codec:commons-codec:1.10")
|
|
175
175
|
implementation("commons-io:commons-io:2.6")
|
|
176
176
|
implementation("commons-fileupload:commons-fileupload:1.4")
|
|
177
|
+
implementation("javax.portlet:portlet-api:3.0.1")
|
|
178
|
+
implementation("javax.servlet:javax.servlet-api:4.0.1")
|
|
177
179
|
implementation("org.apache.commons:commons-lang3:3.9")
|
|
178
180
|
implementation("org.bouncycastle:bcutil-jdk15to18:1.70")
|
|
179
181
|
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
package expo.modules.updates
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.os.Bundle
|
|
5
|
+
import android.util.Log
|
|
6
|
+
import com.facebook.react.ReactInstanceManager
|
|
7
|
+
import expo.modules.kotlin.exception.CodedException
|
|
8
|
+
import expo.modules.updates.UpdatesConfiguration.Companion.UPDATES_CONFIGURATION_RELEASE_CHANNEL_DEFAULT_VALUE
|
|
9
|
+
import expo.modules.updates.launcher.Launcher
|
|
10
|
+
import expo.modules.updates.launcher.NoDatabaseLauncher
|
|
11
|
+
import expo.modules.updates.statemachine.UpdatesStateContext
|
|
12
|
+
import java.io.File
|
|
13
|
+
|
|
14
|
+
// this needs to stay for versioning to work
|
|
15
|
+
/* ktlint-disable no-unused-imports */
|
|
16
|
+
import expo.modules.updates.UpdatesConfiguration
|
|
17
|
+
/* ktlint-enable no-unused-imports */
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Updates controller for applications that either disable updates explicitly or have an error
|
|
21
|
+
* during initialization. Errors that may occur include but are not limited to:
|
|
22
|
+
* - Disk access errors
|
|
23
|
+
* - Internal database initialization errors
|
|
24
|
+
* - Configuration errors (missing required configuration)
|
|
25
|
+
*/
|
|
26
|
+
class DisabledUpdatesController(
|
|
27
|
+
private val context: Context,
|
|
28
|
+
private val fatalException: Exception?,
|
|
29
|
+
private val isMissingRuntimeVersion: Boolean
|
|
30
|
+
) : IUpdatesController {
|
|
31
|
+
private var isStarted = false
|
|
32
|
+
private var launcher: Launcher? = null
|
|
33
|
+
private var isLoaderTaskFinished = false
|
|
34
|
+
override var updatesDirectory: File? = null
|
|
35
|
+
|
|
36
|
+
override var isEmergencyLaunch = false
|
|
37
|
+
private set
|
|
38
|
+
|
|
39
|
+
@get:Synchronized
|
|
40
|
+
override val launchAssetFile: String?
|
|
41
|
+
get() {
|
|
42
|
+
while (!isLoaderTaskFinished) {
|
|
43
|
+
try {
|
|
44
|
+
(this as java.lang.Object).wait()
|
|
45
|
+
} catch (e: InterruptedException) {
|
|
46
|
+
Log.e(TAG, "Interrupted while waiting for launch asset file", e)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return launcher?.launchAssetFile
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
override val bundleAssetName: String?
|
|
53
|
+
get() = launcher?.bundleAssetName
|
|
54
|
+
|
|
55
|
+
override fun onDidCreateReactInstanceManager(reactInstanceManager: ReactInstanceManager) {}
|
|
56
|
+
|
|
57
|
+
@Synchronized
|
|
58
|
+
override fun start() {
|
|
59
|
+
if (isStarted) {
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
isStarted = true
|
|
63
|
+
|
|
64
|
+
launcher = NoDatabaseLauncher(context, fatalException)
|
|
65
|
+
isEmergencyLaunch = fatalException != null
|
|
66
|
+
notifyController()
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
class UpdatesDisabledException(message: String) : CodedException(message)
|
|
71
|
+
|
|
72
|
+
override fun getConstantsForModule(): IUpdatesController.UpdatesModuleConstants {
|
|
73
|
+
return IUpdatesController.UpdatesModuleConstants(
|
|
74
|
+
launchedUpdate = launcher?.launchedUpdate,
|
|
75
|
+
embeddedUpdate = null,
|
|
76
|
+
isEmergencyLaunch = isEmergencyLaunch,
|
|
77
|
+
isEnabled = false,
|
|
78
|
+
releaseChannel = UPDATES_CONFIGURATION_RELEASE_CHANNEL_DEFAULT_VALUE,
|
|
79
|
+
isUsingEmbeddedAssets = launcher?.isUsingEmbeddedAssets ?: false,
|
|
80
|
+
runtimeVersion = null,
|
|
81
|
+
checkOnLaunch = UpdatesConfiguration.CheckAutomaticallyConfiguration.NEVER,
|
|
82
|
+
requestHeaders = mapOf(),
|
|
83
|
+
localAssetFiles = launcher?.localAssetFiles,
|
|
84
|
+
isMissingRuntimeVersion = isMissingRuntimeVersion,
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
override fun relaunchReactApplicationForModule(callback: IUpdatesController.ModuleCallback<Unit>) {
|
|
89
|
+
callback.onFailure(UpdatesDisabledException("You cannot reload when expo-updates is not enabled."))
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
override fun getNativeStateMachineContext(callback: IUpdatesController.ModuleCallback<UpdatesStateContext>) {
|
|
93
|
+
callback.onFailure(UpdatesDisabledException("You cannot check for updates when expo-updates is not enabled."))
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
override fun checkForUpdate(
|
|
97
|
+
callback: IUpdatesController.ModuleCallback<IUpdatesController.CheckForUpdateResult>
|
|
98
|
+
) {
|
|
99
|
+
callback.onFailure(UpdatesDisabledException("You cannot check for updates when expo-updates is not enabled."))
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
override fun fetchUpdate(
|
|
103
|
+
callback: IUpdatesController.ModuleCallback<IUpdatesController.FetchUpdateResult>
|
|
104
|
+
) {
|
|
105
|
+
callback.onFailure(UpdatesDisabledException("You cannot fetch update when expo-updates is not enabled."))
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
override fun getExtraParams(callback: IUpdatesController.ModuleCallback<Bundle>) {
|
|
109
|
+
callback.onFailure(UpdatesDisabledException("You cannot use extra params when expo-updates is not enabled."))
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
override fun setExtraParam(
|
|
113
|
+
key: String,
|
|
114
|
+
value: String?,
|
|
115
|
+
callback: IUpdatesController.ModuleCallback<Unit>
|
|
116
|
+
) {
|
|
117
|
+
callback.onFailure(UpdatesDisabledException("You cannot use extra params when expo-updates is not enabled."))
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@Synchronized
|
|
121
|
+
private fun notifyController() {
|
|
122
|
+
if (launcher == null) {
|
|
123
|
+
throw AssertionError("UpdatesController.notifyController was called with a null launcher, which is an error. This method should only be called when an update is ready to launch.")
|
|
124
|
+
}
|
|
125
|
+
isLoaderTaskFinished = true
|
|
126
|
+
(this as java.lang.Object).notify()
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
companion object {
|
|
130
|
+
private val TAG = DisabledUpdatesController::class.java.simpleName
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
package expo.modules.updates
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.os.AsyncTask
|
|
5
|
+
import android.os.Bundle
|
|
6
|
+
import android.util.Log
|
|
7
|
+
import com.facebook.react.ReactApplication
|
|
8
|
+
import com.facebook.react.ReactInstanceManager
|
|
9
|
+
import com.facebook.react.ReactNativeHost
|
|
10
|
+
import com.facebook.react.bridge.Arguments
|
|
11
|
+
import com.facebook.react.bridge.WritableMap
|
|
12
|
+
import expo.modules.kotlin.exception.CodedException
|
|
13
|
+
import expo.modules.kotlin.exception.toCodedException
|
|
14
|
+
import expo.modules.updates.db.BuildData
|
|
15
|
+
import expo.modules.updates.db.DatabaseHolder
|
|
16
|
+
import expo.modules.updates.db.UpdatesDatabase
|
|
17
|
+
import expo.modules.updates.launcher.Launcher.LauncherCallback
|
|
18
|
+
import expo.modules.updates.loader.FileDownloader
|
|
19
|
+
import expo.modules.updates.logging.UpdatesLogReader
|
|
20
|
+
import expo.modules.updates.logging.UpdatesLogger
|
|
21
|
+
import expo.modules.updates.manifest.EmbeddedManifest
|
|
22
|
+
import expo.modules.updates.manifest.ManifestMetadata
|
|
23
|
+
import expo.modules.updates.procedures.CheckForUpdateProcedure
|
|
24
|
+
import expo.modules.updates.procedures.FetchUpdateProcedure
|
|
25
|
+
import expo.modules.updates.procedures.RelaunchProcedure
|
|
26
|
+
import expo.modules.updates.selectionpolicy.SelectionPolicyFactory
|
|
27
|
+
import expo.modules.updates.procedures.StartupProcedure
|
|
28
|
+
import expo.modules.updates.statemachine.UpdatesStateChangeEventSender
|
|
29
|
+
import expo.modules.updates.statemachine.UpdatesStateContext
|
|
30
|
+
import expo.modules.updates.statemachine.UpdatesStateEventType
|
|
31
|
+
import expo.modules.updates.statemachine.UpdatesStateMachine
|
|
32
|
+
import java.io.File
|
|
33
|
+
import java.lang.ref.WeakReference
|
|
34
|
+
|
|
35
|
+
// this needs to stay for versioning to work
|
|
36
|
+
/* ktlint-disable no-unused-imports */
|
|
37
|
+
import expo.modules.updates.UpdatesConfiguration
|
|
38
|
+
/* ktlint-enable no-unused-imports */
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Updates controller for applications that have updates enabled and properly-configured.
|
|
42
|
+
*/
|
|
43
|
+
class EnabledUpdatesController(
|
|
44
|
+
private val context: Context,
|
|
45
|
+
private val updatesConfiguration: UpdatesConfiguration,
|
|
46
|
+
override val updatesDirectory: File
|
|
47
|
+
) : IUpdatesController, UpdatesStateChangeEventSender {
|
|
48
|
+
private var reactNativeHost: WeakReference<ReactNativeHost>? = if (context is ReactApplication) {
|
|
49
|
+
WeakReference(context.reactNativeHost)
|
|
50
|
+
} else {
|
|
51
|
+
null
|
|
52
|
+
}
|
|
53
|
+
private val logger = UpdatesLogger(context)
|
|
54
|
+
private val fileDownloader = FileDownloader(context)
|
|
55
|
+
private val selectionPolicy = SelectionPolicyFactory.createFilterAwarePolicy(
|
|
56
|
+
updatesConfiguration.getRuntimeVersion()
|
|
57
|
+
)
|
|
58
|
+
private val stateMachine = UpdatesStateMachine(context, this)
|
|
59
|
+
private val databaseHolder = DatabaseHolder(UpdatesDatabase.getInstance(context))
|
|
60
|
+
|
|
61
|
+
private fun purgeUpdatesLogsOlderThanOneDay() {
|
|
62
|
+
UpdatesLogReader(context).purgeLogEntries {
|
|
63
|
+
if (it != null) {
|
|
64
|
+
Log.e(TAG, "UpdatesLogReader: error in purgeLogEntries", it)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private var isStarted = false
|
|
70
|
+
|
|
71
|
+
private var isStartupFinished = false
|
|
72
|
+
|
|
73
|
+
@Synchronized
|
|
74
|
+
private fun onStartupProcedureFinished() {
|
|
75
|
+
isStartupFinished = true
|
|
76
|
+
(this@EnabledUpdatesController as java.lang.Object).notify()
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private val startupProcedure = StartupProcedure(
|
|
80
|
+
context,
|
|
81
|
+
updatesConfiguration,
|
|
82
|
+
databaseHolder,
|
|
83
|
+
updatesDirectory,
|
|
84
|
+
fileDownloader,
|
|
85
|
+
selectionPolicy,
|
|
86
|
+
logger,
|
|
87
|
+
object : StartupProcedure.StartupProcedureCallback {
|
|
88
|
+
override fun onFinished() {
|
|
89
|
+
onStartupProcedureFinished()
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
override fun onLegacyJSEvent(event: StartupProcedure.StartupProcedureCallback.LegacyJSEvent) {
|
|
93
|
+
when (event) {
|
|
94
|
+
is StartupProcedure.StartupProcedureCallback.LegacyJSEvent.Error -> sendLegacyUpdateEventToJS(
|
|
95
|
+
UPDATE_ERROR_EVENT,
|
|
96
|
+
Arguments.createMap().apply {
|
|
97
|
+
putString("message", event.exception.message)
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
is StartupProcedure.StartupProcedureCallback.LegacyJSEvent.NoUpdateAvailable -> sendLegacyUpdateEventToJS(UPDATE_NO_UPDATE_AVAILABLE_EVENT, null)
|
|
101
|
+
is StartupProcedure.StartupProcedureCallback.LegacyJSEvent.UpdateAvailable -> sendLegacyUpdateEventToJS(
|
|
102
|
+
UPDATE_AVAILABLE_EVENT,
|
|
103
|
+
Arguments.createMap().apply {
|
|
104
|
+
putString("manifestString", event.manifest.toString())
|
|
105
|
+
}
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
override fun onRequestRelaunch(shouldRunReaper: Boolean, callback: LauncherCallback) {
|
|
111
|
+
relaunchReactApplication(shouldRunReaper, callback)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
private val launchedUpdate
|
|
117
|
+
get() = startupProcedure.launchedUpdate
|
|
118
|
+
private val isUsingEmbeddedAssets
|
|
119
|
+
get() = startupProcedure.isUsingEmbeddedAssets
|
|
120
|
+
private val localAssetFiles
|
|
121
|
+
get() = startupProcedure.localAssetFiles
|
|
122
|
+
override val isEmergencyLaunch: Boolean
|
|
123
|
+
get() = startupProcedure.isEmergencyLaunch
|
|
124
|
+
|
|
125
|
+
@get:Synchronized
|
|
126
|
+
override val launchAssetFile: String?
|
|
127
|
+
get() {
|
|
128
|
+
while (!isStartupFinished) {
|
|
129
|
+
try {
|
|
130
|
+
(this as java.lang.Object).wait()
|
|
131
|
+
} catch (e: InterruptedException) {
|
|
132
|
+
Log.e(TAG, "Interrupted while waiting for launch asset file", e)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return startupProcedure.launchAssetFile
|
|
136
|
+
}
|
|
137
|
+
override val bundleAssetName: String?
|
|
138
|
+
get() = startupProcedure.bundleAssetName
|
|
139
|
+
|
|
140
|
+
override fun onDidCreateReactInstanceManager(reactInstanceManager: ReactInstanceManager) {
|
|
141
|
+
startupProcedure.onDidCreateReactInstanceManager(reactInstanceManager)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
@Synchronized
|
|
145
|
+
override fun start() {
|
|
146
|
+
if (isStarted) {
|
|
147
|
+
return
|
|
148
|
+
}
|
|
149
|
+
isStarted = true
|
|
150
|
+
|
|
151
|
+
purgeUpdatesLogsOlderThanOneDay()
|
|
152
|
+
|
|
153
|
+
BuildData.ensureBuildDataIsConsistent(updatesConfiguration, databaseHolder.database)
|
|
154
|
+
databaseHolder.releaseDatabase()
|
|
155
|
+
|
|
156
|
+
stateMachine.queueExecution(startupProcedure)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
private fun relaunchReactApplication(shouldRunReaper: Boolean, callback: LauncherCallback) {
|
|
160
|
+
val procedure = RelaunchProcedure(
|
|
161
|
+
context,
|
|
162
|
+
updatesConfiguration,
|
|
163
|
+
databaseHolder,
|
|
164
|
+
updatesDirectory,
|
|
165
|
+
fileDownloader,
|
|
166
|
+
selectionPolicy,
|
|
167
|
+
reactNativeHost,
|
|
168
|
+
getCurrentLauncher = { startupProcedure.launcher!! },
|
|
169
|
+
setCurrentLauncher = { currentLauncher -> startupProcedure.setLauncher(currentLauncher) },
|
|
170
|
+
shouldRunReaper = shouldRunReaper,
|
|
171
|
+
callback
|
|
172
|
+
)
|
|
173
|
+
stateMachine.queueExecution(procedure)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
override fun sendUpdateStateChangeEventToBridge(eventType: UpdatesStateEventType, context: UpdatesStateContext) {
|
|
177
|
+
sendEventToJS(UPDATES_STATE_CHANGE_EVENT_NAME, eventType.type, context.writableMap)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private fun sendLegacyUpdateEventToJS(eventType: String, params: WritableMap?) {
|
|
181
|
+
sendEventToJS(UPDATES_EVENT_NAME, eventType, params)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private fun sendEventToJS(eventName: String, eventType: String, params: WritableMap?) {
|
|
185
|
+
UpdatesUtils.sendEventToReactNative(reactNativeHost, logger, eventName, eventType, params)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
override fun getConstantsForModule(): IUpdatesController.UpdatesModuleConstants {
|
|
189
|
+
return IUpdatesController.UpdatesModuleConstants(
|
|
190
|
+
launchedUpdate = launchedUpdate,
|
|
191
|
+
embeddedUpdate = EmbeddedManifest.get(context, updatesConfiguration)?.updateEntity,
|
|
192
|
+
isEmergencyLaunch = isEmergencyLaunch,
|
|
193
|
+
isEnabled = true,
|
|
194
|
+
releaseChannel = updatesConfiguration.releaseChannel,
|
|
195
|
+
isUsingEmbeddedAssets = isUsingEmbeddedAssets,
|
|
196
|
+
runtimeVersion = updatesConfiguration.runtimeVersionRaw,
|
|
197
|
+
checkOnLaunch = updatesConfiguration.checkOnLaunch,
|
|
198
|
+
requestHeaders = updatesConfiguration.requestHeaders,
|
|
199
|
+
localAssetFiles = localAssetFiles,
|
|
200
|
+
isMissingRuntimeVersion = false,
|
|
201
|
+
)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
override fun relaunchReactApplicationForModule(callback: IUpdatesController.ModuleCallback<Unit>) {
|
|
205
|
+
val canRelaunch = launchedUpdate != null
|
|
206
|
+
if (!canRelaunch) {
|
|
207
|
+
callback.onFailure(object : CodedException("ERR_UPDATES_RELOAD", "Cannot relaunch without a launched update.", null) {})
|
|
208
|
+
} else {
|
|
209
|
+
relaunchReactApplication(
|
|
210
|
+
shouldRunReaper = true,
|
|
211
|
+
object : LauncherCallback {
|
|
212
|
+
override fun onFailure(e: Exception) {
|
|
213
|
+
callback.onFailure(e.toCodedException())
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
override fun onSuccess() {
|
|
217
|
+
callback.onSuccess(Unit)
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
override fun getNativeStateMachineContext(callback: IUpdatesController.ModuleCallback<UpdatesStateContext>) {
|
|
225
|
+
callback.onSuccess(stateMachine.context)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
override fun checkForUpdate(callback: IUpdatesController.ModuleCallback<IUpdatesController.CheckForUpdateResult>) {
|
|
229
|
+
val procedure = CheckForUpdateProcedure(context, updatesConfiguration, databaseHolder, logger, fileDownloader, selectionPolicy, launchedUpdate) {
|
|
230
|
+
callback.onSuccess(it)
|
|
231
|
+
}
|
|
232
|
+
stateMachine.queueExecution(procedure)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
override fun fetchUpdate(callback: IUpdatesController.ModuleCallback<IUpdatesController.FetchUpdateResult>) {
|
|
236
|
+
val procedure = FetchUpdateProcedure(context, updatesConfiguration, databaseHolder, updatesDirectory, fileDownloader, selectionPolicy, launchedUpdate) {
|
|
237
|
+
callback.onSuccess(it)
|
|
238
|
+
}
|
|
239
|
+
stateMachine.queueExecution(procedure)
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
override fun getExtraParams(callback: IUpdatesController.ModuleCallback<Bundle>) {
|
|
243
|
+
AsyncTask.execute {
|
|
244
|
+
try {
|
|
245
|
+
val result = ManifestMetadata.getExtraParams(
|
|
246
|
+
databaseHolder.database,
|
|
247
|
+
updatesConfiguration,
|
|
248
|
+
)
|
|
249
|
+
databaseHolder.releaseDatabase()
|
|
250
|
+
val resultMap = when (result) {
|
|
251
|
+
null -> Bundle()
|
|
252
|
+
else -> {
|
|
253
|
+
Bundle().apply {
|
|
254
|
+
result.forEach {
|
|
255
|
+
putString(it.key, it.value)
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
callback.onSuccess(resultMap)
|
|
261
|
+
} catch (e: Exception) {
|
|
262
|
+
databaseHolder.releaseDatabase()
|
|
263
|
+
callback.onFailure(e.toCodedException())
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
override fun setExtraParam(key: String, value: String?, callback: IUpdatesController.ModuleCallback<Unit>) {
|
|
269
|
+
AsyncTask.execute {
|
|
270
|
+
try {
|
|
271
|
+
ManifestMetadata.setExtraParam(
|
|
272
|
+
databaseHolder.database,
|
|
273
|
+
updatesConfiguration,
|
|
274
|
+
key,
|
|
275
|
+
value
|
|
276
|
+
)
|
|
277
|
+
databaseHolder.releaseDatabase()
|
|
278
|
+
callback.onSuccess(Unit)
|
|
279
|
+
} catch (e: Exception) {
|
|
280
|
+
databaseHolder.releaseDatabase()
|
|
281
|
+
callback.onFailure(e.toCodedException())
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
companion object {
|
|
287
|
+
private val TAG = EnabledUpdatesController::class.java.simpleName
|
|
288
|
+
|
|
289
|
+
private const val UPDATE_AVAILABLE_EVENT = "updateAvailable"
|
|
290
|
+
private const val UPDATE_NO_UPDATE_AVAILABLE_EVENT = "noUpdateAvailable"
|
|
291
|
+
private const val UPDATE_ERROR_EVENT = "error"
|
|
292
|
+
|
|
293
|
+
private const val UPDATES_EVENT_NAME = "Expo.nativeUpdatesEvent"
|
|
294
|
+
private const val UPDATES_STATE_CHANGE_EVENT_NAME = "Expo.nativeUpdatesStateChangeEvent"
|
|
295
|
+
}
|
|
296
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
package expo.modules.updates
|
|
2
|
+
|
|
3
|
+
import android.os.Bundle
|
|
4
|
+
import com.facebook.react.ReactApplication
|
|
5
|
+
import com.facebook.react.ReactInstanceManager
|
|
6
|
+
import expo.modules.kotlin.exception.CodedException
|
|
7
|
+
import expo.modules.updates.db.entity.AssetEntity
|
|
8
|
+
import expo.modules.updates.db.entity.UpdateEntity
|
|
9
|
+
import expo.modules.updates.loader.LoaderTask
|
|
10
|
+
import expo.modules.updates.manifest.UpdateManifest
|
|
11
|
+
import expo.modules.updates.statemachine.UpdatesStateContext
|
|
12
|
+
import java.io.File
|
|
13
|
+
import java.util.Date
|
|
14
|
+
|
|
15
|
+
interface IUpdatesController {
|
|
16
|
+
val isEmergencyLaunch: Boolean
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The path on disk to the launch asset (JS bundle) file for the React Native host to use.
|
|
20
|
+
* Blocks until the configured timeout runs out, or a new update has been downloaded and is ready
|
|
21
|
+
* to use (whichever comes sooner). ReactNativeHost.getJSBundleFile() should call into this.
|
|
22
|
+
*
|
|
23
|
+
* If this returns null, something has gone wrong and expo-updates has not been able to launch or
|
|
24
|
+
* find an update to use. In (and only in) this case, `getBundleAssetName()` will return a nonnull
|
|
25
|
+
* fallback value to use.
|
|
26
|
+
*/
|
|
27
|
+
val launchAssetFile: String?
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Returns the filename of the launch asset (JS bundle) file embedded in the APK bundle, which can
|
|
31
|
+
* be read using `context.getAssets()`. This is only nonnull if `getLaunchAssetFile` is null and
|
|
32
|
+
* should only be used in such a situation. ReactNativeHost.getBundleAssetName() should call into
|
|
33
|
+
* this.
|
|
34
|
+
*/
|
|
35
|
+
val bundleAssetName: String?
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Public for E2E tests.
|
|
39
|
+
*/
|
|
40
|
+
val updatesDirectory: File?
|
|
41
|
+
|
|
42
|
+
fun onDidCreateReactInstanceManager(reactInstanceManager: ReactInstanceManager)
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Starts the update process to launch a previously-loaded update and (if configured to do so)
|
|
46
|
+
* check for a new update from the server. This method should be called as early as possible in
|
|
47
|
+
* the application's lifecycle.
|
|
48
|
+
* @param context the base context of the application, ideally a [ReactApplication]
|
|
49
|
+
*/
|
|
50
|
+
fun start()
|
|
51
|
+
|
|
52
|
+
interface ModuleCallback<T> {
|
|
53
|
+
fun onSuccess(result: T)
|
|
54
|
+
fun onFailure(exception: CodedException)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
data class UpdatesModuleConstants(
|
|
58
|
+
val launchedUpdate: UpdateEntity?,
|
|
59
|
+
val embeddedUpdate: UpdateEntity?,
|
|
60
|
+
val isEmergencyLaunch: Boolean,
|
|
61
|
+
val isEnabled: Boolean,
|
|
62
|
+
val releaseChannel: String,
|
|
63
|
+
val isUsingEmbeddedAssets: Boolean,
|
|
64
|
+
val runtimeVersion: String?,
|
|
65
|
+
val checkOnLaunch: UpdatesConfiguration.CheckAutomaticallyConfiguration,
|
|
66
|
+
val requestHeaders: Map<String, String>,
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Returns a map of the locally downloaded assets for the current update. Keys are the remote URLs
|
|
70
|
+
* of the assets and values are local paths. This should be exported by the Updates JS module and
|
|
71
|
+
* can be used by `expo-asset` or a similar module to override React Native's asset resolution and
|
|
72
|
+
* use the locally downloaded assets.
|
|
73
|
+
*/
|
|
74
|
+
val localAssetFiles: Map<AssetEntity, String>?,
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Whether there is no runtime version (or sdkVersion) provided in configuration. If it is missing,
|
|
78
|
+
* updates will be disabled and a warning will be logged.
|
|
79
|
+
*/
|
|
80
|
+
val isMissingRuntimeVersion: Boolean,
|
|
81
|
+
)
|
|
82
|
+
fun getConstantsForModule(): UpdatesModuleConstants
|
|
83
|
+
|
|
84
|
+
fun relaunchReactApplicationForModule(callback: ModuleCallback<Unit>)
|
|
85
|
+
|
|
86
|
+
fun getNativeStateMachineContext(callback: ModuleCallback<UpdatesStateContext>)
|
|
87
|
+
|
|
88
|
+
sealed class CheckForUpdateResult(private val status: Status) {
|
|
89
|
+
private enum class Status {
|
|
90
|
+
NO_UPDATE_AVAILABLE,
|
|
91
|
+
UPDATE_AVAILABLE,
|
|
92
|
+
ROLL_BACK_TO_EMBEDDED,
|
|
93
|
+
ERROR
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
class NoUpdateAvailable(val reason: LoaderTask.RemoteCheckResultNotAvailableReason) : CheckForUpdateResult(Status.NO_UPDATE_AVAILABLE)
|
|
97
|
+
class UpdateAvailable(val updateManifest: UpdateManifest) : CheckForUpdateResult(Status.UPDATE_AVAILABLE)
|
|
98
|
+
class RollBackToEmbedded(val commitTime: Date) : CheckForUpdateResult(Status.ROLL_BACK_TO_EMBEDDED)
|
|
99
|
+
class ErrorResult(val error: Exception, val message: String) : CheckForUpdateResult(Status.ERROR)
|
|
100
|
+
}
|
|
101
|
+
fun checkForUpdate(callback: ModuleCallback<CheckForUpdateResult>)
|
|
102
|
+
|
|
103
|
+
sealed class FetchUpdateResult(private val status: Status) {
|
|
104
|
+
private enum class Status {
|
|
105
|
+
SUCCESS,
|
|
106
|
+
FAILURE,
|
|
107
|
+
ROLL_BACK_TO_EMBEDDED,
|
|
108
|
+
ERROR
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
class Success(val update: UpdateEntity) : FetchUpdateResult(Status.SUCCESS)
|
|
112
|
+
class Failure : FetchUpdateResult(Status.FAILURE)
|
|
113
|
+
class RollBackToEmbedded : FetchUpdateResult(Status.ROLL_BACK_TO_EMBEDDED)
|
|
114
|
+
class ErrorResult(val error: Exception) : FetchUpdateResult(Status.ERROR)
|
|
115
|
+
}
|
|
116
|
+
fun fetchUpdate(callback: ModuleCallback<FetchUpdateResult>)
|
|
117
|
+
|
|
118
|
+
fun getExtraParams(callback: ModuleCallback<Bundle>)
|
|
119
|
+
|
|
120
|
+
fun setExtraParam(key: String, value: String?, callback: ModuleCallback<Unit>)
|
|
121
|
+
}
|