@@ -23,6 +23,7 @@ import io.github.sds100.keymapper.sysbridge.adb.AdbManager
2323import io.github.sds100.keymapper.sysbridge.manager.SystemBridgeConnectionManager
2424import io.github.sds100.keymapper.sysbridge.manager.SystemBridgeConnectionState
2525import io.github.sds100.keymapper.sysbridge.manager.awaitConnected
26+ import io.github.sds100.keymapper.sysbridge.service.SystemBridgeSetupControllerImpl.Companion.START_TIMEOUT_MS
2627import javax.inject.Inject
2728import javax.inject.Singleton
2829import kotlinx.coroutines.CoroutineScope
@@ -54,6 +55,7 @@ class SystemBridgeSetupControllerImpl @Inject constructor(
5455 companion object {
5556 private const val DEVELOPER_OPTIONS_SETTING = " development_settings_enabled"
5657 private const val ADB_WIRELESS_SETTING = " adb_wifi_enabled"
58+ private const val START_TIMEOUT_MS = 60_000L
5759 }
5860
5961 private val activityManager: ActivityManager by lazy { ctx.getSystemService()!! }
@@ -62,6 +64,9 @@ class SystemBridgeSetupControllerImpl @Inject constructor(
6264 override val isStarting: StateFlow <Boolean > = _isStarting
6365 private var startJob: Job ? = null
6466
67+ private val _showStartError : MutableSharedFlow <Unit > = MutableSharedFlow ()
68+ override val showStartError: Flow <Unit > = _showStartError
69+
6570 override val isDeveloperOptionsEnabled: MutableStateFlow <Boolean > =
6671 MutableStateFlow (getDeveloperOptionsEnabled())
6772
@@ -107,48 +112,30 @@ class SystemBridgeSetupControllerImpl @Inject constructor(
107112 }
108113
109114 override fun startWithRoot () {
110- if (startJob?.isActive == true ) {
111- Timber .i(" System Bridge is already starting" )
112- return
113- }
114-
115- startJob = coroutineScope.launch {
116- _isStarting .value = true
117- try {
118- connectionManager.startWithRoot()
119- // Wait for the service to bind and start system bridge
120- withTimeoutOrNull(10000L ) {
121- connectionManager.awaitConnected()
122- }
123- } finally {
124- _isStarting .value = false
125- }
115+ launchStartJob {
116+ connectionManager.startWithRoot()
126117 }
127118 }
128119
129120 override fun startWithShizuku () {
130- if (startJob?.isActive == true ) {
131- Timber .i(" System Bridge is already starting" )
132- return
133- }
134-
135- startJob = coroutineScope.launch {
136- _isStarting .value = true
137- try {
138- connectionManager.startWithShizuku()
139-
140- // Wait for the service to bind and start system bridge
141- withTimeoutOrNull(10000L ) {
142- connectionManager.awaitConnected()
143- }
144- } finally {
145- _isStarting .value = false
146- }
121+ launchStartJob {
122+ connectionManager.startWithShizuku()
147123 }
148124 }
149125
150126 @RequiresApi(Build .VERSION_CODES .R )
151127 override fun startWithAdb () {
128+ launchStartJob {
129+ connectionManager.startWithAdb()
130+ }
131+ }
132+
133+ /* *
134+ * Launch a start job that runs [start], then waits up to [START_TIMEOUT_MS] for the
135+ * system bridge to connect. If it does not connect in time, an error is emitted
136+ * via [showStartError].
137+ */
138+ private fun launchStartJob (start : suspend () -> Unit ) {
152139 if (startJob?.isActive == true ) {
153140 Timber .i(" System Bridge is already starting" )
154141 return
@@ -157,11 +144,17 @@ class SystemBridgeSetupControllerImpl @Inject constructor(
157144 startJob = coroutineScope.launch {
158145 _isStarting .value = true
159146 try {
160- connectionManager.startWithAdb()
147+ start()
148+
161149 // Wait for the service to bind and start system bridge
162- withTimeoutOrNull(10000L ) {
150+ val connected = withTimeoutOrNull(START_TIMEOUT_MS ) {
163151 connectionManager.awaitConnected()
164152 }
153+
154+ if (connected == null ) {
155+ Timber .e(" System Bridge failed to start within ${START_TIMEOUT_MS } ms" )
156+ _showStartError .emit(Unit )
157+ }
165158 } finally {
166159 _isStarting .value = false
167160 }
@@ -422,6 +415,7 @@ class SystemBridgeSetupControllerImpl @Inject constructor(
422415interface SystemBridgeSetupController {
423416 val setupAssistantStep: Flow <SystemBridgeSetupStep ?>
424417 val isStarting: StateFlow <Boolean >
418+ val showStartError: Flow <Unit >
425419
426420 val isDeveloperOptionsEnabled: Flow <Boolean >
427421 fun enableDeveloperOptions ()
0 commit comments