1 package host.exp.exponent.experience
2 
3 import com.facebook.react.bridge.NativeModule
4 import com.facebook.react.bridge.ReactApplicationContext
5 import expo.modules.adapters.react.ReactModuleRegistryProvider
6 import expo.modules.core.ModuleRegistry
7 import expo.modules.core.interfaces.RegistryLifecycleListener
8 import expo.modules.notifications.notifications.categories.ExpoNotificationCategoriesModule
9 import expo.modules.notifications.notifications.handling.NotificationsHandler
10 import expo.modules.notifications.notifications.scheduling.NotificationScheduler
11 import host.exp.exponent.utils.ScopedContext
12 import host.exp.exponent.kernel.ExperienceKey
13 import expo.modules.manifests.core.Manifest
14 import versioned.host.exp.exponent.modules.universal.*
15 import versioned.host.exp.exponent.modules.universal.notifications.ScopedServerRegistrationModule
16 
17 open class DetachedModuleRegistryAdapter(moduleRegistryProvider: ReactModuleRegistryProvider) :
18   ExpoModuleRegistryAdapter(moduleRegistryProvider) {
19 
20   override fun createNativeModules(
21     scopedContext: ScopedContext,
22     experienceKey: ExperienceKey,
23     experienceProperties: Map<String, Any?>,
24     manifest: Manifest,
25     otherModules: List<NativeModule>
26   ): List<NativeModule> {
27     val reactApplicationContext = scopedContext.context as ReactApplicationContext
28 
29     // We only use React application context, because we're detached -- no scopes
30     val moduleRegistry = mModuleRegistryProvider[reactApplicationContext]
31 
32     moduleRegistry.registerInternalModule(
33       ConstantsBinding(
34         scopedContext,
35         experienceProperties,
36         manifest
37       )
38     )
39 
40     // Overriding expo-updates UpdatesService
41     moduleRegistry.registerInternalModule(UpdatesBinding(scopedContext, experienceProperties))
42 
43     // ReactAdapterPackage requires ReactContext
44     val reactContext = scopedContext.context as ReactApplicationContext
45     for (internalModule in mReactAdapterPackage.createInternalModules(reactContext)) {
46       moduleRegistry.registerInternalModule(internalModule)
47     }
48 
49     // Overriding ScopedUIManagerModuleWrapper from ReactAdapterPackage
50     moduleRegistry.registerInternalModule(ScopedUIManagerModuleWrapper(reactContext))
51 
52     // Overriding expo-file-system FileSystemModule
53     moduleRegistry.registerExportedModule(ScopedFileSystemModule(scopedContext))
54 
55     // Overriding expo-secure-store
56     moduleRegistry.registerExportedModule(ScopedSecureStoreModule(scopedContext))
57 
58     // Certain notifications classes should share `SharedPreferences` object with the notifications services, so we don't want to use scoped context.
59     moduleRegistry.registerExportedModule(NotificationScheduler(scopedContext.baseContext))
60     moduleRegistry.registerExportedModule(ExpoNotificationCategoriesModule(scopedContext.baseContext))
61     moduleRegistry.registerExportedModule(NotificationsHandler(scopedContext.baseContext))
62     // We consciously pass scoped context to ScopedServerRegistrationModule
63     // so it can access legacy scoped backed-up storage and migrates
64     // the legacy UUID to scoped non-backed-up storage.
65     moduleRegistry.registerExportedModule(ScopedServerRegistrationModule(scopedContext))
66 
67     // Adding other modules (not universal) to module registry as consumers.
68     // It allows these modules to refer to universal modules.
69     for (otherModule in otherModules) {
70       if (otherModule is RegistryLifecycleListener) {
71         moduleRegistry.registerExtraListener(otherModule as RegistryLifecycleListener)
72       }
73     }
74     configureModuleRegistry(moduleRegistry, reactApplicationContext)
75     return getNativeModulesFromModuleRegistry(reactApplicationContext, moduleRegistry)
76   }
77 
78   protected open fun configureModuleRegistry(
79     moduleRegistry: ModuleRegistry,
80     reactContext: ReactApplicationContext
81   ) {
82     // Subclasses may add more modules here.
83   }
84 }
85