Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b3bd0b8
feat: implement bound service
tzebrowski Feb 3, 2026
1a7f483
feat: Introduce withDataLogger Fragment/Activity extensions
tzebrowski Feb 3, 2026
a74e732
fix: apply spotless fixes
tzebrowski Feb 3, 2026
757cfbf
refactor: Move DataLoggerRepository to separate cass
tzebrowski Feb 3, 2026
ea8d547
refactor: move DataLoggerConnector to base package
tzebrowski Feb 3, 2026
c84bb79
refactor: separate DataLoggerConnector from UI extensions
tzebrowski Feb 3, 2026
4892684
feat: unify datalogger access in the automotive module
tzebrowski Feb 3, 2026
ce1dd85
fix: fix unit tests
tzebrowski Feb 3, 2026
b598864
refactor: introduce Lambda with Receiver pattern
tzebrowski Feb 3, 2026
e9be168
fix: remove comments
tzebrowski Feb 3, 2026
64ef9da
fix: cleanup unused methods
tzebrowski Feb 3, 2026
40fe609
feat: Remove BaseFragment.kt
tzebrowski Feb 4, 2026
1ad906d
feat: apply singleton pattern to DataLoggerConnector
tzebrowski Feb 4, 2026
9957646
feat: re-work Prefs initialization
tzebrowski Feb 4, 2026
29590be
fix: Remove getContext()!! from DataLoggerService
tzebrowski Feb 4, 2026
f6c23fc
fix: apply spotless fixes
tzebrowski Feb 4, 2026
efeaff4
fix: apply spotless fixes
tzebrowski Feb 4, 2026
4677ffe
fix: apply spotless fixes
tzebrowski Feb 4, 2026
0df2536
fix: junit-tests fix
tzebrowski Feb 5, 2026
3cefca1
feat: improve DataLoggerService resiliance
tzebrowski Feb 5, 2026
ef35013
fix: apply spotless fixes
tzebrowski Feb 5, 2026
f7d7599
fix: update failed tests
tzebrowski Feb 5, 2026
fb0141a
fix: DataLoggerConnector implementation cleanup
tzebrowski Feb 5, 2026
5ceeaf1
fix: remove reference to workflowOrchestrator
tzebrowski Feb 5, 2026
01d4168
fix: apply spotless fixes
tzebrowski Feb 5, 2026
cbd365a
fix: hide visibility of DataLoggerConnector
tzebrowski Feb 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions app/src/main/java/org/obd/graphs/PowerBroadcastReceiver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import android.util.Log
import org.obd.graphs.activity.LOG_TAG
import org.obd.graphs.activity.MainActivity
import org.obd.graphs.bl.datalogger.DATA_LOGGER_SCHEDULED_START_EVENT
import org.obd.graphs.bl.datalogger.dataLogger
import org.obd.graphs.bl.datalogger.DATA_LOGGER_SCHEDULED_STOP_EVENT

const val SCREEN_OFF_EVENT = "power.screen.off"
const val SCREEN_ON_EVENT = "power.screen.on"
Expand Down Expand Up @@ -65,12 +65,7 @@ internal class PowerBroadcastReceiver : BroadcastReceiver() {
}

if (powerPreferences.connectOnPower) {
Log.d(
LOG_TAG,
"Stop data logging",
)
dataLogger.stop()
dataLogger.scheduledStop()
sendBroadcastEvent(DATA_LOGGER_SCHEDULED_STOP_EVENT)
}

