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

Commit 0b8353a

Browse files
authored
Merge pull request #49 from 05nelsonm/mn/refactor/last-action
Refactors lastServiceAction tracking
2 parents 642f2e5 + 075e093 commit 0b8353a

File tree

8 files changed

+82
-34
lines changed

8 files changed

+82
-34
lines changed

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ import androidx.lifecycle.OnLifecycleEvent
7272
import androidx.lifecycle.ProcessLifecycleOwner
7373
import io.matthewnelson.topl_service.service.BaseService
7474
import io.matthewnelson.topl_service.service.TorService
75+
import io.matthewnelson.topl_service.service.components.actions.ServiceActionProcessor
7576
import io.matthewnelson.topl_service.service.components.binding.BaseServiceConnection
7677
import io.matthewnelson.topl_service.util.ServiceConsts
7778

@@ -255,15 +256,20 @@ class BackgroundManager internal constructor(
255256
private fun applicationMovedToForeground() {
256257
// if the last _accepted_ ServiceAction to be issued by the Application was not to STOP
257258
// the service, then we want to put it back in the state it was in
258-
if (!BaseService.wasLastAcceptedServiceActionStop()) {
259+
if (!ServiceActionProcessor.wasLastAcceptedServiceActionStop()) {
259260
BaseServiceConnection.serviceBinder?.cancelExecuteBackgroundPolicyJob()
260-
BaseService.startService(BaseService.getAppContext(), serviceClass, serviceConnection)
261+
BaseService.startService(
262+
BaseService.getAppContext(),
263+
serviceClass,
264+
serviceConnection,
265+
includeIntentActionStart = false
266+
)
261267
}
262268
}
263269

264270
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
265271
private fun applicationMovedToBackground() {
266-
if (!BaseService.wasLastAcceptedServiceActionStop())
272+
if (!ServiceActionProcessor.wasLastAcceptedServiceActionStop())
267273
BaseServiceConnection.serviceBinder?.executeBackgroundPolicyJob(policy, executionDelay)
268274
}
269275
}

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

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,29 @@ internal abstract class BaseService: Service() {
166166
/// ServiceStartup ///
167167
//////////////////////
168168

169+
/**
170+
* Starts the Service. Setting [includeIntentActionStart] to `false`, will not include
171+
* [ServiceActionName.START] in the Intent as an action so that [onStartCommand] knows
172+
* to set the [ServiceActions.Start.updateLastAction] to false. This allows for
173+
* distinguishing what is coming from the application (either by user input, or how
174+
* the application has the library implemented), and what is coming from this library.
175+
* It makes keeping the state of the service in sync with the application's desires.
176+
*
177+
* @param [context]
178+
* @param [serviceClass] The Service's class wanting to be started
179+
* @param [serviceConn] The [BaseServiceConnection] to bind to
180+
* @param [includeIntentActionStart] Boolean for including [ServiceActionName.START] as
181+
* the Intent's Action.
182+
* */
169183
fun startService(
170184
context: Context,
171185
serviceClass: Class<*>,
172-
serviceConn: BaseServiceConnection
186+
serviceConn: BaseServiceConnection,
187+
includeIntentActionStart: Boolean = true
173188
) {
174189
val intent = Intent(context.applicationContext, serviceClass)
190+
if (includeIntentActionStart)
191+
intent.action = ServiceActionName.START
175192
context.applicationContext.startService(intent)
176193
context.applicationContext.bindService(intent, serviceConn, Context.BIND_AUTO_CREATE)
177194
}
@@ -328,12 +345,17 @@ internal abstract class BaseService: Service() {
328345
}
329346

330347
/**
331-
* No matter what Intent comes in, it will update [BaseService.lastAcceptedServiceAction]
332-
* with [ServiceActionName.START] and then start Tor.
348+
* No matter what Intent comes in, it starts Tor. If the Intent comes with no Action,
349+
* it will not update [ServiceActionProcessor.lastServiceAction].
350+
*
351+
* @see [Companion.startService]
333352
* */
334353
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
335-
updateLastAcceptedServiceAction(ServiceActionName.START)
336-
processServiceAction(ServiceActions.Start())
354+
if (intent?.action == ServiceActionName.START)
355+
processServiceAction(ServiceActions.Start())
356+
else
357+
processServiceAction(ServiceActions.Start(updateLastServiceAction = false))
358+
337359
return START_NOT_STICKY
338360
}
339361

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ internal class TorService: BaseService() {
262262
super.onTaskRemoved(rootIntent)
263263
broadcastLogger.debug("Task has been removed")
264264

265-
// Shutdown Tor and stop the Service
266-
processServiceAction(ServiceActions.Stop())
265+
// Shutdown Tor and stop the Service.
266+
processServiceAction(ServiceActions.Stop(updateLastServiceAction = false))
267267
}
268268
}

