1094c4dddSWill Schurman // Copyright 2015-present 650 Industries. All rights reserved. 2094c4dddSWill Schurman package host.exp.exponent.di 3094c4dddSWill Schurman 4094c4dddSWill Schurman import android.app.Application 5094c4dddSWill Schurman import android.content.Context 6094c4dddSWill Schurman import android.os.Handler 7094c4dddSWill Schurman import android.os.Looper 8094c4dddSWill Schurman import com.facebook.proguard.annotations.DoNotStrip 9094c4dddSWill Schurman import expo.modules.updates.db.DatabaseHolder 10094c4dddSWill Schurman import expo.modules.updates.db.UpdatesDatabase 11094c4dddSWill Schurman import host.exp.exponent.ExpoHandler 12094c4dddSWill Schurman import host.exp.exponent.ExponentManifest 13094c4dddSWill Schurman import host.exp.exponent.analytics.EXL 14094c4dddSWill Schurman import host.exp.exponent.kernel.services.ExpoKernelServiceRegistry 15094c4dddSWill Schurman import host.exp.exponent.network.ExponentNetwork 16094c4dddSWill Schurman import host.exp.exponent.storage.ExponentSharedPreferences 17094c4dddSWill Schurman import java.lang.reflect.Field 18094c4dddSWill Schurman import javax.inject.Inject 19094c4dddSWill Schurman 20094c4dddSWill Schurman class NativeModuleDepsProvider(application: Application) { 21094c4dddSWill Schurman @Inject 22094c4dddSWill Schurman @DoNotStrip 23094c4dddSWill Schurman val mContext: Context = application 24094c4dddSWill Schurman 25094c4dddSWill Schurman @Inject 26094c4dddSWill Schurman @DoNotStrip 27094c4dddSWill Schurman val mApplicationContext: Application = application 28094c4dddSWill Schurman 29094c4dddSWill Schurman @Inject 30094c4dddSWill Schurman @DoNotStrip 31094c4dddSWill Schurman val mExpoHandler: ExpoHandler = ExpoHandler(Handler(Looper.getMainLooper())) 32094c4dddSWill Schurman 33094c4dddSWill Schurman @Inject 34094c4dddSWill Schurman @DoNotStrip 35094c4dddSWill Schurman val mExponentSharedPreferences: ExponentSharedPreferences = ExponentSharedPreferences(mContext) 36094c4dddSWill Schurman 37094c4dddSWill Schurman @Inject 38094c4dddSWill Schurman @DoNotStrip 39094c4dddSWill Schurman val mExponentNetwork: ExponentNetwork = ExponentNetwork(mContext, mExponentSharedPreferences) 40094c4dddSWill Schurman 41094c4dddSWill Schurman @Inject 42094c4dddSWill Schurman @DoNotStrip 43*d88f0633SWill Schurman var mExponentManifest: ExponentManifest = ExponentManifest(mContext, mExponentSharedPreferences) 44094c4dddSWill Schurman 45094c4dddSWill Schurman @Inject 46094c4dddSWill Schurman @DoNotStrip 47094c4dddSWill Schurman var mKernelServiceRegistry: ExpoKernelServiceRegistry = ExpoKernelServiceRegistry(mContext, mExponentSharedPreferences) 48094c4dddSWill Schurman 49094c4dddSWill Schurman @Inject 50094c4dddSWill Schurman @DoNotStrip 51094c4dddSWill Schurman val mUpdatesDatabaseHolder: DatabaseHolder = DatabaseHolder(UpdatesDatabase.getInstance(mContext)) 52094c4dddSWill Schurman 53094c4dddSWill Schurman private val classToInstanceMap = mutableMapOf<Class<*>, Any>() 54094c4dddSWill Schurman addnull55094c4dddSWill Schurman fun add(clazz: Class<*>, instance: Any) { 56094c4dddSWill Schurman classToInstanceMap[clazz] = instance 57094c4dddSWill Schurman } 58094c4dddSWill Schurman injectnull59094c4dddSWill Schurman fun inject(clazz: Class<*>, target: Any) { 60094c4dddSWill Schurman for (field in clazz.declaredFields) { 61094c4dddSWill Schurman injectFieldInTarget(target, field) 62094c4dddSWill Schurman } 63094c4dddSWill Schurman } 64094c4dddSWill Schurman injectFieldInTargetnull65094c4dddSWill Schurman private fun injectFieldInTarget(target: Any, field: Field) { 66094c4dddSWill Schurman if (field.isAnnotationPresent(Inject::class.java)) { 67094c4dddSWill Schurman val fieldClazz = field.type 68094c4dddSWill Schurman if (!classToInstanceMap.containsKey(fieldClazz)) { 69094c4dddSWill Schurman throw RuntimeException("NativeModuleDepsProvider could not find object for class $fieldClazz") 70094c4dddSWill Schurman } 71094c4dddSWill Schurman val instance = classToInstanceMap[fieldClazz] 72094c4dddSWill Schurman try { 73094c4dddSWill Schurman field.isAccessible = true 74094c4dddSWill Schurman field[target] = instance 75094c4dddSWill Schurman } catch (e: IllegalAccessException) { 76094c4dddSWill Schurman EXL.e(TAG, e.toString()) 77094c4dddSWill Schurman } 78094c4dddSWill Schurman } 79094c4dddSWill Schurman } 80094c4dddSWill Schurman 81094c4dddSWill Schurman companion object { 82094c4dddSWill Schurman private val TAG = NativeModuleDepsProvider::class.java.simpleName 83094c4dddSWill Schurman 84094c4dddSWill Schurman @JvmStatic lateinit var instance: NativeModuleDepsProvider 85094c4dddSWill Schurman private set 86094c4dddSWill Schurman 87094c4dddSWill Schurman private var useTestInstance = false 88094c4dddSWill Schurman initializenull89094c4dddSWill Schurman fun initialize(application: Application) { 90094c4dddSWill Schurman if (!useTestInstance) { 91094c4dddSWill Schurman instance = NativeModuleDepsProvider(application) 92094c4dddSWill Schurman } 93094c4dddSWill Schurman } 94094c4dddSWill Schurman 95094c4dddSWill Schurman // Only for testing! setTestInstancenull96094c4dddSWill Schurman fun setTestInstance(instance: NativeModuleDepsProvider) { 97094c4dddSWill Schurman Companion.instance = instance 98094c4dddSWill Schurman useTestInstance = true 99094c4dddSWill Schurman } 100094c4dddSWill Schurman } 101094c4dddSWill Schurman 102094c4dddSWill Schurman init { fieldnull103094c4dddSWill Schurman for (field in NativeModuleDepsProvider::class.java.declaredFields) { 104094c4dddSWill Schurman if (field.isAnnotationPresent(Inject::class.java)) { 105094c4dddSWill Schurman try { 106094c4dddSWill Schurman classToInstanceMap[field.type] = field[this] 107094c4dddSWill Schurman } catch (e: IllegalAccessException) { 108094c4dddSWill Schurman EXL.e(TAG, e.toString()) 109094c4dddSWill Schurman } 110094c4dddSWill Schurman } 111094c4dddSWill Schurman } 112094c4dddSWill Schurman } 113094c4dddSWill Schurman } 114