1 // Copyright 2015-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.storage.ExponentSharedPreferences
7 import host.exp.exponent.kernel.ExpoViewKernel
8 import host.exp.exponent.kernel.KernelConstants
9 import expo.modules.constants.ConstantsService
10 import expo.modules.interfaces.constants.ConstantsInterface
11 import expo.modules.manifests.core.Manifest
12 import host.exp.exponent.Constants
13 import host.exp.exponent.di.NativeModuleDepsProvider
14 import org.json.JSONException
15 
16 class ConstantsBinding(
17   context: Context,
18   private val experienceProperties: Map<String, Any?>,
19   private val manifest: Manifest
20 ) : ConstantsService(context), ConstantsInterface {
21   @Inject
22   lateinit var exponentSharedPreferences: ExponentSharedPreferences
23 
getConstantsnull24   override fun getConstants(): Map<String, Any?> {
25     return super.getConstants().toMutableMap().apply {
26       this["expoVersion"] = ExpoViewKernel.instance.versionName
27       this["manifest"] = manifest.toString()
28       this["nativeAppVersion"] = ExpoViewKernel.instance.versionName
29       this["nativeBuildVersion"] = Constants.ANDROID_VERSION_CODE
30       this["supportedExpoSdks"] = Constants.SDK_VERSIONS_LIST
31       this["appOwnership"] = appOwnership
32       this["executionEnvironment"] = executionEnvironment.string
33 
34       this.putAll(experienceProperties)
35 
36       this["platform"] = mapOf(
37         "android" to mapOf(
38           "versionCode" to if (appOwnership == "expo") null else Constants.ANDROID_VERSION_CODE
39         )
40       )
41       this["isDetached"] = Constants.isStandaloneApp()
42     }
43   }
44 
getAppScopeKeynull45   override fun getAppScopeKey(): String? {
46     return try {
47       manifest.getScopeKey()
48     } catch (e: JSONException) {
49       null
50     }
51   }
52 
getAppOwnershipnull53   override fun getAppOwnership(): String {
54     return if (experienceProperties.containsKey(KernelConstants.MANIFEST_URL_KEY)) {
55       val manifestUrl = experienceProperties[KernelConstants.MANIFEST_URL_KEY] as String?
56       when {
57         Constants.INITIAL_URL == null -> "expo"
58         manifestUrl == Constants.INITIAL_URL -> "standalone"
59         else -> "guest"
60       }
61     } else {
62       "expo"
63     }
64   }
65 
66   private val executionEnvironment: ExecutionEnvironment
67     get() = if (Constants.isStandaloneApp()) {
68       ExecutionEnvironment.STANDALONE
69     } else {
70       ExecutionEnvironment.STORE_CLIENT
71     }
72 
getOrCreateInstallationIdnull73   override fun getOrCreateInstallationId(): String {
74     // Override scoped installationId from ConstantsService with unscoped
75     return exponentSharedPreferences.getOrCreateUUID()
76   }
77 
78   companion object {
convertPixelsToDpnull79     private fun convertPixelsToDp(px: Float, context: Context): Int {
80       val resources = context.resources
81       val metrics = resources.displayMetrics
82       val dp = px / (metrics.densityDpi / 160f)
83       return dp.toInt()
84     }
85   }
86 
87   init {
88     NativeModuleDepsProvider.instance.inject(ConstantsBinding::class.java, this)
89     val resourceId = context.resources.getIdentifier("status_bar_height", "dimen", "android")
90     statusBarHeightInternal = if (resourceId > 0) convertPixelsToDp(
91       context.resources.getDimensionPixelSize(resourceId).toFloat(), context
92     ) else 0
93   }
94 }
95