Skip to content
This repository was archived by the owner on Dec 18, 2022. It is now read-only.

Commit 758a50f

Browse files
authored
Merge pull request #52 from 05nelsonm/mn/testing/tor-service-integration
Add unit test for stopping Tor
2 parents 0a18dd7 + bf137c5 commit 758a50f

File tree

13 files changed

+547
-222
lines changed

13 files changed

+547
-222
lines changed

topl-service/src/main/java/io/matthewnelson/topl_service/TorServiceController.kt

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ import io.matthewnelson.topl_core_base.TorConfigFiles
7575
import io.matthewnelson.topl_core_base.TorSettings
7676
import io.matthewnelson.topl_service.service.BaseService
7777
import io.matthewnelson.topl_service.lifecycle.BackgroundManager
78-
import io.matthewnelson.topl_service.service.components.binding.BaseServiceConnection
7978
import io.matthewnelson.topl_service.service.components.actions.ServiceActionProcessor
8079
import io.matthewnelson.topl_service.service.components.actions.ServiceActions
8180
import io.matthewnelson.topl_service.service.components.binding.TorServiceConnection
@@ -296,10 +295,7 @@ class TorServiceController private constructor(): ServiceConsts() {
296295

297296
torServiceNotificationBuilder.build(application.applicationContext)
298297

299-
backgroundManagerPolicy.build(
300-
TorService::class.java,
301-
TorServiceConnection.torServiceConnection
302-
)
298+
backgroundManagerPolicy.build()
303299
}
304300
}
305301

@@ -343,28 +339,24 @@ class TorServiceController private constructor(): ServiceConsts() {
343339
* */
344340
@Throws(RuntimeException::class)
345341
fun startTor() =
346-
BaseService.startService(
347-
BaseService.getAppContext(),
348-
TorService::class.java,
349-
TorServiceConnection.torServiceConnection
350-
)
342+
BaseService.startService(BaseService.getAppContext(), TorService::class.java)
351343

352344
/**
353345
* Stops [TorService].
354346
* */
355347
fun stopTor() =
356-
BaseServiceConnection.serviceBinder?.submitServiceAction(ServiceActions.Stop())
348+
TorServiceConnection.serviceBinder?.submitServiceAction(ServiceActions.Stop())
357349

358350
/**
359351
* Restarts Tor.
360352
* */
361353
fun restartTor() =
362-
BaseServiceConnection.serviceBinder?.submitServiceAction(ServiceActions.RestartTor())
354+
TorServiceConnection.serviceBinder?.submitServiceAction(ServiceActions.RestartTor())
363355

364356
/**
365357
* Changes identities.
366358
* */
367359
fun newIdentity() =
368-
BaseServiceConnection.serviceBinder?.submitServiceAction(ServiceActions.NewId())
360+
TorServiceConnection.serviceBinder?.submitServiceAction(ServiceActions.NewId())
369361
}
370362
}

topl-service/src/main/java/io/matthewnelson/topl_service/lifecycle/BackgroundManager.kt

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,15 @@
6666
* */
6767
package io.matthewnelson.topl_service.lifecycle
6868

69+
import android.content.Context
6970
import androidx.lifecycle.Lifecycle
7071
import androidx.lifecycle.LifecycleObserver
7172
import androidx.lifecycle.OnLifecycleEvent
7273
import androidx.lifecycle.ProcessLifecycleOwner
7374
import io.matthewnelson.topl_service.service.BaseService
7475
import io.matthewnelson.topl_service.service.TorService
7576
import io.matthewnelson.topl_service.service.components.actions.ServiceActionProcessor
76-
import io.matthewnelson.topl_service.service.components.binding.BaseServiceConnection
77+
import io.matthewnelson.topl_service.service.components.binding.TorServiceConnection
7778
import io.matthewnelson.topl_service.util.ServiceConsts
7879

