1 // Copyright 2020-present 650 Industries. All rights reserved.
2 package versioned.host.exp.exponent.modules.universal
3 
4 import android.content.Context
5 import javax.inject.Inject
6 import host.exp.exponent.ExpoUpdatesAppLoader
7 import expo.modules.updates.UpdatesConfiguration
8 import expo.modules.updates.UpdatesInterface
9 import expo.modules.updates.UpdatesService
10 import expo.modules.updates.db.DatabaseHolder
11 import expo.modules.updates.selectionpolicy.SelectionPolicy
12 import expo.modules.updates.statemachine.UpdatesStateMachine
13 import expo.modules.updates.loader.FileDownloader
14 import expo.modules.updates.db.entity.UpdateEntity
15 import expo.modules.updates.db.entity.AssetEntity
16 import expo.modules.updates.launcher.Launcher.LauncherCallback
17 import host.exp.exponent.kernel.KernelProvider
18 import host.exp.exponent.di.NativeModuleDepsProvider
19 import host.exp.exponent.kernel.KernelConstants
20 import java.io.File
21 
22 /**
23  * Scoped internal module which overrides [UpdatesService] at runtime in Expo Go, and gives
24  * [UpdatesModule] access to the correct instance of [ExpoUpdatesAppLoader].
25  */
26 class UpdatesBinding(context: Context, experienceProperties: Map<String, Any?>) :
27   UpdatesService(context), UpdatesInterface {
28 
29   @Inject
30   lateinit var databaseHolderInternal: DatabaseHolder
31 
32   private var manifestUrl: String?
33   private var appLoader: ExpoUpdatesAppLoader?
34 
getExportedInterfacesnull35   override fun getExportedInterfaces(): List<Class<*>> {
36     return listOf(UpdatesInterface::class.java as Class<*>)
37   }
38 
39   override val configuration: UpdatesConfiguration
40     get() = appLoader!!.updatesConfiguration
41 
42   override val selectionPolicy: SelectionPolicy
43     get() = appLoader!!.selectionPolicy
44 
45   override val directory: File
46     get() = appLoader!!.updatesDirectory
47 
48   override val fileDownloader: FileDownloader
49     get() = appLoader!!.fileDownloader
50 
51   override val databaseHolder: DatabaseHolder
52     get() = databaseHolderInternal
53 
54   override val isEmergencyLaunch: Boolean
55     get() = appLoader!!.isEmergencyLaunch
56 
57   override val isUsingEmbeddedAssets: Boolean
58     get() = false
59 
canRelaunchnull60   override fun canRelaunch(): Boolean {
61     return true
62   }
63   override val stateMachine: UpdatesStateMachine?
64     get() = null
65 
66   override val embeddedUpdate: UpdateEntity? = null
67 
68   override val launchedUpdate: UpdateEntity?
69     get() = appLoader!!.launcher.launchedUpdate
70 
71   override val localAssetFiles: Map<AssetEntity, String>?
72     get() = appLoader!!.launcher.localAssetFiles
73 
relaunchReactApplicationnull74   override fun relaunchReactApplication(callback: LauncherCallback) {
75     KernelProvider.instance.reloadVisibleExperience(manifestUrl!!, true)
76     callback.onSuccess()
77   }
78 
resetSelectionPolicynull79   override fun resetSelectionPolicy() {
80     // no-op in managed
81   }
82 
83   companion object {
84     private val TAG = UpdatesBinding::class.java.simpleName
85   }
86 
87   init {
88     NativeModuleDepsProvider.instance.inject(UpdatesBinding::class.java, this)
89     manifestUrl = experienceProperties[KernelConstants.MANIFEST_URL_KEY] as String?
90     appLoader = KernelProvider.instance.getAppLoaderForManifestUrl(manifestUrl)
91   }
92 }
93