if (powerPreferences.screenOnOff) {
Expand Down
30 changes: 15 additions & 15 deletions app/src/main/java/org/obd/graphs/activity/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,15 @@ import org.obd.graphs.MAIN_ACTIVITY_EVENT_DESTROYED
import org.obd.graphs.MAIN_ACTIVITY_EVENT_PAUSE
import org.obd.graphs.Permissions
import org.obd.graphs.R
import org.obd.graphs.bl.datalogger.dataLogger
import org.obd.graphs.bl.datalogger.DataLoggerRepository
import org.obd.graphs.bl.drag.dragRacingMetricsProcessor
import org.obd.graphs.bl.extra.vehicleStatusMetricsProcessor
import org.obd.graphs.bl.generator.MetricsGenerator
import org.obd.graphs.bl.gps.gpsMetricsEmitter
import org.obd.graphs.bl.trip.tripManager
import org.obd.graphs.cacheManager
import org.obd.graphs.network
import org.obd.graphs.preferences.initPrefs
import org.obd.graphs.profile.profile
import org.obd.graphs.sendBroadcastEvent
import org.obd.graphs.setActivityContext
Expand All @@ -58,7 +59,6 @@ const val LOG_TAG = "MainActivity"
class MainActivity :
AppCompatActivity(),
EasyPermissions.PermissionCallbacks {

lateinit var lockScreenDialog: AlertDialog
internal lateinit var backupManager: BackupManager

Expand Down Expand Up @@ -125,13 +125,14 @@ class MainActivity :

override fun onSupportNavigateUp(): Boolean {
val navController = (supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment).navController
return NavigationUI.navigateUp(navController,appBarConfiguration) || super.onSupportNavigateUp()
return NavigationUI.navigateUp(navController, appBarConfiguration) || super.onSupportNavigateUp()
}

override fun onCreate(savedInstanceState: Bundle?) {
setupStrictMode()
super.onCreate(savedInstanceState)
setActivityContext(this)
initPrefs(this)
initCache()
setContentView(R.layout.activity_main)

Expand Down Expand Up @@ -164,7 +165,6 @@ class MainActivity :
validatePermissions()
}


override fun onResume() {
super.onResume()
screen.setupWindowManager(this)
Expand All @@ -188,15 +188,15 @@ class MainActivity :
Thread.setDefaultUncaughtExceptionHandler(ExceptionHandler())
}


fun getAppBarConfiguration(): AppBarConfiguration = AppBarConfiguration(
setOf(
R.id.nav_giulia,
R.id.nav_graph,
R.id.nav_gauge,
),
findViewById<DrawerLayout>(R.id.drawer_layout)
)
fun getAppBarConfiguration(): AppBarConfiguration =
AppBarConfiguration(
setOf(
R.id.nav_giulia,
R.id.nav_graph,
R.id.nav_gauge,
),
findViewById<DrawerLayout>(R.id.drawer_layout),
)

private fun initCache() {
cacheManager.initCache(cache)
Expand Down Expand Up @@ -244,14 +244,14 @@ class MainActivity :
}

private fun setupMetricsProcessors() {
dataLogger
DataLoggerRepository
.observe(dragRacingMetricsProcessor)
.observe(tripManager)
.observe(vehicleStatusMetricsProcessor)
.observe(gpsMetricsEmitter)

if (BuildConfig.DEBUG) {
dataLogger.observe(MetricsGenerator(BuildConfig.DEBUG))
DataLoggerRepository.observe(MetricsGenerator(BuildConfig.DEBUG))
}
}

Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/org/obd/graphs/activity/Navigation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import androidx.core.os.bundleOf
import androidx.core.view.GravityCompat
import androidx.navigation.ui.NavigationUI
import org.obd.graphs.R
import org.obd.graphs.bl.datalogger.dataLogger
import org.obd.graphs.bl.datalogger.DataLoggerRepository
import org.obd.graphs.getContext
import org.obd.graphs.preferences.PREFERENCE_SCREEN_KEY
import org.obd.graphs.preferences.Prefs
Expand Down Expand Up @@ -99,7 +99,7 @@ internal fun MainActivity.setupNavigationBar() {
navController.addOnDestinationChangedListener { _, destination, _ ->

bottomAppBar {
it.menu.findItem(R.id.ctx_menu_dtc).isVisible = dataLogger.isDTCEnabled()
it.menu.findItem(R.id.ctx_menu_dtc).isVisible = DataLoggerRepository.isDTCEnabled() ?: false
it.menu.findItem(R.id.ctx_menu_android_auto)?.let {
if (NavigationRouter.isAndroidAutoEnabled(this)) {
val spanString = SpannableString(it.title.toString())
Expand Down
31 changes: 25 additions & 6 deletions app/src/main/java/org/obd/graphs/activity/Receivers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,11 @@ import org.obd.graphs.bl.datalogger.DATA_LOGGER_DTC_AVAILABLE
import org.obd.graphs.bl.datalogger.DATA_LOGGER_ERROR_CONNECT_EVENT
import org.obd.graphs.bl.datalogger.DATA_LOGGER_ERROR_EVENT
import org.obd.graphs.bl.datalogger.DATA_LOGGER_NO_NETWORK_EVENT
import org.obd.graphs.bl.datalogger.DATA_LOGGER_SCHEDULED_STOP_EVENT
import org.obd.graphs.bl.datalogger.DATA_LOGGER_STOPPED_EVENT
import org.obd.graphs.bl.datalogger.DATA_LOGGER_WIFI_INCORRECT
import org.obd.graphs.bl.datalogger.DATA_LOGGER_WIFI_NOT_CONNECTED
import org.obd.graphs.bl.datalogger.dataLogger
import org.obd.graphs.bl.datalogger.DataLoggerRepository
import org.obd.graphs.bl.datalogger.dataLoggerSettings
import org.obd.graphs.bl.extra.EVENT_VEHICLE_STATUS_IGNITION_OFF
import org.obd.graphs.bl.extra.EVENT_VEHICLE_STATUS_IGNITION_ON
Expand All @@ -81,6 +82,7 @@ import org.obd.graphs.registerReceiver
import org.obd.graphs.ui.common.COLOR_CARDINAL
import org.obd.graphs.ui.common.COLOR_PHILIPPINE_GREEN
import org.obd.graphs.ui.common.toast
import org.obd.graphs.ui.withDataLogger

internal val powerReceiver = PowerBroadcastReceiver()
const val NOTIFICATION_GRAPH_VIEW_TOGGLE = "view.graph.toggle"
Expand All @@ -96,6 +98,16 @@ private const val EVENT_VEHICLE_STATUS_CHANGED = "event.vehicle.status.CHANGED"

internal fun MainActivity.receive(intent: Intent?) {
when (intent?.action) {
DATA_LOGGER_SCHEDULED_STOP_EVENT -> {
Log.d(
LOG_TAG,
"Stop data logging",
)
withDataLogger {
stop()
scheduledStop()
}
}

NAVIGATION_BUTTONS_VISIBILITY_CHANGED -> setupNavigationBar()
GOOGLE_SIGN_IN_NO_CREDENTIAL_FAILURE -> toast(org.obd.graphs.commons.R.string.main_activity_toast_google_signin_failed)
Expand Down Expand Up @@ -150,7 +162,9 @@ internal fun MainActivity.receive(intent: Intent?) {
UsbManager.ACTION_USB_DEVICE_DETACHED -> {
val usbDevice: UsbDevice = intent.extras?.get(UsbManager.EXTRA_DEVICE) as UsbDevice
toast(R.string.pref_usb_device_detached, usbDevice.productName!!)
dataLogger.stop()
withDataLogger {
stop()
}
}

USB_DEVICE_ATTACHED_EVENT -> {
Expand Down Expand Up @@ -211,7 +225,9 @@ internal fun MainActivity.receive(intent: Intent?) {
ContextCompat.getColorStateList(applicationContext, org.obd.graphs.commons.R.color.cardinal)
it.setOnClickListener {
Log.i(LOG_TAG, "Stop data logging ")
dataLogger.stop()
withDataLogger {
stop()
}
}
it.refreshDrawableState()
}
Expand Down Expand Up @@ -264,7 +280,9 @@ internal fun MainActivity.receive(intent: Intent?) {
updateVehicleStatus("Key off")
if (dataLoggerSettings.instance().vehicleStatusDisconnectWhenOff) {
Log.i(LOG_TAG, "Received vehicle status OFF event. Closing the session.")
dataLogger.stop()
withDataLogger {
stop()
}
}
}
}
Expand Down Expand Up @@ -301,7 +319,7 @@ internal fun MainActivity.toggleNavigationItem(
internal fun MainActivity.unregisterReceiver() {
unregisterReceiver(activityBroadcastReceiver)
unregisterReceiver(powerReceiver)
unregisterReceiver(dataLogger.eventsReceiver)
unregisterReceiver(DataLoggerRepository.eventsReceiver)
}

internal fun MainActivity.registerReceiver() {
Expand Down Expand Up @@ -359,14 +377,15 @@ internal fun MainActivity.registerReceiver() {
it.addAction(REQUEST_NOTIFICATION_PERMISSIONS)
it.addAction(LOCATION_IS_DISABLED)
it.addAction(NAVIGATION_BUTTONS_VISIBILITY_CHANGED)
it.addAction(DATA_LOGGER_SCHEDULED_STOP_EVENT)
}

registerReceiver(this, powerReceiver) {
it.addAction("android.intent.action.ACTION_POWER_CONNECTED")
it.addAction("android.intent.action.ACTION_POWER_DISCONNECTED")
}

registerReceiver(this, dataLogger.eventsReceiver) {
registerReceiver(this, DataLoggerRepository.eventsReceiver) {
it.addAction(MODULES_LIST_CHANGED_EVENT)
it.addAction(PROFILE_CHANGED_EVENT)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import android.view.ViewGroup
import androidx.preference.*
import org.obd.graphs.R
import org.obd.graphs.activity.*
import org.obd.graphs.bl.datalogger.dataLogger
import org.obd.graphs.bl.datalogger.DataLoggerRepository
import org.obd.graphs.bl.trip.tripVirtualScreenManager
import org.obd.graphs.preferences.dtc.DiagnosticTroubleCodeListPreferences
import org.obd.graphs.preferences.dtc.DiagnosticTroubleCodePreferenceDialogFragment
Expand Down Expand Up @@ -191,7 +191,7 @@ class PreferencesFragment : PreferenceFragmentCompat() {

private fun hidePreferences() {
findPreference<PreferenceCategory>("pref.dtc.category")?.isVisible =
dataLogger.isDTCEnabled()
DataLoggerRepository.isDTCEnabled()
}

private fun registerListeners() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import org.obd.graphs.R
import org.obd.graphs.ViewPreferencesSerializer
import org.obd.graphs.bl.datalogger.dataLogger
import org.obd.graphs.bl.datalogger.DataLoggerRepository
import org.obd.graphs.bl.datalogger.dataLoggerSettings
import org.obd.graphs.bl.datalogger.serialize
import org.obd.graphs.bl.datalogger.vehicleCapabilitiesManager
Expand Down Expand Up @@ -317,12 +317,12 @@ open class PidDefinitionPreferenceDialogFragment(
private fun getAdapter() = (getRecyclerView(root).adapter as PidViewAdapter)

private fun sourceList(): MutableList<PidDefinitionDetails> {
val all = dataLogger.getPidDefinitionRegistry().findAll()
val all = DataLoggerRepository.getPidDefinitionRegistry().findAll()
val individualQuery = dataLoggerSettings.instance().adapter.individualQueryStrategyEnabled

val sourceList: List<PidDefinitionDetails> =
if (source == PREFERENCE_SCREEN_SOURCE_TRIP_INFO) {
val pidRegistry = dataLogger.getPidDefinitionRegistry()
val pidRegistry = DataLoggerRepository.getPidDefinitionRegistry()
val list =
Query
.instance(QueryStrategyType.TRIP_INFO_QUERY)
Expand All @@ -331,7 +331,7 @@ open class PidDefinitionPreferenceDialogFragment(
.toMutableList()
list.map { PidDefinitionDetails(it, checked = false, supported = true) }
} else if (source == PREFERENCE_SCREEN_SOURCE_PERFORMANCE) {
val pidRegistry = dataLogger.getPidDefinitionRegistry()
val pidRegistry = DataLoggerRepository.getPidDefinitionRegistry()
val list =
Query
.instance(QueryStrategyType.PERFORMANCE_QUERY)
Expand All @@ -340,18 +340,18 @@ open class PidDefinitionPreferenceDialogFragment(
.toMutableList()
list.map { PidDefinitionDetails(it, checked = false, supported = true) }
} else if (individualQuery) {
findPidDefinitionByPriority(dataLogger.getPidDefinitionRegistry().findAll()) { true }
findPidDefinitionByPriority(DataLoggerRepository.getPidDefinitionRegistry().findAll()) { true }
} else {
when (source) {
"low" -> findPidDefinitionByPriority(all) { pidDefinition -> pidDefinition.priority > 0 }
"high" -> findPidDefinitionByPriority(all) { pidDefinition -> pidDefinition.priority == 0 }
"edit" -> findPidDefinitionByPriority(dataLogger.getPidDefinitionRegistry().findAll()) { true }
"edit" -> findPidDefinitionByPriority(DataLoggerRepository.getPidDefinitionRegistry().findAll()) { true }
"dashboard" -> map(all)
"graph" -> map(all)
"gauge" -> map(all)
"giulia" -> map(all)
"aa" -> map(all)
else -> findPidDefinitionByPriority(dataLogger.getPidDefinitionRegistry().findAll()) { true }
else -> findPidDefinitionByPriority(DataLoggerRepository.getPidDefinitionRegistry().findAll()) { true }
}
}

Expand Down
65 changes: 65 additions & 0 deletions app/src/main/java/org/obd/graphs/ui/Extensions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* Copyright 2019-2026, Tomasz Żebrowski
*
* <p>Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* <p>http://www.apache.org/licenses/LICENSE-2.0
*
* <p>Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.obd.graphs.ui

import android.util.Log
import androidx.activity.ComponentActivity
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import com.google.android.material.floatingactionbutton.FloatingActionButton
import org.obd.graphs.R
import org.obd.graphs.bl.datalogger.DataLoggerRepository
import org.obd.graphs.bl.datalogger.DataLoggerService
import org.obd.graphs.bl.query.Query

fun Fragment.withDataLogger(action: DataLoggerService.() -> Unit) {
org.obd.graphs.bl.datalogger.withDataLogger(requireContext(), action)
}

fun ComponentActivity.withDataLogger(action: DataLoggerService.() -> Unit) {
org.obd.graphs.bl.datalogger.withDataLogger(this, action)
}

fun Fragment.configureActionButton(query: Query) {
activity?.let {
val btn = it.findViewById<FloatingActionButton>(R.id.connect_btn)

btn?.setOnClickListener {
if (DataLoggerRepository.isRunning()) {
withDataLogger {
Log.i("Fragment", "Stop data logging")
stop()
}
} else {
withDataLogger {
Log.i("Fragment", "Start data logging")
start(query)
}
}
}

btn?.backgroundTintList =
ContextCompat.getColorStateList(
it,
if (DataLoggerRepository.isRunning()) {
org.obd.graphs.commons.R.color.cardinal
} else {
org.obd.graphs.commons.R.color.philippine_green
},
)
}
}
Loading
Loading