/
HomeActivity.kt
187 lines (169 loc) · 7.2 KB
/
HomeActivity.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// Copyright 2015-present 650 Industries. All rights reserved.
package host.exp.exponent.experience
import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.os.Debug
import android.view.View
import androidx.core.content.ContextCompat
import com.facebook.react.ReactRootView
import com.facebook.soloader.SoLoader
import com.squareup.leakcanary.LeakCanary
import de.greenrobot.event.EventBus
import expo.modules.application.ApplicationModule
import expo.modules.asset.AssetModule
import expo.modules.barcodescanner.BarCodeScannerModule
import expo.modules.barcodescanner.BarCodeScannerPackage
import expo.modules.blur.BlurModule
import expo.modules.camera.CameraViewModule
import expo.modules.clipboard.ClipboardModule
import expo.modules.constants.ConstantsModule
import expo.modules.constants.ConstantsPackage
import expo.modules.core.interfaces.Package
import expo.modules.device.DeviceModule
import expo.modules.easclient.EASClientModule
import expo.modules.facedetector.FaceDetectorPackage
import expo.modules.filesystem.FileSystemModule
import expo.modules.filesystem.FileSystemPackage
import expo.modules.haptics.HapticsModule
import expo.modules.keepawake.KeepAwakeModule
import expo.modules.keepawake.KeepAwakePackage
import expo.modules.kotlin.ModulesProvider
import expo.modules.kotlin.modules.Module
import expo.modules.lineargradient.LinearGradientModule
import expo.modules.notifications.NotificationsPackage
import expo.modules.splashscreen.SplashScreenImageResizeMode
import expo.modules.splashscreen.SplashScreenModule
import expo.modules.splashscreen.SplashScreenPackage
import expo.modules.splashscreen.singletons.SplashScreen
import expo.modules.storereview.StoreReviewModule
import expo.modules.taskManager.TaskManagerPackage
import expo.modules.trackingtransparency.TrackingTransparencyModule
import expo.modules.webbrowser.WebBrowserModule
import host.exp.exponent.Constants
import host.exp.exponent.ExponentManifest
import host.exp.exponent.RNObject
import host.exp.exponent.di.NativeModuleDepsProvider
import host.exp.exponent.kernel.ExperienceKey
import host.exp.exponent.kernel.Kernel.KernelStartedRunningEvent
import host.exp.exponent.utils.ExperienceActivityUtils
import host.exp.exponent.utils.ExperienceRTLManager
import host.exp.expoview.BuildConfig
import org.json.JSONException
import javax.inject.Inject
open class HomeActivity : BaseExperienceActivity() {
@Inject
lateinit var exponentManifest: ExponentManifest
//region Activity Lifecycle
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
NativeModuleDepsProvider.instance.inject(HomeActivity::class.java, this)
sdkVersion = RNObject.UNVERSIONED
manifest = exponentManifest.getKernelManifestAndAssetRequestHeaders().manifest
experienceKey = try {
ExperienceKey.fromManifest(manifest!!)
} catch (e: JSONException) {
ExperienceKey("")
}
// @sjchmiela, @lukmccall: We are consciously not overriding UI mode in Home, because it has no effect.
// `ExpoAppearanceModule` with which `ExperienceActivityUtils#overrideUiMode` is compatible
// is disabled in Home as of end of 2020, to fix some issues with dev menu, see:
// https://github.com/expo/expo/blob/eb9bd274472e646a730fd535a4bcf360039cbd49/android/expoview/src/main/java/versioned/host/exp/exponent/ExponentPackage.java#L200-L207
// ExperienceActivityUtils.overrideUiMode(mExponentManifest.getKernelManifest(), this);
ExperienceActivityUtils.configureStatusBar(exponentManifest.getKernelManifestAndAssetRequestHeaders().manifest, this)
EventBus.getDefault().registerSticky(this)
kernel.startJSKernel(this)
ExperienceRTLManager.setSupportsRTL(this, false)
SplashScreen.show(this, SplashScreenImageResizeMode.NATIVE, ReactRootView::class.java, true)
tryInstallLeakCanary(true)
}
override fun shouldCreateLoadingView(): Boolean {
// Home app shouldn't show LoadingView as it indicates state when the app's manifest is being
// downloaded and Splash info is not yet available and this is not the case for Home app
// (Splash info is known from the start).
return false
}
override fun onResume() {
super.onResume()
SoLoader.init(this, false)
}
//endregion Activity Lifecycle
/**
* This method has been split out from onDestroy lifecycle method to [ReactNativeActivity.destroyReactInstanceManager]
* and overridden here as we want to prevent destroying react instance manager when HomeActivity gets destroyed.
* It needs to continue to live since it is needed for DevMenu to work as expected (it relies on ExponentKernelModule from that react context).
*/
override fun destroyReactInstanceManager() {}
private fun tryInstallLeakCanary(shouldAskForPermissions: Boolean) {
if (BuildConfig.DEBUG && Constants.ENABLE_LEAK_CANARY) {
// Leak canary needs WRITE_EXTERNAL_STORAGE permission
if (shouldAskForPermissions && ContextCompat.checkSelfPermission(
this,
Manifest.permission.WRITE_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED
) {
requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1248919246)
} else {
LeakCanary.install(application)
}
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
tryInstallLeakCanary(false)
}
fun onEventMainThread(event: KernelStartedRunningEvent?) {
reactInstanceManager.assign(kernel.reactInstanceManager)
reactRootView.assign(kernel.reactRootView)
reactInstanceManager.onHostResume(this, this)
setReactRootView((reactRootView.get() as View))
finishLoading()
if (Constants.DEBUG_COLD_START_METHOD_TRACING) {
Debug.stopMethodTracing()
}
}
override fun onError(intent: Intent) {
intent.putExtra(ErrorActivity.IS_HOME_KEY, true)
kernel.setHasError()
}
companion object : ModulesProvider {
fun homeExpoPackages(): List<Package> {
return listOf(
ConstantsPackage(),
FileSystemPackage(),
BarCodeScannerPackage(),
KeepAwakePackage(),
FaceDetectorPackage(),
NotificationsPackage(), // home doesn't use notifications, but we want the singleton modules created
TaskManagerPackage(), // load expo-task-manager to restore tasks once the client is opened
SplashScreenPackage()
)
}
override fun getModulesList(): List<Class<out Module>> {
return listOf(
AssetModule::class.java,
BarCodeScannerModule::class.java,
BlurModule::class.java,
CameraViewModule::class.java,
ClipboardModule::class.java,
ConstantsModule::class.java,
DeviceModule::class.java,
EASClientModule::class.java,
FileSystemModule::class.java,
HapticsModule::class.java,
KeepAwakeModule::class.java,
LinearGradientModule::class.java,
SplashScreenModule::class.java,
TrackingTransparencyModule::class.java,
StoreReviewModule::class.java,
WebBrowserModule::class.java,
ApplicationModule::class.java
)
}
}
}