1 // Copyright 2015-present 650 Industries. All rights reserved.
2 package host.exp.exponent
3 
4 import android.app.IntentService
5 import android.content.Context
6 import android.content.Intent
7 import android.os.Handler
8 import host.exp.exponent.analytics.Analytics
9 import host.exp.exponent.di.NativeModuleDepsProvider
10 import host.exp.exponent.experience.ExperienceActivity
11 import host.exp.exponent.kernel.Kernel
12 import host.exp.exponent.kernel.KernelConstants
13 import javax.inject.Inject
14 
15 private const val ACTION_RELOAD_EXPERIENCE = "host.exp.exponent.action.RELOAD_EXPERIENCE"
16 private const val ACTION_STAY_AWAKE = "host.exp.exponent.action.STAY_AWAKE"
17 private const val STAY_AWAKE_MS = (1000 * 60).toLong()
18 
19 class ExponentIntentService : IntentService("ExponentIntentService") {
20   @Inject
21   lateinit var kernel: Kernel
22 
23   private val handler = Handler()
24 
25   override fun onCreate() {
26     super.onCreate()
27     NativeModuleDepsProvider.instance.inject(ExponentIntentService::class.java, this)
28   }
29 
30   override fun onHandleIntent(intent: Intent?) {
31     if (intent == null) {
32       return
33     }
34 
35     val action = intent.action
36     var isUserAction = false
37     when (action) {
38       ACTION_RELOAD_EXPERIENCE -> {
39         isUserAction = true
40         handleActionReloadExperience(intent.getStringExtra(KernelConstants.MANIFEST_URL_KEY)!!)
41       }
42       ACTION_STAY_AWAKE -> handleActionStayAwake()
43     }
44     if (isUserAction) {
45       val kernelActivityContext = kernel.activityContext
46       if (kernelActivityContext is ExperienceActivity) {
47         kernelActivityContext.onNotificationAction()
48       }
49     }
50   }
51 
52   private fun handleActionReloadExperience(manifestUrl: String) {
53     kernel.reloadVisibleExperience(manifestUrl)
54 
55     // Application can't close system dialogs on Android 31 or higher.
56     // See https://developer.android.com/about/versions/12/behavior-changes-all#close-system-dialogs
57     if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.S) {
58       val intent = Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
59       sendBroadcast(intent)
60     }
61 
62     Analytics.logEventWithManifestUrl(Analytics.AnalyticsEvent.RELOAD_EXPERIENCE, manifestUrl)
63     stopSelf()
64   }
65 
66   private fun handleActionStayAwake() {
67     handler.postDelayed({ stopSelf() }, STAY_AWAKE_MS)
68   }
69 
70   companion object {
71     @JvmStatic fun getActionReloadExperience(context: Context, manifestUrl: String): Intent {
72       return Intent(context, ExponentIntentService::class.java).apply {
73         action = ACTION_RELOAD_EXPERIENCE
74         putExtra(KernelConstants.MANIFEST_URL_KEY, manifestUrl)
75       }
76     }
77 
78     @JvmStatic fun getActionStayAwake(context: Context): Intent {
79       return Intent(context, ExponentIntentService::class.java).apply {
80         action = ACTION_STAY_AWAKE
81       }
82     }
83   }
84 }
85