topl-service/src/main/java/io/matthewnelson/topl_service/service/components/actions/ServiceActionProcessor.kt

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,11 @@ import io.matthewnelson.topl_service.util.ServiceConsts
7272
import kotlinx.coroutines.*
7373

7474
/**
75-
* [ServiceConsts.ServiceActionName]'s are translated to [ServiceAction]'s,
76-
* submitted to a queue, and then processed. This allows for sequential execution of
77-
* individual [ServiceConsts.ServiceActionCommand]'s for each [ServiceAction]
78-
* and the ability to quickly interrupt execution for reacting to User actions (such as
79-
* stopping, or clearing the task).
75+
* This class allows for sequential execution of individual [ServiceConsts.ServiceActionCommand]'s
76+
* for each [ServiceAction] and the ability to quickly interrupt execution for reacting to User
77+
* actions (such as stopping, or clearing the task). Because there are various ways to interact
78+
* with a Service (via Binding, BroadcastReceiver, or startService), this class acts as the funnel
79+
* to standardize things.
8080
*
8181
* @param [torService] [BaseService] for interacting with other components of the Service
8282
* @see [ServiceActions]
@@ -93,6 +93,16 @@ internal class ServiceActionProcessor(private val torService: BaseService): Serv
9393
restartTorDelayTime = restartMilliseconds
9494
stopServiceDelayTime = stopServiceMilliseconds
9595
}
96+
97+
//////////////////////////
98+
/// Last ServiceAction ///
99+
//////////////////////////
100+
@Volatile
101+
@ServiceActionName
102+
private var lastServiceAction: String = ServiceActionName.STOP
103+
104+
fun wasLastAcceptedServiceActionStop(): Boolean =
105+
lastServiceAction == ServiceActionName.STOP
96106
}
97107

98108
private val broadcastLogger = torService.getBroadcastLogger(ServiceActionProcessor::class.java)
@@ -112,6 +122,9 @@ internal class ServiceActionProcessor(private val torService: BaseService): Serv
112122
}
113123
}
114124

125+
if (serviceAction.updateLastAction)
126+
lastServiceAction = serviceAction.name
127+
115128
if (addActionToQueue(serviceAction))
116129
launchProcessQueueJob()
117130
}
@@ -168,7 +181,7 @@ internal class ServiceActionProcessor(private val torService: BaseService): Serv
168181
processQueueJob = torService.getScopeIO().launch {
169182
broadcastDebugMsgWithObjectDetails("Processing Queue: ", this)
170183

171-
while (actionQueue.isNotEmpty()) {
184+
while (actionQueue.isNotEmpty() && isActive) {
172185
val serviceAction = actionQueue.elementAtOrNull(0)
173186
if (serviceAction == null) {
174187
return@launch

topl-service/src/main/java/io/matthewnelson/topl_service/service/components/actions/ServiceActions.kt

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,16 @@ internal sealed class ServiceActions {
115115
delayLengthQueue.removeAt(0)
116116
else
117117
0L
118+
119+
/**
120+
* Boolean value for providing [ServiceAction]'s the capability of being issued to
121+
* the [ServiceActionProcessor] and notifying that the submitter of the [ServiceAction]
122+
* wants [ServiceActionProcessor.lastServiceAction] to be updated.
123+
*
124+
* @see [Start]
125+
* @see [Stop]
126+
* */
127+
open val updateLastAction: Boolean = true
118128
}
119129