7980
/**
@@ -117,15 +118,15 @@ import io.matthewnelson.topl_service.util.ServiceConsts
117118
* @param [executionDelay] Length of time before the policy gets executed *after* the application
118119
* is sent to the background.
119120
* @param [serviceClass] The Service class being managed
120-
* @param [serviceConnection] The ServiceConnection being used to bind with
121-
* @see [io.matthewnelson.topl_service.service.components.binding.TorServiceBinder.executeBackgroundPolicyJob]
122-
* @see [io.matthewnelson.topl_service.service.components.binding.TorServiceBinder.cancelExecuteBackgroundPolicyJob]
121+
* @param [bindServiceFlag] The flag to be used when binding to the service
122+
* @see [io.matthewnelson.topl_service.service.components.binding.BaseServiceBinder.executeBackgroundPolicyJob]
123+
* @see [io.matthewnelson.topl_service.service.components.binding.BaseServiceBinder.cancelExecuteBackgroundPolicyJob]
123124
* */
124125
class BackgroundManager internal constructor(
125126
@BackgroundPolicy private val policy: String,
126127
private val executionDelay: Long,
127128
private val serviceClass: Class<*>,
128-
private val serviceConnection: BaseServiceConnection
129+
private val bindServiceFlag: Int
129130
): ServiceConsts(), LifecycleObserver {
130131

131132

@@ -213,8 +214,8 @@ class BackgroundManager internal constructor(
213214
* test classes get initialized so they aren't overwritten by production classes.
214215
* */
215216
internal fun build(
216-
serviceClass: Class<*>,
217-
serviceConnection: BaseServiceConnection
217+
serviceClass: Class<*> = TorService::class.java,
218+
bindServiceFlag: Int = Context.BIND_AUTO_CREATE
218219
) {
219220

220221
// Only initialize it once. Reflection has issues here
@@ -227,7 +228,7 @@ class BackgroundManager internal constructor(
227228
policyBuilder.chosenPolicy,
228229
policyBuilder.executionDelay,
229230
serviceClass,
230-
serviceConnection
231+
bindServiceFlag
231232
)
232233
}
233234
}
@@ -257,19 +258,19 @@ class BackgroundManager internal constructor(
257258
// if the last _accepted_ ServiceAction to be issued by the Application was not to STOP
258259
// the service, then we want to put it back in the state it was in
259260
if (!ServiceActionProcessor.wasLastAcceptedServiceActionStop()) {
260-
BaseServiceConnection.serviceBinder?.cancelExecuteBackgroundPolicyJob()
261+
TorServiceConnection.serviceBinder?.cancelExecuteBackgroundPolicyJob()
261262
BaseService.startService(
262263
BaseService.getAppContext(),
263264
serviceClass,
264-
serviceConnection,
265-
includeIntentActionStart = false
265+
includeIntentActionStart = false,
266+
bindServiceFlag = bindServiceFlag
266267
)
267268
}
268269
}
269270

270271
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
271272
private fun applicationMovedToBackground() {
272273
if (!ServiceActionProcessor.wasLastAcceptedServiceActionStop())
273-
BaseServiceConnection.serviceBinder?.executeBackgroundPolicyJob(policy, executionDelay)
274+
TorServiceConnection.serviceBinder?.executeBackgroundPolicyJob(policy, executionDelay)
274275
}
275276
}

