@@ -21,6 +21,7 @@ import com.evsuite.tasker.util.BtDevices
2121import com.evsuite.tasker.util.BtMessaging
2222import com.evsuite.tasker.util.CarLocation
2323import com.evsuite.tasker.util.DriveClock
24+ import com.evsuite.tasker.util.LocationTriggerDetector
2425import com.evsuite.tasker.util.Notifier
2526import com.evsuite.tasker.util.ParkTriggerDetector
2627import com.evsuite.tasker.vehicle.BtOnboard
@@ -56,6 +57,12 @@ class TaskerVehicleService : Service() {
5657 private const val ONBOARD_SAMPLE_MS = 15_000L
5758 /* * Gear has no portable push callback on every supported generation. Poll only in RUN. */
5859 private const val PARK_SAMPLE_MS = 500L
60+ /* *
61+ * How often position rules are checked while in RUN. At 50 km/h the car covers ~70 m
62+ * between two looks — inside any radius worth writing — and each look is one cached
63+ * fix and one read of the rule store, no vehicle binder call.
64+ */
65+ private const val LOCATION_SAMPLE_MS = 5_000L
5966 private const val HARDKEY_ACTION = " com.saic.keyevent.hardkey.report"
6067 private const val SYSTEMUI_HARDKEY_ACTION = " com.android.systemui.ACTION_HARD_KEY_EVENT"
6168 const val HARDKEY_PERMISSION = " com.evsuite.tasker.permission.RECEIVE_HARDKEY"
@@ -95,6 +102,7 @@ class TaskerVehicleService : Service() {
95102 private var lastTrigger: RuleTrigger ? = null
96103
97104 private val parkTrigger = ParkTriggerDetector ()
105+ private val locationTrigger = LocationTriggerDetector ()
98106
99107 /* * Stops an in-flight park sample from scheduling itself again after ignition-off. */
100108 @Volatile
@@ -127,6 +135,21 @@ class TaskerVehicleService : Service() {
127135 }
128136 }
129137
138+ /* * Shares the park sampler's lifecycle and thread: RUN only, detector reset at each edge. */
139+ private val locationSampler = object : Runnable {
140+ override fun run () {
141+ if (! vehicleRunning) return
142+ val rules = RuleStore (this @TaskerVehicleService).getAll().filter {
143+ it.enabled && ! it.hasPhysicalButtonCondition && it.firesOn == RuleTrigger .LOCATION
144+ }
145+ val fix = CarLocation .lastKnown(applicationContext)
146+ for (id in locationTrigger.sample(rules, fix)) {
147+ runRulesFor(RuleTrigger .LOCATION , " Position condition turned true" , id)
148+ }
149+ if (vehicleRunning) onboardHandler.postDelayed(this , LOCATION_SAMPLE_MS )
150+ }
151+ }
152+
130153 override fun onBind (intent : Intent ? ): IBinder ? = null
131154
132155 override fun onCreate () {
@@ -213,6 +236,7 @@ class TaskerVehicleService : Service() {
213236 vehicleRunning = false
214237 onboardHandler.removeCallbacks(onboardSampler)
215238 onboardHandler.removeCallbacks(parkSampler)
239+ onboardHandler.removeCallbacks(locationSampler)
216240 onboardThread.quitSafely()
217241 }
218242
@@ -229,24 +253,33 @@ class TaskerVehicleService : Service() {
229253 if (vehicleRunning) return
230254 vehicleRunning = true
231255 onboardHandler.removeCallbacks(parkSampler)
256+ onboardHandler.removeCallbacks(locationSampler)
232257 onboardHandler.post {
233258 parkTrigger.reset()
234- if (vehicleRunning) parkSampler.run ()
259+ locationTrigger.reset()
260+ if (vehicleRunning) {
261+ parkSampler.run ()
262+ locationSampler.run ()
263+ }
235264 }
236265 }
237266
238267 private fun stopParkSampling () {
239268 if (! vehicleRunning) return
240269 vehicleRunning = false
241270 onboardHandler.removeCallbacks(parkSampler)
271+ onboardHandler.removeCallbacks(locationSampler)
242272 // Keep detector mutation on its sampling thread.
243- onboardHandler.post { parkTrigger.reset() }
273+ onboardHandler.post {
274+ parkTrigger.reset()
275+ locationTrigger.reset()
276+ }
244277 }
245278
246- private fun runRulesFor (trigger : RuleTrigger , event : String ) {
279+ private fun runRulesFor (trigger : RuleTrigger , event : String , ruleId : String? = null ) {
247280 if (AppState .isAutomationEnabled(this )) {
248- AppLogger .i(TAG , " $event → evaluating ${trigger.name} rules" )
249- thread(name = " mg4-tasker-cycle" ) { RuleCycle .run (this , trigger.name) }
281+ AppLogger .i(TAG , " $event → evaluating ${trigger.name} rules${ruleId?. let { " ( $it ) " }.orEmpty()} " )
282+ thread(name = " mg4-tasker-cycle" ) { RuleCycle .run (this , trigger.name, ruleId = ruleId ) }
250283 } else {
251284 AppLogger .i(TAG , " $event but automation disabled — ignored" )
252285 }
0 commit comments