expo-updates 1.0.0-canary-20250404-87e2506 → 29.0.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 +127 -0
- package/android/build.gradle +16 -7
- package/android/proguard-rules.pro +1 -1
- package/android/src/main/java/expo/modules/updates/DisabledUpdatesController.kt +48 -30
- package/android/src/main/java/expo/modules/updates/EnabledUpdatesController.kt +67 -36
- package/android/src/main/java/expo/modules/updates/IUpdatesController.kt +14 -12
- package/android/src/main/java/expo/modules/updates/UpdatesConfiguration.kt +80 -13
- package/android/src/main/java/expo/modules/updates/UpdatesConfigurationOverride.kt +29 -15
- package/android/src/main/java/expo/modules/updates/UpdatesController.kt +5 -1
- package/android/src/main/java/expo/modules/updates/UpdatesDevLauncherController.kt +93 -90
- package/android/src/main/java/expo/modules/updates/UpdatesModule.kt +104 -159
- package/android/src/main/java/expo/modules/updates/UpdatesPackage.kt +0 -26
- package/android/src/main/java/expo/modules/updates/UpdatesUtils.kt +4 -5
- package/android/src/main/java/expo/modules/updates/db/Converters.kt +22 -0
- package/android/src/main/java/expo/modules/updates/db/DatabaseHolder.kt +14 -23
- package/android/src/main/java/expo/modules/updates/db/UpdatesDatabase.kt +44 -24
- package/android/src/main/java/expo/modules/updates/db/dao/AssetDao.kt +16 -10
- package/android/src/main/java/expo/modules/updates/db/entity/AssetEntity.kt +9 -0
- package/android/src/main/java/expo/modules/updates/db/entity/UpdateEntity.kt +4 -1
- package/android/src/main/java/expo/modules/updates/launcher/DatabaseLauncher.kt +93 -83
- package/android/src/main/java/expo/modules/updates/launcher/NoDatabaseLauncher.kt +2 -2
- package/android/src/main/java/expo/modules/updates/loader/EmbeddedLoader.kt +34 -31
- package/android/src/main/java/expo/modules/updates/loader/FileDownloader.kt +357 -433
- package/android/src/main/java/expo/modules/updates/loader/Loader.kt +133 -174
- package/android/src/main/java/expo/modules/updates/loader/LoaderFiles.kt +7 -2
- package/android/src/main/java/expo/modules/updates/loader/LoaderTask.kt +192 -256
- package/android/src/main/java/expo/modules/updates/loader/RemoteLoader.kt +38 -55
- package/android/src/main/java/expo/modules/updates/manifest/EmbeddedManifestUtils.kt +36 -14
- package/android/src/main/java/expo/modules/updates/manifest/EmbeddedUpdate.kt +8 -3
- package/android/src/main/java/expo/modules/updates/manifest/ExpoUpdatesUpdate.kt +7 -3
- package/android/src/main/java/expo/modules/updates/procedures/CheckForUpdateProcedure.kt +120 -113
- package/android/src/main/java/expo/modules/updates/procedures/FetchUpdateProcedure.kt +72 -70
- package/android/src/main/java/expo/modules/updates/procedures/RecreateReactContextProcedure.kt +10 -5
- package/android/src/main/java/expo/modules/updates/procedures/RelaunchProcedure.kt +56 -41
- package/android/src/main/java/expo/modules/updates/procedures/StartupProcedure.kt +33 -50
- package/android/src/main/java/expo/modules/updates/procedures/StateMachineSerialExecutorQueue.kt +3 -1
- package/android/src/main/java/expo/modules/updates/reloadscreen/ReloadScreenConfiguration.kt +82 -0
- package/android/src/main/java/expo/modules/updates/reloadscreen/ReloadScreenManager.kt +100 -0
- package/android/src/main/java/expo/modules/updates/reloadscreen/ReloadScreenView.kt +162 -0
- package/android/src/main/java/expo/modules/updates/selectionpolicy/LauncherSelectionPolicyDevelopmentClient.kt +23 -0
- package/android/src/main/java/expo/modules/updates/selectionpolicy/LauncherSelectionPolicyFilterAware.kt +10 -13
- package/android/src/main/java/expo/modules/updates/selectionpolicy/LoaderSelectionPolicyDevelopmentClient.kt +80 -0
- package/android/src/main/java/expo/modules/updates/selectionpolicy/LoaderSelectionPolicyFilterAware.kt +26 -5
- package/android/src/main/java/expo/modules/updates/selectionpolicy/SelectionPolicyFactory.kt +5 -3
- package/android/src/main/java/expo/modules/updates/statemachine/UpdatesStateContext.kt +7 -0
- package/android/src/main/java/expo/modules/updates/statemachine/UpdatesStateEvent.kt +1 -0
- package/android/src/main/java/expo/modules/updates/statemachine/UpdatesStateEventType.kt +1 -0
- package/android/src/main/java/expo/modules/updates/statemachine/UpdatesStateMachine.kt +8 -2
- package/android/src/main/java/expo/modules/updates/utils/AndroidResourceAssetUtils.kt +120 -0
- package/android/src/shared/certificates/chainExpoProjectInformationViolationIntermediate.pem +24 -0
- package/android/src/shared/certificates/chainExpoProjectInformationViolationLeaf.pem +23 -0
- package/android/src/shared/certificates/chainExpoProjectInformationViolationRoot.pem +22 -0
- package/android/src/shared/certificates/chainIntermediate.pem +22 -0
- package/android/src/shared/certificates/chainLeaf.pem +23 -0
- package/android/src/shared/certificates/chainNotCAIntermediate.pem +22 -0
- package/android/src/shared/certificates/chainNotCALeaf.pem +23 -0
- package/android/src/shared/certificates/chainNotCARoot.pem +22 -0
- package/android/src/shared/certificates/chainPathLenViolationIntermediate.pem +22 -0
- package/android/src/shared/certificates/chainPathLenViolationLeaf.pem +23 -0
- package/android/src/shared/certificates/chainPathLenViolationRoot.pem +22 -0
- package/android/src/shared/certificates/chainRoot.pem +22 -0
- package/android/src/shared/certificates/invalidSignatureChainLeaf.pem +23 -0
- package/android/src/shared/certificates/noCodeSigningExtendedUsage.pem +17 -0
- package/android/src/shared/certificates/noKeyUsage.pem +17 -0
- package/android/src/shared/certificates/privatekeys/chainExpoProjectInformationViolationIntermediate-privateKey.pem +27 -0
- package/android/src/shared/certificates/privatekeys/chainExpoProjectInformationViolationLeaf-privateKey.pem +27 -0
- package/android/src/shared/certificates/privatekeys/chainExpoProjectInformationViolationRoot-privateKey.pem +27 -0
- package/android/src/shared/certificates/privatekeys/chainIntermediate-privateKey.pem +27 -0
- package/android/src/shared/certificates/privatekeys/chainLeaf-privateKey.pem +27 -0
- package/android/src/shared/certificates/privatekeys/chainNotCAIntermediate-privateKey.pem +27 -0
- package/android/src/shared/certificates/privatekeys/chainNotCALeaf-privateKey.pem +27 -0
- package/android/src/shared/certificates/privatekeys/chainNotCARoot-privateKey.pem +27 -0
- package/android/src/shared/certificates/privatekeys/chainPathLenViolationIntermediate-privateKey.pem +27 -0
- package/android/src/shared/certificates/privatekeys/chainPathLenViolationLeaf-privateKey.pem +27 -0
- package/android/src/shared/certificates/privatekeys/chainPathLenViolationRoot-privateKey.pem +27 -0
- package/android/src/shared/certificates/privatekeys/chainRoot-privateKey.pem +27 -0
- package/android/src/shared/certificates/privatekeys/noCodeSigningExtendedUsage-privateKey.pem +27 -0
- package/android/src/shared/certificates/privatekeys/noKeyUsage-privateKey.pem +27 -0
- package/android/src/shared/certificates/privatekeys/test-privateKey.pem +27 -0
- package/android/src/shared/certificates/privatekeys/validityExpired-privateKey.pem +27 -0
- package/android/src/shared/certificates/signatureInvalid.pem +18 -0
- package/android/src/shared/certificates/test.pem +18 -0
- package/android/src/shared/certificates/validityExpired.pem +17 -0
- package/build/ExpoUpdates.web.d.ts.map +1 -1
- package/build/ExpoUpdates.web.js +2 -1
- package/build/ExpoUpdates.web.js.map +1 -1
- package/build/ExpoUpdatesModule.types.d.ts +2 -2
- package/build/ExpoUpdatesModule.types.d.ts.map +1 -1
- package/build/ExpoUpdatesModule.types.js +1 -1
- package/build/ExpoUpdatesModule.types.js.map +1 -1
- package/build/ReloadScreen.types.d.ts +70 -0
- package/build/ReloadScreen.types.d.ts.map +1 -0
- package/build/ReloadScreen.types.js +2 -0
- package/build/ReloadScreen.types.js.map +1 -0
- package/build/Updates.d.ts +61 -3
- package/build/Updates.d.ts.map +1 -1
- package/build/Updates.js +103 -3
- package/build/Updates.js.map +1 -1
- package/build/Updates.types.d.ts +2 -0
- package/build/Updates.types.d.ts.map +1 -1
- package/build/Updates.types.js.map +1 -1
- package/build/UpdatesEmitter.d.ts.map +1 -1
- package/build/UpdatesEmitter.js.map +1 -1
- package/build/UseUpdates.types.d.ts +6 -0
- package/build/UseUpdates.types.d.ts.map +1 -1
- package/build/UseUpdates.types.js.map +1 -1
- package/build/UseUpdatesUtils.d.ts.map +1 -1
- package/build/UseUpdatesUtils.js +1 -0
- package/build/UseUpdatesUtils.js.map +1 -1
- package/cli/build/assetsVerify.js +17 -7
- package/cli/build/assetsVerifyAsync.js +7 -8
- package/cli/build/cli.js +17 -7
- package/cli/build/configureCodeSigning.js +17 -7
- package/cli/build/configureCodeSigningAsync.js +2 -3
- package/cli/build/generateCodeSigning.js +17 -7
- package/cli/build/generateCodeSigningAsync.js +1 -2
- package/cli/build/generateFingerprint.js +17 -7
- package/cli/build/resolveRuntimeVersion.js +17 -7
- package/cli/build/syncConfigurationToNative.js +17 -7
- package/cli/build/syncConfigurationToNativeAsync.js +5 -6
- package/cli/build/utils/args.js +20 -11
- package/cli/build/utils/dir.js +1 -2
- package/cli/build/utils/errors.js +2 -2
- package/cli/build/utils/log.js +8 -9
- package/cli/build/utils/modifyConfigAsync.d.ts +1 -1
- package/cli/build/utils/modifyConfigAsync.js +20 -11
- package/cli/build/utils/withConsoleDisabledAsync.js +1 -2
- package/cli/src/configureCodeSigningAsync.ts +1 -1
- package/cli/src/syncConfigurationToNativeAsync.ts +2 -2
- package/cli/src/utils/modifyConfigAsync.ts +2 -2
- package/e2e/README.md +17 -59
- package/e2e/fixtures/App.tsx +42 -6
- package/e2e/fixtures/custom_init/AppDelegate.swift +35 -18
- package/e2e/fixtures/project_files/.env +1 -0
- package/e2e/fixtures/project_files/maestro/maestro-test-executor.sh +60 -0
- package/e2e/fixtures/project_files/maestro/tests/assetRecovery_restoreAssetFiles.yml +81 -0
- package/e2e/fixtures/project_files/maestro/tests/basic_checkRequestHeaders.yml +19 -0
- package/e2e/fixtures/project_files/maestro/tests/basic_reload.yml +32 -0
- package/e2e/fixtures/project_files/maestro/tests/basic_rollback.yml +90 -0
- package/e2e/fixtures/project_files/maestro/tests/basic_runUpdate.yml +30 -0
- package/e2e/fixtures/project_files/maestro/tests/basic_startAndStop.yml +24 -0
- package/e2e/fixtures/project_files/maestro/tests/basic_updateInvalidAssetHash.yml +48 -0
- package/e2e/fixtures/project_files/maestro/tests/basic_updateInvalidHash.yml +30 -0
- package/e2e/fixtures/project_files/maestro/tests/basic_updateMultipleAssets.yml +33 -0
- package/e2e/fixtures/project_files/maestro/tests/basic_updateOldCommitTime.yml +33 -0
- package/e2e/fixtures/project_files/maestro/tests/beforeEach.yml +23 -0
- package/e2e/fixtures/project_files/maestro/tests/brickingDisabled_jsReloadUpdate.yml +47 -0
- package/e2e/fixtures/project_files/maestro/tests/brickingDisabled_runUpdate.yml +42 -0
- package/e2e/fixtures/project_files/maestro/tests/devClient_runUpdate.yml +42 -0
- package/e2e/fixtures/project_files/maestro/tests/devClient_verifyState.yml +41 -0
- package/e2e/fixtures/project_files/maestro/tests/disabled_verifyState.yml +61 -0
- package/e2e/fixtures/project_files/maestro/tests/errorRecovery_runUpdate.yml +67 -0
- package/e2e/fixtures/project_files/maestro/tests/fingerprint_runUpdate.yml +21 -0
- package/e2e/fixtures/project_files/maestro/tests/jsapi_runUpdate.yml +110 -0
- package/e2e/fixtures/project_files/maestro/tests/jsapi_setRequestHeadersOverride.yml +130 -0
- package/e2e/fixtures/project_files/maestro/tests/jsapi_stateMachine.yml +218 -0
- package/e2e/fixtures/project_files/maestro/tests/maestroUpdatesApi.js +77 -0
- package/e2e/fixtures/project_files/maestro/tests/startup_runFastUpdate.yml +19 -0
- package/e2e/fixtures/project_files/maestro/tests/startup_runSlowUpdate.yml +24 -0
- package/e2e/fixtures/project_files/maestro/tests/updates-e2e-bricking-measures-disabled.yml +6 -0
- package/e2e/fixtures/project_files/maestro/tests/updates-e2e-dev-client.yml +6 -0
- package/e2e/fixtures/project_files/maestro/tests/updates-e2e-disabled.yml +6 -0
- package/e2e/fixtures/project_files/maestro/tests/updates-e2e-enabled.yml +28 -0
- package/e2e/fixtures/project_files/maestro/tests/updates-e2e-error-recovery.yml +4 -0
- package/e2e/fixtures/project_files/maestro/tests/updates-e2e-fingerprint.yml +4 -0
- package/e2e/fixtures/project_files/maestro/tests/updates-e2e-startup.yml +6 -0
- package/e2e/fixtures/project_files/maestro/updates-server/server.ts +829 -0
- package/e2e/fixtures/project_files/maestro/updates-server/start.ts +17 -0
- package/e2e/fixtures/project_files/{e2e/tests/utils → maestro/updates-server}/update.ts +20 -13
- package/e2e/fixtures/project_files/scripts/check-android-emulator.ts +44 -0
- package/e2e/fixtures/project_files/scripts/generate-test-update-bundles.ts +9 -1
- package/e2e/setup/create-bricking-measures-disabled-eas-project.ts +3 -4
- package/e2e/setup/create-dev-client-eas-project.ts +12 -8
- package/e2e/setup/create-disabled-eas-project.ts +3 -3
- package/e2e/setup/create-eas-project-custom-init.ts +3 -5
- package/e2e/setup/create-eas-project-old-arch.ts +43 -0
- package/e2e/setup/create-eas-project-tv.ts +21 -8
- package/e2e/setup/create-eas-project.ts +3 -5
- package/e2e/setup/create-error-recovery-eas-project.ts +3 -4
- package/e2e/setup/create-fingerprint-eas-project.ts +3 -4
- package/e2e/setup/create-startup-eas-project.ts +3 -4
- package/e2e/setup/create-updates-test.ts +3 -5
- package/e2e/setup/project.ts +92 -105
- package/e2e/tsconfig.json +4 -0
- package/expo-updates-gradle-plugin/src/main/kotlin/expo/modules/updates/ExpoUpdatesPlugin.kt +9 -4
- package/ios/EXUpdates/AppController.swift +3 -0
- package/ios/EXUpdates/AppLauncher/AppLauncherWithDatabase.swift +12 -9
- package/ios/EXUpdates/AppLoader/AppLoader.swift +31 -3
- package/ios/EXUpdates/AppLoader/AppLoaderTask.swift +1 -1
- package/ios/EXUpdates/AppLoader/EmbeddedAppLoader.swift +29 -5
- package/ios/EXUpdates/AppLoader/FileDownloader.swift +23 -5
- package/ios/EXUpdates/AppLoader/RemoteAppLoader.swift +65 -41
- package/ios/EXUpdates/CodeSigning/CodeSigningConfiguration.swift +2 -3
- package/ios/EXUpdates/Database/Migrations/UpdatesDatabaseMigration10To11.swift +21 -0
- package/ios/EXUpdates/Database/Migrations/UpdatesDatabaseMigrationRegistry.swift +2 -1
- package/ios/EXUpdates/Database/UpdatesDatabase.swift +27 -5
- package/ios/EXUpdates/Database/UpdatesDatabaseInitialization.swift +3 -1
- package/ios/EXUpdates/DevLauncherAppController.swift +11 -2
- package/ios/EXUpdates/DisabledAppController.swift +6 -0
- package/ios/EXUpdates/EnabledAppController.swift +28 -9
- package/ios/EXUpdates/Exceptions.swift +17 -0
- package/ios/EXUpdates/Multipart/EXUpdatesMultipartStreamReader.h +3 -2
- package/ios/EXUpdates/Multipart/EXUpdatesMultipartStreamReader.m +2 -2
- package/ios/EXUpdates/Procedures/FetchUpdateProcedure.swift +4 -1
- package/ios/EXUpdates/Procedures/RelaunchProcedure.swift +5 -0
- package/ios/EXUpdates/ReactDelegateHandler/EXDeferredRCTRootView.h +1 -1
- package/ios/EXUpdates/ReactDelegateHandler/EXDeferredRCTRootView.m +1 -0
- package/ios/EXUpdates/ReactDelegateHandler/ExpoUpdatesReactDelegateHandler.swift +27 -4
- package/ios/EXUpdates/ReloadScreen/ReloadExceptions.swift +7 -0
- package/ios/EXUpdates/ReloadScreen/ReloadScreenConfiguration.swift +114 -0
- package/ios/EXUpdates/ReloadScreen/ReloadScreenManager.swift +101 -0
- package/ios/EXUpdates/ReloadScreen/ReloadScreenManagerMacOS.swift +104 -0
- package/ios/EXUpdates/ReloadScreen/ReloadScreenView.swift +175 -0
- package/ios/EXUpdates/ReloadScreen/ReloadScreenViewMacOS.swift +173 -0
- package/ios/EXUpdates/ReloadScreen/Reloadable.swift +5 -0
- package/ios/EXUpdates/SelectionPolicy/LauncherSelectionPolicyDevelopmentClient.swift +25 -0
- package/ios/EXUpdates/SelectionPolicy/LauncherSelectionPolicyFilterAware.swift +7 -17
- package/ios/EXUpdates/SelectionPolicy/LoaderSelectionPolicyDevelopmentClient.swift +80 -0
- package/ios/EXUpdates/SelectionPolicy/LoaderSelectionPolicyFilterAware.swift +27 -1
- package/ios/EXUpdates/SelectionPolicy/SelectionPolicyFactory.swift +3 -3
- package/ios/EXUpdates/Update/EmbeddedUpdate.swift +3 -1
- package/ios/EXUpdates/Update/ExpoUpdatesUpdate.swift +3 -1
- package/ios/EXUpdates/Update/Update.swift +7 -1
- package/ios/EXUpdates/UpdatesConfig.swift +76 -5
- package/ios/EXUpdates/UpdatesConfigOverride.swift +12 -2
- package/ios/EXUpdates/UpdatesModule.swift +24 -2
- package/ios/EXUpdates/UpdatesStateMachine.swift +18 -1
- package/ios/EXUpdates.podspec +3 -2
- package/ios/Tests/AppLauncherWithDatabaseSpec.swift +10 -8
- package/ios/Tests/DatabaseInitializationSpec.swift +95 -0
- package/ios/Tests/DatabaseIntegrityCheckSpec.swift +17 -9
- package/ios/Tests/ErrorRecoverySpec.swift +6 -2
- package/ios/Tests/FileDownloaderSpec.swift +111 -4
- package/ios/Tests/LauncherSelectionPolicyFilterAwareSpec.swift +179 -0
- package/ios/Tests/LoaderSelectionPolicyFilterAwareSpec.swift +201 -0
- package/ios/Tests/ReaperSelectionPolicyDevelopmentClientSpec.swift +15 -5
- package/ios/Tests/ReaperSelectionPolicyFilterAwareSpec.swift +18 -6
- package/ios/Tests/SelectionPolicyFilterAwareSpec.swift +1 -1
- package/ios/Tests/UpdatesBuildDataSpec.swift +1 -1
- package/ios/Tests/UpdatesConfigOverrideSpec.swift +130 -0
- package/ios/Tests/UpdatesConfigSpec.swift +57 -0
- package/ios/Tests/UpdatesDatabaseSpec.swift +42 -4
- package/ios/Tests/UpdatesStateMachineSpec.swift +17 -0
- package/package.json +22 -14
- package/scripts/create-updates-resources-ios.sh +11 -1
- package/src/ExpoUpdates.web.ts +2 -1
- package/src/ExpoUpdatesModule.types.ts +2 -1
- package/src/ReloadScreen.types.ts +80 -0
- package/src/Updates.ts +119 -3
- package/src/Updates.types.ts +3 -0
- package/src/UseUpdates.types.ts +6 -0
- package/src/UseUpdatesUtils.ts +1 -0
- package/utils/build/createFingerprintAsync.js +18 -9
- package/utils/build/createFingerprintForBuildAsync.js +2 -3
- package/utils/build/createManifestForBuildAsync.js +8 -9
- package/utils/build/filterPlatformAssetScales.js +1 -2
- package/utils/build/findUpProjectRoot.js +1 -2
- package/utils/build/resolveRuntimeVersionAsync.js +3 -4
- package/utils/build/vcs.js +1 -1
- package/utils/build/workflow.js +3 -4
- package/utils/src/createFingerprintForBuildAsync.ts +1 -1
- package/utils/src/createManifestForBuildAsync.ts +9 -13
- package/utils/src/resolveRuntimeVersionAsync.ts +2 -2
- package/utils/src/workflow.ts +1 -1
- package/e2e/fixtures/Updates-bricking-measures-disabled.e2e.ts +0 -77
- package/e2e/fixtures/Updates-dev-client.e2e.ts +0 -77
- package/e2e/fixtures/Updates-disabled.e2e.ts +0 -78
- package/e2e/fixtures/Updates-error-recovery.e2e.ts +0 -103
- package/e2e/fixtures/Updates-fingerprint.e2e.ts +0 -73
- package/e2e/fixtures/Updates-startup.e2e.ts +0 -104
- package/e2e/fixtures/Updates.e2e.ts +0 -1016
- package/e2e/fixtures/project_files/.detoxrc.json +0 -68
- package/e2e/fixtures/project_files/e2e/jest.config.js +0 -12
- package/e2e/fixtures/project_files/e2e/tests/utils/server.ts +0 -303
- package/e2e/fixtures/project_files/eas-hooks/eas-build-on-success.sh +0 -83
- package/e2e/fixtures/project_files/eas-hooks/eas-build-pre-install.sh +0 -43
- package/utils/ts-declarations/expo__cli/index.d.ts +0 -2
- /package/e2e/fixtures/project_files/{e2e/tests → maestro/updates-server}/assets/lubo-minar-j2RgHfqKhCM-unsplash.jpg +0 -0
- /package/e2e/fixtures/project_files/{e2e/tests → maestro/updates-server}/assets/niklas-liniger-zuPiCN7xekM-unsplash.jpg +0 -0
- /package/e2e/fixtures/project_files/{e2e/tests → maestro/updates-server}/assets/patrick-untersee-XJjsuuDwWas-unsplash.jpg +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,133 @@
|
|
|
4
4
|
|
|
5
5
|
### 🛠 Breaking changes
|
|
6
6
|
|
|
7
|
+
### 🎉 New features
|
|
8
|
+
|
|
9
|
+
### 🐛 Bug fixes
|
|
10
|
+
|
|
11
|
+
### 💡 Others
|
|
12
|
+
|
|
13
|
+
## 29.0.0 — 2025-08-13
|
|
14
|
+
|
|
15
|
+
### 🎉 New features
|
|
16
|
+
|
|
17
|
+
- Add experimental support for macOS. ([#37629](https://github.com/expo/expo/pull/37629) by [@gabrieldonadel](https://github.com/gabrieldonadel))
|
|
18
|
+
- Add support for a customisable reloading view when `reloadAsync` is called. ([#38074](https://github.com/expo/expo/pull/38074) by [@alanjhughes](https://github.com/alanjhughes)), ([#38362](https://github.com/expo/expo/pull/38362) by [@alanjhughes](https://github.com/alanjhughes)) and ([#38409](https://github.com/expo/expo/pull/38409) by [@gabrieldonadel](https://github.com/gabrieldonadel))
|
|
19
|
+
- Add `downloadProgress` state to the `useUpdates` hook to support listening to overall asset download progress. ([#38307](https://github.com/expo/expo/pull/38307)) by [@nishan](https://github.com/intergalacticspacehighway)
|
|
20
|
+
- [iOS] dev-client support for Apple TV. ([#38388](https://github.com/expo/expo/pull/38388) by [@douglowder](https://github.com/douglowder))
|
|
21
|
+
- Added reload support to `setUpdateURLAndRequestHeadersOverride`. ([#38167](https://github.com/expo/expo/pull/38167), [#38180](https://github.com/expo/expo/pull/38180) by [@kudo](https://github.com/kudo))
|
|
22
|
+
- Added `setUpdateRequestHeadersOverride` to allow runtime `requestHeaders` override. ([#38623](https://github.com/expo/expo/pull/38623), [#38628](https://github.com/expo/expo/pull/38628), [#38624](https://github.com/expo/expo/pull/38624) by [@kudo](https://github.com/kudo))
|
|
23
|
+
|
|
24
|
+
### 🐛 Bug fixes
|
|
25
|
+
|
|
26
|
+
- Fixed imports after upgrading to Metro 0.83 ([#38375](https://github.com/expo/expo/pull/38375) by [@chrfalch](https://github.com/chrfalch))
|
|
27
|
+
|
|
28
|
+
### 💡 Others
|
|
29
|
+
|
|
30
|
+
- [Android] Cleanup state machine resources when the module is destroyed. ([#37193](https://github.com/expo/expo/pull/37193) by [@alanjhughes](https://github.com/alanjhughes))
|
|
31
|
+
- [CI] convert E2E (enabled) tests to Maestro. ([#37492](https://github.com/expo/expo/pull/37492) by [@douglowder](https://github.com/douglowder))
|
|
32
|
+
- [CI] convert E2E (disabled) tests to Maestro. ([#37558](https://github.com/expo/expo/pull/37558) by [@douglowder](https://github.com/douglowder))
|
|
33
|
+
- [CI] convert E2E (fingerprint and startup) tests to Maestro. ([#37592](https://github.com/expo/expo/pull/37592) by [@douglowder](https://github.com/douglowder))
|
|
34
|
+
- [CI] convert E2E (old arch, custom init, error recovery, bricking measures disabled) tests to Maestro. ([#37600](https://github.com/expo/expo/pull/37600) by [@douglowder](https://github.com/douglowder))
|
|
35
|
+
- Bump Express and types to `express@5`. ([#37635](https://github.com/expo/expo/pull/37635) by [@byCedric](https://github.com/byCedric))
|
|
36
|
+
- [CI] Removed Detox testing workaround code on Android. ([#37707](https://github.com/expo/expo/pull/37707) by [@kudo](https://github.com/kudo))
|
|
37
|
+
- [CI] Removed Detox dependency and unused files in E2E code. ([#37751](https://github.com/expo/expo/pull/37751) by [@douglowder](https://github.com/douglowder))
|
|
38
|
+
- Updates imports from `@expo/config`, `@expo/config-plugins` to `expo/config`, `expo/config-plugins`. ([#37860](https://github.com/expo/expo/pull/37860) by [@aleqsio](https://github.com/aleqsio))
|
|
39
|
+
- [Android] Migrate loaders and file downloader to coroutines. ([#37959](https://github.com/expo/expo/pull/37959) by [@alanjhughes](https://github.com/alanjhughes))
|
|
40
|
+
- [Android] Fix procedure scope no surviving app reloads. ([#38073](https://github.com/expo/expo/pull/38073) by [@alanjhughes](https://github.com/alanjhughes))
|
|
41
|
+
- [Internal] Replace dependency chain to `@expo/cli` internals with an internal entrypoint ([#38574](https://github.com/expo/expo/pull/38574) by [@kitten](https://github.com/kitten))
|
|
42
|
+
|
|
43
|
+
### 📚 3rd party library updates
|
|
44
|
+
|
|
45
|
+
- Bumped `form-data@4.0.4`. ([#38214](https://github.com/expo/expo/pull/38214) by [@kudo](https://github.com/kudo))
|
|
46
|
+
|
|
47
|
+
## 0.28.17 - 2025-07-08
|
|
48
|
+
|
|
49
|
+
_This version does not introduce any user-facing changes._
|
|
50
|
+
|
|
51
|
+
## 0.28.16 - 2025-07-03
|
|
52
|
+
|
|
53
|
+
_This version does not introduce any user-facing changes._
|
|
54
|
+
|
|
55
|
+
## 0.28.15 - 2025-06-18
|
|
56
|
+
|
|
57
|
+
### 🐛 Bug fixes
|
|
58
|
+
|
|
59
|
+
- Fix updates native debug for iOS. ([#37323](https://github.com/expo/expo/pull/37323) by [@douglowder](https://github.com/douglowder))
|
|
60
|
+
|
|
61
|
+
## 0.28.14 - 2025-06-04
|
|
62
|
+
|
|
63
|
+
### 🐛 Bug fixes
|
|
64
|
+
|
|
65
|
+
- Fix update failure reason not populated on iOS. ([#36893](https://github.com/expo/expo/pull/36893) by [@brainbicycle](https://github.com/brainbicycle))
|
|
66
|
+
|
|
67
|
+
### 💡 Others
|
|
68
|
+
|
|
69
|
+
- Remove "Please" from warnings and errors ([#36862](https://github.com/expo/expo/pull/36862) by [@brentvatne](https://github.com/brentvatne))
|
|
70
|
+
|
|
71
|
+
## 0.28.13 — 2025-05-08
|
|
72
|
+
|
|
73
|
+
### 🐛 Bug fixes
|
|
74
|
+
|
|
75
|
+
- [Android] Fixed errors when `configuration-cache` is enabled. ([#36678](https://github.com/expo/expo/pull/36678) by [@lukmccall](https://github.com/lukmccall))
|
|
76
|
+
- [iOS] Update the constraints of the deferred root view. ([#36744](https://github.com/expo/expo/pull/36744) by [@alanjhughes](https://github.com/alanjhughes))
|
|
77
|
+
|
|
78
|
+
## 0.28.12 — 2025-05-01
|
|
79
|
+
|
|
80
|
+
_This version does not introduce any user-facing changes._
|
|
81
|
+
|
|
82
|
+
## 0.28.11 — 2025-04-30
|
|
83
|
+
|
|
84
|
+
_This version does not introduce any user-facing changes._
|
|
85
|
+
|
|
86
|
+
## 0.28.10 — 2025-04-30
|
|
87
|
+
|
|
88
|
+
_This version does not introduce any user-facing changes._
|
|
89
|
+
|
|
90
|
+
## 0.28.9 — 2025-04-28
|
|
91
|
+
|
|
92
|
+
_This version does not introduce any user-facing changes._
|
|
93
|
+
|
|
94
|
+
## 0.28.8 — 2025-04-28
|
|
95
|
+
|
|
96
|
+
_This version does not introduce any user-facing changes._
|
|
97
|
+
|
|
98
|
+
## 0.28.7 — 2025-04-25
|
|
99
|
+
|
|
100
|
+
### 🐛 Bug fixes
|
|
101
|
+
|
|
102
|
+
- Fixed build error from **AppDelegate.swift** integration. ([#36368](https://github.com/expo/expo/pull/36368) by [@kudo](https://github.com/kudo))
|
|
103
|
+
|
|
104
|
+
## 0.28.6 — 2025-04-22
|
|
105
|
+
|
|
106
|
+
_This version does not introduce any user-facing changes._
|
|
107
|
+
|
|
108
|
+
## 0.28.5 — 2025-04-14
|
|
109
|
+
|
|
110
|
+
_This version does not introduce any user-facing changes._
|
|
111
|
+
|
|
112
|
+
## 0.28.4 — 2025-04-14
|
|
113
|
+
|
|
114
|
+
### 🎉 New features
|
|
115
|
+
|
|
116
|
+
- [Android] Added `EX_UPDATES_COPY_EMBEDDED_ASSETS` flag which is false by default, to not copy embedded assets. ([#36059](https://github.com/expo/expo/pull/36059) by [@kudo](https://github.com/kudo))
|
|
117
|
+
|
|
118
|
+
## 0.28.3 — 2025-04-11
|
|
119
|
+
|
|
120
|
+
_This version does not introduce any user-facing changes._
|
|
121
|
+
|
|
122
|
+
## 0.28.2 — 2025-04-09
|
|
123
|
+
|
|
124
|
+
_This version does not introduce any user-facing changes._
|
|
125
|
+
|
|
126
|
+
## 0.28.1 — 2025-04-08
|
|
127
|
+
|
|
128
|
+
_This version does not introduce any user-facing changes._
|
|
129
|
+
|
|
130
|
+
## 0.28.0 — 2025-04-04
|
|
131
|
+
|
|
132
|
+
### 🛠 Breaking changes
|
|
133
|
+
|
|
7
134
|
- upgrade RN to 0.78 ([#35050](https://github.com/expo/expo/pull/35050) by [@vonovak](https://github.com/vonovak))
|
|
8
135
|
- Remove a few long-deprecated typescript types. ([#34215](https://github.com/expo/expo/pull/34215) by [@wschurman](https://github.com/wschurman))
|
|
9
136
|
|
package/android/build.gradle
CHANGED
|
@@ -11,7 +11,10 @@ buildscript {
|
|
|
11
11
|
// We can remove this path once we update the test environment
|
|
12
12
|
// to use the same version of Kotlin as the `expo/expo` repo.
|
|
13
13
|
def kotlinVersion = rootProject["kotlinVersion"]
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
if (kotlinVersion == "2.1.20") {
|
|
16
|
+
return "2.1.20-2.0.1"
|
|
17
|
+
} else if (kotlinVersion == "2.0.21") {
|
|
15
18
|
return "2.0.21-1.0.28"
|
|
16
19
|
} else if (kotlinVersion == "1.9.25") {
|
|
17
20
|
return "1.9.25-1.0.20"
|
|
@@ -39,7 +42,7 @@ expoModule {
|
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
group = 'host.exp.exponent'
|
|
42
|
-
version = '0.
|
|
45
|
+
version = '29.0.0'
|
|
43
46
|
|
|
44
47
|
// Utility method to derive boolean values from the environment or from Java properties,
|
|
45
48
|
// and return them as strings to be used in BuildConfig fields
|
|
@@ -72,6 +75,9 @@ def exUpdatesCustomInit = getBoolStringFromPropOrEnv("EX_UPDATES_CUSTOM_INIT", f
|
|
|
72
75
|
// (default true)
|
|
73
76
|
def exUpdatesAndroidDelayLoadApp = getBoolStringFromPropOrEnv("EX_UPDATES_ANDROID_DELAY_LOAD_APP", true)
|
|
74
77
|
|
|
78
|
+
// If true, updates will copy embedded assets to file system when startup. (default false)
|
|
79
|
+
def exUpdatesCopyEmbeddedAssets = getBoolStringFromPropOrEnv("EX_UPDATES_COPY_EMBEDDED_ASSETS", false)
|
|
80
|
+
|
|
75
81
|
def useDevClient = findProject(":expo-dev-client") != null
|
|
76
82
|
|
|
77
83
|
android {
|
|
@@ -82,13 +88,14 @@ android {
|
|
|
82
88
|
namespace "expo.modules.updates"
|
|
83
89
|
defaultConfig {
|
|
84
90
|
versionCode 31
|
|
85
|
-
versionName '0.
|
|
91
|
+
versionName '29.0.0'
|
|
86
92
|
consumerProguardFiles("proguard-rules.pro")
|
|
87
93
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
88
94
|
|
|
89
95
|
buildConfigField("boolean", "EX_UPDATES_NATIVE_DEBUG", exUpdatesNativeDebug)
|
|
90
96
|
buildConfigField("boolean", "EX_UPDATES_CUSTOM_INIT", exUpdatesCustomInit)
|
|
91
97
|
buildConfigField("boolean", "EX_UPDATES_ANDROID_DELAY_LOAD_APP", exUpdatesAndroidDelayLoadApp)
|
|
98
|
+
buildConfigField("boolean", "EX_UPDATES_COPY_EMBEDDED_ASSETS", exUpdatesCopyEmbeddedAssets)
|
|
92
99
|
buildConfigField("boolean", "USE_DEV_CLIENT", useDevClient.toString())
|
|
93
100
|
}
|
|
94
101
|
testOptions {
|
|
@@ -127,6 +134,7 @@ dependencies {
|
|
|
127
134
|
def mockk_version = "1.13.11"
|
|
128
135
|
|
|
129
136
|
implementation "androidx.room:room-runtime:$room_version"
|
|
137
|
+
implementation "androidx.room:room-ktx:$room_version"
|
|
130
138
|
ksp "androidx.room:room-compiler:$room_version"
|
|
131
139
|
|
|
132
140
|
implementation("com.squareup.okhttp3:okhttp:4.9.2")
|
|
@@ -135,16 +143,17 @@ dependencies {
|
|
|
135
143
|
implementation("org.bouncycastle:bcutil-jdk15to18:1.78.1")
|
|
136
144
|
|
|
137
145
|
testImplementation 'junit:junit:4.13.2'
|
|
138
|
-
testImplementation 'androidx.test:core:1.
|
|
146
|
+
testImplementation 'androidx.test:core:1.6.1'
|
|
147
|
+
testImplementation 'com.google.truth:truth:1.1.2'
|
|
139
148
|
testImplementation "io.mockk:mockk:$mockk_version"
|
|
140
149
|
testImplementation "org.jetbrains.kotlin:kotlin-test-junit:${kotlinVersion}"
|
|
141
150
|
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3'
|
|
142
151
|
testImplementation 'org.robolectric:robolectric:4.14.1'
|
|
143
152
|
|
|
144
153
|
androidTestImplementation 'com.squareup.okio:okio:2.9.0'
|
|
145
|
-
androidTestImplementation 'androidx.test:runner:1.
|
|
146
|
-
androidTestImplementation 'androidx.test:core:1.
|
|
147
|
-
androidTestImplementation 'androidx.test:rules:1.
|
|
154
|
+
androidTestImplementation 'androidx.test:runner:1.6.2'
|
|
155
|
+
androidTestImplementation 'androidx.test:core:1.6.1'
|
|
156
|
+
androidTestImplementation 'androidx.test:rules:1.6.1'
|
|
148
157
|
androidTestImplementation "io.mockk:mockk-android:$mockk_version"
|
|
149
158
|
androidTestImplementation "androidx.room:room-testing:$room_version"
|
|
150
159
|
androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3'
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
}
|
|
4
4
|
|
|
5
5
|
-keepclassmembers class com.facebook.react.devsupport.ReleaseDevSupportManager {
|
|
6
|
-
private final com.facebook.react.bridge.
|
|
6
|
+
private final com.facebook.react.bridge.JSExceptionHandler defaultJSExceptionHandler;
|
|
7
7
|
}
|
|
@@ -11,13 +11,24 @@ import expo.modules.updates.events.IUpdatesEventManager
|
|
|
11
11
|
import expo.modules.updates.events.UpdatesEventManager
|
|
12
12
|
import expo.modules.updates.launcher.Launcher
|
|
13
13
|
import expo.modules.updates.launcher.NoDatabaseLauncher
|
|
14
|
-
import expo.modules.updates.logging.UpdatesErrorCode
|
|
15
14
|
import expo.modules.updates.logging.UpdatesLogger
|
|
16
15
|
import expo.modules.updates.procedures.RecreateReactContextProcedure
|
|
16
|
+
import expo.modules.updates.reloadscreen.ReloadScreenManager
|
|
17
17
|
import expo.modules.updates.statemachine.UpdatesStateMachine
|
|
18
18
|
import expo.modules.updates.statemachine.UpdatesStateValue
|
|
19
|
+
import kotlinx.coroutines.CompletableDeferred
|
|
20
|
+
import kotlinx.coroutines.CoroutineScope
|
|
21
|
+
import kotlinx.coroutines.Dispatchers
|
|
22
|
+
import kotlinx.coroutines.cancel
|
|
23
|
+
import kotlinx.coroutines.launch
|
|
24
|
+
import kotlinx.coroutines.runBlocking
|
|
25
|
+
import kotlinx.coroutines.suspendCancellableCoroutine
|
|
26
|
+
import kotlinx.coroutines.sync.Mutex
|
|
27
|
+
import kotlinx.coroutines.sync.withLock
|
|
19
28
|
import java.io.File
|
|
20
29
|
import java.lang.ref.WeakReference
|
|
30
|
+
import kotlin.coroutines.resume
|
|
31
|
+
import kotlin.coroutines.resumeWithException
|
|
21
32
|
import kotlin.time.DurationUnit
|
|
22
33
|
import kotlin.time.toDuration
|
|
23
34
|
|
|
@@ -34,6 +45,7 @@ class DisabledUpdatesController(
|
|
|
34
45
|
) : IUpdatesController {
|
|
35
46
|
/** Keep the activity for [RecreateReactContextProcedure] to relaunch the app. */
|
|
36
47
|
private var weakActivity: WeakReference<Activity>? = null
|
|
48
|
+
private val controllerScope = CoroutineScope(Dispatchers.IO)
|
|
37
49
|
|
|
38
50
|
private val logger = UpdatesLogger(context.filesDir)
|
|
39
51
|
override val eventManager: IUpdatesEventManager = UpdatesEventManager(logger)
|
|
@@ -55,24 +67,22 @@ class DisabledUpdatesController(
|
|
|
55
67
|
}
|
|
56
68
|
|
|
57
69
|
private var launcher: Launcher? = null
|
|
58
|
-
private var isLoaderTaskFinished = false
|
|
59
70
|
override var updatesDirectory: File? = null
|
|
71
|
+
private val loaderTaskFinishedDeferred = CompletableDeferred<Unit>()
|
|
72
|
+
private val loaderTaskFinishedMutex = Mutex()
|
|
60
73
|
|
|
61
|
-
@get:Synchronized
|
|
62
74
|
override val launchAssetFile: String?
|
|
63
75
|
get() {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
(this as java.lang.Object).wait()
|
|
67
|
-
} catch (e: InterruptedException) {
|
|
68
|
-
logger.error("Interrupted while waiting for launch asset file", e, UpdatesErrorCode.InitializationError)
|
|
69
|
-
}
|
|
76
|
+
runBlocking {
|
|
77
|
+
loaderTaskFinishedDeferred.await()
|
|
70
78
|
}
|
|
71
79
|
return launcher?.launchAssetFile
|
|
72
80
|
}
|
|
73
81
|
|
|
74
82
|
override val bundleAssetName: String?
|
|
75
83
|
get() = launcher?.bundleAssetName
|
|
84
|
+
override val reloadScreenManager: ReloadScreenManager?
|
|
85
|
+
get() = null
|
|
76
86
|
|
|
77
87
|
override fun onEventListenerStartObserving() {
|
|
78
88
|
stateMachine.sendContextToJS()
|
|
@@ -121,58 +131,66 @@ class DisabledUpdatesController(
|
|
|
121
131
|
)
|
|
122
132
|
}
|
|
123
133
|
|
|
124
|
-
override fun relaunchReactApplicationForModule(
|
|
134
|
+
override suspend fun relaunchReactApplicationForModule() = suspendCancellableCoroutine { continuation ->
|
|
125
135
|
val procedure = RecreateReactContextProcedure(
|
|
126
136
|
context,
|
|
127
137
|
weakActivity,
|
|
128
138
|
object : Launcher.LauncherCallback {
|
|
129
139
|
override fun onFailure(e: Exception) {
|
|
130
|
-
|
|
140
|
+
continuation.resumeWithException(e.toCodedException())
|
|
131
141
|
}
|
|
132
142
|
|
|
133
143
|
override fun onSuccess() {
|
|
134
|
-
|
|
144
|
+
continuation.resume(Unit)
|
|
135
145
|
}
|
|
136
146
|
}
|
|
137
147
|
)
|
|
138
148
|
stateMachine.queueExecution(procedure)
|
|
139
149
|
}
|
|
140
150
|
|
|
141
|
-
override fun checkForUpdate(
|
|
142
|
-
|
|
143
|
-
) {
|
|
144
|
-
callback.onFailure(UpdatesDisabledException("Updates.checkForUpdateAsync() is not supported when expo-updates is not enabled."))
|
|
151
|
+
override suspend fun checkForUpdate(): IUpdatesController.CheckForUpdateResult {
|
|
152
|
+
throw UpdatesDisabledException("Updates.checkForUpdateAsync() is not supported when expo-updates is not enabled.")
|
|
145
153
|
}
|
|
146
154
|
|
|
147
|
-
override fun fetchUpdate(
|
|
148
|
-
|
|
149
|
-
) {
|
|
150
|
-
callback.onFailure(UpdatesDisabledException("Updates.fetchUpdateAsync() is not supported when expo-updates is not enabled."))
|
|
155
|
+
override suspend fun fetchUpdate(): IUpdatesController.FetchUpdateResult {
|
|
156
|
+
throw UpdatesDisabledException("Updates.fetchUpdateAsync() is not supported when expo-updates is not enabled.")
|
|
151
157
|
}
|
|
152
158
|
|
|
153
|
-
override fun getExtraParams(
|
|
154
|
-
|
|
159
|
+
override suspend fun getExtraParams(): Bundle {
|
|
160
|
+
throw UpdatesDisabledException("Updates.getExtraParamsAsync() is not supported when expo-updates is not enabled.")
|
|
155
161
|
}
|
|
156
162
|
|
|
157
|
-
override fun setExtraParam(
|
|
163
|
+
override suspend fun setExtraParam(
|
|
158
164
|
key: String,
|
|
159
|
-
value: String
|
|
160
|
-
callback: IUpdatesController.ModuleCallback<Unit>
|
|
165
|
+
value: String?
|
|
161
166
|
) {
|
|
162
|
-
|
|
167
|
+
throw UpdatesDisabledException("Updates.setExtraParamAsync() is not supported when expo-updates is not enabled.")
|
|
163
168
|
}
|
|
164
169
|
|
|
165
170
|
override fun setUpdateURLAndRequestHeadersOverride(configOverride: UpdatesConfigurationOverride?) {
|
|
166
171
|
throw UpdatesDisabledException("Updates.setUpdateURLAndRequestHeadersOverride() is not supported when expo-updates is not enabled.")
|
|
167
172
|
}
|
|
168
173
|
|
|
174
|
+
override fun setUpdateRequestHeadersOverride(requestHeaders: Map<String, String>?) {
|
|
175
|
+
throw UpdatesDisabledException("Updates.setUpdateRequestHeadersOverride() is not supported when expo-updates is not enabled.")
|
|
176
|
+
}
|
|
177
|
+
|
|
169
178
|
@Synchronized
|
|
170
179
|
private fun notifyController() {
|
|
171
|
-
|
|
172
|
-
|
|
180
|
+
controllerScope.launch {
|
|
181
|
+
loaderTaskFinishedMutex.withLock {
|
|
182
|
+
if (!loaderTaskFinishedDeferred.isCompleted) {
|
|
183
|
+
if (launcher == null) {
|
|
184
|
+
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.")
|
|
185
|
+
}
|
|
186
|
+
loaderTaskFinishedDeferred.complete(Unit)
|
|
187
|
+
}
|
|
188
|
+
}
|
|
173
189
|
}
|
|
174
|
-
|
|
175
|
-
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
override fun shutdown() {
|
|
193
|
+
controllerScope.cancel()
|
|
176
194
|
}
|
|
177
195
|
|
|
178
196
|
companion object {
|
|
@@ -5,6 +5,7 @@ import android.content.Context
|
|
|
5
5
|
import android.os.Bundle
|
|
6
6
|
import com.facebook.react.bridge.ReactContext
|
|
7
7
|
import com.facebook.react.devsupport.interfaces.DevSupportManager
|
|
8
|
+
import expo.modules.easclient.EASClientID
|
|
8
9
|
import expo.modules.kotlin.exception.CodedException
|
|
9
10
|
import expo.modules.kotlin.exception.toCodedException
|
|
10
11
|
import expo.modules.updates.db.BuildData
|
|
@@ -23,14 +24,24 @@ import expo.modules.updates.procedures.CheckForUpdateProcedure
|
|
|
23
24
|
import expo.modules.updates.procedures.FetchUpdateProcedure
|
|
24
25
|
import expo.modules.updates.procedures.RelaunchProcedure
|
|
25
26
|
import expo.modules.updates.procedures.StartupProcedure
|
|
27
|
+
import expo.modules.updates.reloadscreen.ReloadScreenManager
|
|
28
|
+
import expo.modules.updates.selectionpolicy.SelectionPolicy
|
|
26
29
|
import expo.modules.updates.selectionpolicy.SelectionPolicyFactory
|
|
27
30
|
import expo.modules.updates.statemachine.UpdatesStateMachine
|
|
28
31
|
import expo.modules.updates.statemachine.UpdatesStateValue
|
|
32
|
+
import kotlinx.coroutines.CompletableDeferred
|
|
29
33
|
import kotlinx.coroutines.CoroutineScope
|
|
30
34
|
import kotlinx.coroutines.Dispatchers
|
|
35
|
+
import kotlinx.coroutines.cancel
|
|
31
36
|
import kotlinx.coroutines.launch
|
|
37
|
+
import kotlinx.coroutines.runBlocking
|
|
38
|
+
import kotlinx.coroutines.suspendCancellableCoroutine
|
|
39
|
+
import kotlinx.coroutines.sync.Mutex
|
|
40
|
+
import kotlinx.coroutines.sync.withLock
|
|
32
41
|
import java.io.File
|
|
33
42
|
import java.lang.ref.WeakReference
|
|
43
|
+
import kotlin.coroutines.resume
|
|
44
|
+
import kotlin.coroutines.resumeWithException
|
|
34
45
|
import kotlin.time.DurationUnit
|
|
35
46
|
import kotlin.time.toDuration
|
|
36
47
|
|
|
@@ -39,7 +50,7 @@ import kotlin.time.toDuration
|
|
|
39
50
|
*/
|
|
40
51
|
class EnabledUpdatesController(
|
|
41
52
|
private val context: Context,
|
|
42
|
-
private
|
|
53
|
+
private var updatesConfiguration: UpdatesConfiguration,
|
|
43
54
|
override val updatesDirectory: File
|
|
44
55
|
) : IUpdatesController {
|
|
45
56
|
/** Keep the activity for [RelaunchProcedure] to relaunch the app. */
|
|
@@ -47,13 +58,16 @@ class EnabledUpdatesController(
|
|
|
47
58
|
private val logger = UpdatesLogger(context.filesDir)
|
|
48
59
|
override val eventManager: IUpdatesEventManager = UpdatesEventManager(logger)
|
|
49
60
|
|
|
50
|
-
private val
|
|
51
|
-
|
|
52
|
-
updatesConfiguration.getRuntimeVersion()
|
|
53
|
-
)
|
|
61
|
+
private val selectionPolicy: SelectionPolicy
|
|
62
|
+
get() = SelectionPolicyFactory.createFilterAwarePolicy(updatesConfiguration.getRuntimeVersion(), updatesConfiguration)
|
|
54
63
|
private val stateMachine = UpdatesStateMachine(logger, eventManager, UpdatesStateValue.entries.toSet())
|
|
55
|
-
private val databaseHolder = DatabaseHolder(UpdatesDatabase.getInstance(context))
|
|
56
64
|
private val controllerScope = CoroutineScope(Dispatchers.IO)
|
|
65
|
+
private val fileDownloader: FileDownloader
|
|
66
|
+
get() = FileDownloader(context.filesDir, EASClientID(context).uuid.toString(), updatesConfiguration, logger)
|
|
67
|
+
private val databaseHolder = DatabaseHolder(UpdatesDatabase.getInstance(context, Dispatchers.IO))
|
|
68
|
+
private val startupFinishedDeferred = CompletableDeferred<Unit>()
|
|
69
|
+
private val startupFinishedMutex = Mutex()
|
|
70
|
+
override val reloadScreenManager = ReloadScreenManager()
|
|
57
71
|
|
|
58
72
|
private fun purgeUpdatesLogsOlderThanOneDay() {
|
|
59
73
|
UpdatesLogReader(context.filesDir).purgeLogEntries {
|
|
@@ -70,9 +84,15 @@ class EnabledUpdatesController(
|
|
|
70
84
|
|
|
71
85
|
@Synchronized
|
|
72
86
|
private fun onStartupProcedureFinished() {
|
|
87
|
+
controllerScope.launch {
|
|
88
|
+
startupFinishedMutex.withLock {
|
|
89
|
+
if (!startupFinishedDeferred.isCompleted) {
|
|
90
|
+
startupFinishedDeferred.complete(Unit)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
73
94
|
isStartupFinished = true
|
|
74
95
|
startupEndTimeMillis = System.currentTimeMillis()
|
|
75
|
-
(this@EnabledUpdatesController as java.lang.Object).notify()
|
|
76
96
|
}
|
|
77
97
|
|
|
78
98
|
private val startupProcedure = StartupProcedure(
|
|
@@ -103,18 +123,14 @@ class EnabledUpdatesController(
|
|
|
103
123
|
private val localAssetFiles
|
|
104
124
|
get() = startupProcedure.localAssetFiles
|
|
105
125
|
|
|
106
|
-
@get:Synchronized
|
|
107
126
|
override val launchAssetFile: String?
|
|
108
127
|
get() {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
(this as java.lang.Object).wait()
|
|
112
|
-
} catch (e: InterruptedException) {
|
|
113
|
-
logger.error("Interrupted while waiting for launch asset file", e, UpdatesErrorCode.InitializationError)
|
|
114
|
-
}
|
|
128
|
+
runBlocking {
|
|
129
|
+
startupFinishedDeferred.await()
|
|
115
130
|
}
|
|
116
131
|
return startupProcedure.launchAssetFile
|
|
117
132
|
}
|
|
133
|
+
|
|
118
134
|
override val bundleAssetName: String?
|
|
119
135
|
get() = startupProcedure.bundleAssetName
|
|
120
136
|
|
|
@@ -146,8 +162,9 @@ class EnabledUpdatesController(
|
|
|
146
162
|
|
|
147
163
|
purgeUpdatesLogsOlderThanOneDay()
|
|
148
164
|
|
|
149
|
-
|
|
150
|
-
|
|
165
|
+
if (!updatesConfiguration.hasUpdatesOverride) {
|
|
166
|
+
BuildData.ensureBuildDataIsConsistent(updatesConfiguration, databaseHolder.database)
|
|
167
|
+
}
|
|
151
168
|
|
|
152
169
|
stateMachine.queueExecution(startupProcedure)
|
|
153
170
|
}
|
|
@@ -165,6 +182,7 @@ class EnabledUpdatesController(
|
|
|
165
182
|
getCurrentLauncher = { startupProcedure.launcher!! },
|
|
166
183
|
setCurrentLauncher = { currentLauncher -> startupProcedure.setLauncher(currentLauncher) },
|
|
167
184
|
shouldRunReaper = shouldRunReaper,
|
|
185
|
+
reloadScreenManager = reloadScreenManager,
|
|
168
186
|
callback
|
|
169
187
|
)
|
|
170
188
|
stateMachine.queueExecution(procedure)
|
|
@@ -187,48 +205,47 @@ class EnabledUpdatesController(
|
|
|
187
205
|
)
|
|
188
206
|
}
|
|
189
207
|
|
|
190
|
-
override fun relaunchReactApplicationForModule(
|
|
208
|
+
override suspend fun relaunchReactApplicationForModule() = suspendCancellableCoroutine { continuation ->
|
|
191
209
|
val canRelaunch = launchedUpdate != null
|
|
192
210
|
if (!canRelaunch) {
|
|
193
|
-
|
|
211
|
+
continuation.resumeWithException(object : CodedException("ERR_UPDATES_RELOAD", "Cannot relaunch without a launched update.", null) {})
|
|
194
212
|
} else {
|
|
195
213
|
relaunchReactApplication(
|
|
196
214
|
shouldRunReaper = true,
|
|
197
215
|
object : LauncherCallback {
|
|
198
216
|
override fun onFailure(e: Exception) {
|
|
199
|
-
|
|
217
|
+
continuation.resumeWithException(e.toCodedException())
|
|
200
218
|
}
|
|
201
219
|
|
|
202
220
|
override fun onSuccess() {
|
|
203
|
-
|
|
221
|
+
continuation.resume(Unit)
|
|
204
222
|
}
|
|
205
223
|
}
|
|
206
224
|
)
|
|
207
225
|
}
|
|
208
226
|
}
|
|
209
227
|
|
|
210
|
-
override fun checkForUpdate(
|
|
228
|
+
override suspend fun checkForUpdate() = suspendCancellableCoroutine { continuation ->
|
|
211
229
|
val procedure = CheckForUpdateProcedure(context, updatesConfiguration, databaseHolder, logger, fileDownloader, selectionPolicy, launchedUpdate) {
|
|
212
|
-
|
|
230
|
+
continuation.resume(it)
|
|
213
231
|
}
|
|
214
232
|
stateMachine.queueExecution(procedure)
|
|
215
233
|
}
|
|
216
234
|
|
|
217
|
-
override fun fetchUpdate(
|
|
235
|
+
override suspend fun fetchUpdate() = suspendCancellableCoroutine { continuation ->
|
|
218
236
|
val procedure = FetchUpdateProcedure(context, updatesConfiguration, logger, databaseHolder, updatesDirectory, fileDownloader, selectionPolicy, launchedUpdate) {
|
|
219
|
-
|
|
237
|
+
continuation.resume(it)
|
|
220
238
|
}
|
|
221
239
|
stateMachine.queueExecution(procedure)
|
|
222
240
|
}
|
|
223
241
|
|
|
224
|
-
override fun getExtraParams(
|
|
242
|
+
override suspend fun getExtraParams() = suspendCancellableCoroutine { continuation ->
|
|
225
243
|
controllerScope.launch {
|
|
226
244
|
try {
|
|
227
245
|
val result = ManifestMetadata.getExtraParams(
|
|
228
246
|
databaseHolder.database,
|
|
229
247
|
updatesConfiguration
|
|
230
248
|
)
|
|
231
|
-
databaseHolder.releaseDatabase()
|
|
232
249
|
val resultMap = when (result) {
|
|
233
250
|
null -> Bundle()
|
|
234
251
|
else -> {
|
|
@@ -239,37 +256,51 @@ class EnabledUpdatesController(
|
|
|
239
256
|
}
|
|
240
257
|
}
|
|
241
258
|
}
|
|
242
|
-
|
|
259
|
+
continuation.resume(resultMap)
|
|
243
260
|
} catch (e: Exception) {
|
|
244
|
-
|
|
245
|
-
callback.onFailure(e.toCodedException())
|
|
261
|
+
continuation.resumeWithException(e.toCodedException())
|
|
246
262
|
}
|
|
247
263
|
}
|
|
248
264
|
}
|
|
249
265
|
|
|
250
|
-
override fun setExtraParam(key: String, value: String
|
|
266
|
+
override suspend fun setExtraParam(key: String, value: String?) = suspendCancellableCoroutine { continuation ->
|
|
251
267
|
controllerScope.launch {
|
|
252
|
-
|
|
268
|
+
runCatching {
|
|
253
269
|
ManifestMetadata.setExtraParam(
|
|
254
270
|
databaseHolder.database,
|
|
255
271
|
updatesConfiguration,
|
|
256
272
|
key,
|
|
257
273
|
value
|
|
258
274
|
)
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
databaseHolder.releaseDatabase()
|
|
263
|
-
callback.onFailure(e.toCodedException())
|
|
275
|
+
continuation.resume(Unit)
|
|
276
|
+
}.onFailure { e ->
|
|
277
|
+
continuation.resumeWithException(e.toCodedException())
|
|
264
278
|
}
|
|
265
279
|
}
|
|
266
280
|
}
|
|
267
281
|
|
|
282
|
+
override fun shutdown() {
|
|
283
|
+
controllerScope.cancel()
|
|
284
|
+
}
|
|
285
|
+
|
|
268
286
|
override fun setUpdateURLAndRequestHeadersOverride(configOverride: UpdatesConfigurationOverride?) {
|
|
269
287
|
if (!updatesConfiguration.disableAntiBrickingMeasures) {
|
|
270
288
|
throw CodedException("ERR_UPDATES_RUNTIME_OVERRIDE", "Must set disableAntiBrickingMeasures configuration to use updates overriding", null)
|
|
271
289
|
}
|
|
272
290
|
UpdatesConfigurationOverride.save(context, configOverride)
|
|
291
|
+
updatesConfiguration = UpdatesConfiguration.create(context, updatesConfiguration, configOverride)
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
override fun setUpdateRequestHeadersOverride(requestHeaders: Map<String, String>?) {
|
|
295
|
+
val isValidRequestHeaders = UpdatesConfiguration.isValidRequestHeadersOverride(
|
|
296
|
+
updatesConfiguration.originalEmbeddedRequestHeaders,
|
|
297
|
+
requestHeaders
|
|
298
|
+
)
|
|
299
|
+
if (!isValidRequestHeaders) {
|
|
300
|
+
throw CodedException("ERR_UPDATES_RUNTIME_OVERRIDE", "Invalid update requestHeaders override: $requestHeaders", null)
|
|
301
|
+
}
|
|
302
|
+
val configOverride = UpdatesConfigurationOverride.saveRequestHeaders(context, requestHeaders)
|
|
303
|
+
updatesConfiguration = UpdatesConfiguration.create(context, updatesConfiguration, configOverride)
|
|
273
304
|
}
|
|
274
305
|
|
|
275
306
|
companion object {
|