topl-service/src/main/java/io/matthewnelson/topl_service/service/BaseService.kt

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ import android.app.Service
7171
import android.content.Context
7272
import android.content.Intent
7373
import android.content.SharedPreferences
74-
import android.os.IBinder
7574
import androidx.annotation.WorkerThread
7675
import io.matthewnelson.topl_core.broadcaster.BroadcastLogger
7776
import io.matthewnelson.topl_core_base.TorConfigFiles
@@ -82,8 +81,6 @@ import io.matthewnelson.topl_service.prefs.TorServicePrefsListener
8281
import io.matthewnelson.topl_service.service.components.actions.ServiceActionProcessor
8382
import io.matthewnelson.topl_service.service.components.actions.ServiceActions
8483
import io.matthewnelson.topl_service.service.components.actions.ServiceActions.ServiceAction
85-
import io.matthewnelson.topl_service.service.components.binding.BaseServiceConnection
86-
import io.matthewnelson.topl_service.service.components.binding.TorServiceBinder
8784
import io.matthewnelson.topl_service.service.components.binding.TorServiceConnection
8885
import io.matthewnelson.topl_service.util.ServiceConsts.ServiceActionName
8986
import io.matthewnelson.topl_service.util.ServiceConsts.NotificationImage
@@ -151,7 +148,7 @@ internal abstract class BaseService: Service() {
151148
* Updates [lastAcceptedServiceAction] in several key places so that we can keep
152149
* [TorService]'s state in sync with the latest calls coming from the Application using
153150
* the Library. It is used in [TorService.onStartCommand] and
154-
* [io.matthewnelson.topl_service.service.components.binding.TorServiceBinder.submitServiceAction]
151+
* [io.matthewnelson.topl_service.service.components.binding.BaseServiceBinder.submitServiceAction]
155152
*
156153
* @param [serviceAction] The [ServiceActionName] to update [lastAcceptedServiceAction] to
157154
* */
@@ -176,35 +173,39 @@ internal abstract class BaseService: Service() {
176173
*
177174
* @param [context]
178175
* @param [serviceClass] The Service's class wanting to be started
179-
* @param [serviceConn] The [BaseServiceConnection] to bind to
180176
* @param [includeIntentActionStart] Boolean for including [ServiceActionName.START] as
181177
* the Intent's Action.
178+
* @param [bindServiceFlag] The flag to use when binding to [TorService]
182179
* */
183180
fun startService(
184181
context: Context,
185182
serviceClass: Class<*>,
186-
serviceConn: BaseServiceConnection,
187-
includeIntentActionStart: Boolean = true
183+
includeIntentActionStart: Boolean = true,
184+
bindServiceFlag: Int = Context.BIND_AUTO_CREATE
188185
) {
189186
val intent = Intent(context.applicationContext, serviceClass)
190187
if (includeIntentActionStart)
191188
intent.action = ServiceActionName.START
192189
context.applicationContext.startService(intent)
193-
context.applicationContext.bindService(intent, serviceConn, Context.BIND_AUTO_CREATE)
190+
context.applicationContext.bindService(
191+
intent,
192+
TorServiceConnection.torServiceConnection,
193+
bindServiceFlag
194+
)
194195
}
195196

196197
/**
197198
* Unbinds [TorService] from the Application and clears the reference to
198-
* [BaseServiceConnection.serviceBinder].
199+
* [TorServiceConnection.serviceBinder].
199200
*
200201
* @param [context] [Context]
201-
* @param [serviceConn] The [BaseServiceConnection] to unbind
202+
* @param [serviceConn] The [TorServiceConnection] to unbind
202203
* @throws [IllegalArgumentException] If no binding exists for the provided [serviceConn]
203204
* */
204205
@Throws(IllegalArgumentException::class)
205-
fun unbindService(context: Context, serviceConn: BaseServiceConnection) {
206-
serviceConn.clearServiceBinderReference()
207-
context.applicationContext.unbindService(serviceConn)
206+
fun unbindService(context: Context) {
207+
TorServiceConnection.torServiceConnection.clearServiceBinderReference()
208+
context.applicationContext.unbindService(TorServiceConnection.torServiceConnection)
208209
}
209210
}
210211

@@ -217,21 +218,7 @@ internal abstract class BaseService: Service() {
217218
///////////////
218219
/// Binding ///
219220
///////////////
220-
private val torServiceBinder: TorServiceBinder by lazy {
221-
TorServiceBinder(this)
222-
}
223-
224-
open fun unbindTorService(): Boolean {
225-
return try {
226-
unbindService(context, TorServiceConnection.torServiceConnection)
227-
true
228-
} catch (e: IllegalArgumentException) {
229-
false
230-
}
231-
}
232-
override fun onBind(intent: Intent?): IBinder? {
233-
return torServiceBinder
234-
}
221+
abstract fun unbindTorService()
235222

236223

237224
/////////////////////////
@@ -361,12 +348,12 @@ internal abstract class BaseService: Service() {
361348

362349

363350
override fun onTaskRemoved(rootIntent: Intent?) {
364-
// Cancel the BackgroundManager's coroutine if it's active so it doesn't execute
365-
torServiceBinder.cancelExecuteBackgroundPolicyJob()
366-
367351
// Move to the foreground so we can properly shutdown w/o interrupting the
368352
// application's normal lifecycle (Context.startServiceForeground does... thus,
369353
// the complexity)
370354
startForegroundService()
355+
356+
// Shutdown Tor and stop the Service.
357+
processServiceAction(ServiceActions.Stop(updateLastServiceAction = false))
371358
}
372359
}

topl-service/src/main/java/io/matthewnelson/topl_service/service/TorService.kt

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ import io.matthewnelson.topl_core.OnionProxyManager
7373
import io.matthewnelson.topl_core.broadcaster.BroadcastLogger
7474
import io.matthewnelson.topl_core.util.FileUtilities
7575
import io.matthewnelson.topl_service.TorServiceController
76-
import io.matthewnelson.topl_service.service.components.actions.ServiceActions
76+
import io.matthewnelson.topl_service.service.components.binding.TorServiceBinder
77+
import io.matthewnelson.topl_service.service.components.binding.TorServiceConnection
7778
import io.matthewnelson.topl_service.service.components.onionproxy.ServiceEventBroadcaster
7879
import io.matthewnelson.topl_service.service.components.onionproxy.ServiceEventListener
7980
import io.matthewnelson.topl_service.service.components.onionproxy.ServiceTorInstaller
@@ -98,15 +99,19 @@ internal class TorService: BaseService() {
9899
///////////////
99100
/// Binding ///
100101
///////////////
101-
override fun unbindTorService(): Boolean {
102-
val boolean = super.unbindTorService()
103-
if (boolean)
102+
private val torServiceBinder: TorServiceBinder by lazy {
103+
TorServiceBinder(this)
104+
}
105+
106+
override fun unbindTorService() {
107+
try {
108+
unbindService(context)
104109
broadcastLogger.debug("Has been unbound")
105-
return boolean
110+
} catch (e: IllegalArgumentException) {}
106111
}
107112
override fun onBind(intent: Intent?): IBinder? {
108113
broadcastLogger.debug("Has been bound")
109-
return super.onBind(intent)
114+
return torServiceBinder
110115
}
111116

112117

@@ -254,15 +259,10 @@ internal class TorService: BaseService() {
254259
supervisorJob.cancel()
255260
}
256261

257-
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
258-
return super.onStartCommand(intent, flags, startId)
259-
}
260-
261262
override fun onTaskRemoved(rootIntent: Intent?) {
262-
super.onTaskRemoved(rootIntent)
263+
// Cancel the BackgroundManager's coroutine if it's active so it doesn't execute
264+
torServiceBinder.cancelExecuteBackgroundPolicyJob()
263265
broadcastLogger.debug("Task has been removed")
264-
265-
// Shutdown Tor and stop the Service.
266-
processServiceAction(ServiceActions.Stop(updateLastServiceAction = false))
266+
super.onTaskRemoved(rootIntent)
267267
}
268268
}

0 commit comments

Comments
 (0)