120130
class NewId: ServiceAction() {
@@ -143,7 +153,7 @@ internal sealed class ServiceActions {
143153
override val delayLengthQueue = mutableListOf(ServiceActionProcessor.restartTorDelayTime)
144154
}
145155

146-
class Start: ServiceAction() {
156+
class Start(private val updateLastServiceAction: Boolean = true): ServiceAction() {
147157

148158
@ServiceActionName
149159
override val name: String = ServiceActionName.START
@@ -152,9 +162,12 @@ internal sealed class ServiceActions {
152162
get() = arrayOf(
153163
ServiceActionCommand.START_TOR
154164
)
165+
166+
override val updateLastAction: Boolean
167+
get() = updateLastServiceAction
155168
}
156169

157-
class Stop: ServiceAction() {
170+
class Stop(private val updateLastServiceAction: Boolean = true): ServiceAction() {
158171

159172
@ServiceActionName
160173
override val name: String = ServiceActionName.STOP
@@ -167,5 +180,8 @@ internal sealed class ServiceActions {
167180
)
168181

169182
override val delayLengthQueue = mutableListOf(ServiceActionProcessor.stopServiceDelayTime)
183+
184+
override val updateLastAction: Boolean
185+
get() = updateLastServiceAction
170186
}
171187
}

topl-service/src/main/java/io/matthewnelson/topl_service/service/components/binding/TorServiceBinder.kt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,9 @@ internal class TorServiceBinder(private val torService: BaseService): Binder() {
8383
/**
8484
* Accepts all [ServiceActions] except [ServiceActions.Start], which gets issued via
8585
* [io.matthewnelson.topl_service.service.TorService.onStartCommand].
86-
*
87-
* To be used **only** by interactions coming from the User or Application so
88-
* [BaseService.lastAcceptedServiceAction] stays in sync.
8986
* */
9087
fun submitServiceAction(serviceAction: ServiceAction) {
9188
if (serviceAction is ServiceActions.Start) return
92-
93-
BaseService.updateLastAcceptedServiceAction(serviceAction.name)
9489
torService.processServiceAction(serviceAction)
9590
}
9691

@@ -127,7 +122,9 @@ internal class TorServiceBinder(private val torService: BaseService): Binder() {
127122
BackgroundPolicy.RESPECT_RESOURCES -> {
128123
delay(executionDelay)
129124
bgMgrBroadcastLogger.debug("Executing background management policy")
130-
torService.processServiceAction(ServiceActions.Stop())
125+
torService.processServiceAction(
126+
ServiceActions.Stop(updateLastServiceAction = false)
127+
)
131128
}
132129
}
133130
}

topl-service/src/main/java/io/matthewnelson/topl_service/service/components/receiver/TorServiceReceiver.kt

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,19 +128,13 @@ internal class TorServiceReceiver(private val torService: BaseService): Broadcas
128128

129129
when (val serviceAction = intent.getStringExtra(SERVICE_INTENT_FILTER)) {
130130
ServiceActionName.NEW_ID -> {
131-
BaseServiceConnection.serviceBinder?.submitServiceAction(
132-
ServiceActions.NewId()
133-
)
131+
torService.processServiceAction(ServiceActions.NewId())
134132
}
135133
ServiceActionName.RESTART_TOR -> {
136-
BaseServiceConnection.serviceBinder?.submitServiceAction(
137-
ServiceActions.RestartTor()
138-
)
134+
torService.processServiceAction(ServiceActions.RestartTor())
139135
}
140136
ServiceActionName.STOP -> {
141-
BaseServiceConnection.serviceBinder?.submitServiceAction(
142-
ServiceActions.Stop()
143-
)
137+
torService.processServiceAction(ServiceActions.Stop())
144138
}
145139
else -> {
146140
broadcastLogger.warn(

topl-service/src/test/java/io/matthewnelson/test_helpers/service/TestTorService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,6 @@ internal class TestTorService(
216216
super.onTaskRemoved(rootIntent)
217217

218218
// Shutdown Tor and stop the Service
219-
processServiceAction(ServiceActions.Stop())
219+
processServiceAction(ServiceActions.Stop(updateLastServiceAction = false))
220220
}
221221
}

0 commit comments

Comments
 (0)