From de05221f51f0020d785d4ec6c1cf2e65df66fc2c Mon Sep 17 00:00:00 2001 From: Valter Costa Date: Thu, 1 Jan 2026 21:35:55 +0000 Subject: [PATCH] Add support to change the shifting mode while in ride --- app/src/main/AndroidManifest.xml | 1 + .../datatypes/text/ShiftingModeDataType.kt | 13 +++++-- .../ki2/karoo/datatypes/views/NotAvailable.kt | 2 +- .../ki2/karoo/datatypes/views/TextView.kt | 17 +++++++--- .../ki2/karoo/datatypes/views/Waiting.kt | 2 +- .../BroadcastReceiverServiceClient.kt | 32 +++++++++++++++++ .../ki2/receivers/ChangeShiftModeReceiver.kt | 34 +++++++++++++++++++ app/src/main/res/xml/karoo_extension_info.xml | 2 +- 8 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/com/valterc/ki2/receivers/BroadcastReceiverServiceClient.kt create mode 100644 app/src/main/java/com/valterc/ki2/receivers/ChangeShiftModeReceiver.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 59d5a5b7..c7fa9682 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -77,6 +77,7 @@ android:name="io.hammerhead.karooext.MANIFEST_URL" android:value="https://github.com/valterc/ki2/releases/latest/download/manifest.json" /> + \ No newline at end of file diff --git a/app/src/main/java/com/valterc/ki2/karoo/datatypes/text/ShiftingModeDataType.kt b/app/src/main/java/com/valterc/ki2/karoo/datatypes/text/ShiftingModeDataType.kt index 88e8bca3..53e5be88 100644 --- a/app/src/main/java/com/valterc/ki2/karoo/datatypes/text/ShiftingModeDataType.kt +++ b/app/src/main/java/com/valterc/ki2/karoo/datatypes/text/ShiftingModeDataType.kt @@ -4,6 +4,7 @@ import android.content.Context import androidx.compose.ui.unit.DpSize import androidx.glance.appwidget.ExperimentalGlanceRemoteViewsApi import androidx.glance.appwidget.GlanceRemoteViews +import androidx.glance.appwidget.action.actionSendBroadcast import com.valterc.ki2.data.connection.ConnectionInfo import com.valterc.ki2.data.device.DeviceId import com.valterc.ki2.data.shifting.ShiftingInfo @@ -11,6 +12,7 @@ import com.valterc.ki2.karoo.Ki2ExtensionContext import com.valterc.ki2.karoo.datatypes.views.NotAvailable import com.valterc.ki2.karoo.datatypes.views.TextView import com.valterc.ki2.karoo.datatypes.views.Waiting +import com.valterc.ki2.receivers.ChangeShiftModeReceiver import io.hammerhead.karooext.extension.DataTypeImpl import io.hammerhead.karooext.internal.ViewEmitter import io.hammerhead.karooext.models.ShowCustomStreamState @@ -26,6 +28,7 @@ class ShiftingModeDataType(private val extensionContext: Ki2ExtensionContext) : DataTypeImpl(extensionContext.extension, "DATATYPE_SHIFTING_MODE") { private val glance = GlanceRemoteViews() + private var deviceId: DeviceId? = null private var connectionInfo: ConnectionInfo? = null private var shiftingInfo: ShiftingInfo? = null @@ -34,7 +37,8 @@ class ShiftingModeDataType(private val extensionContext: Ki2ExtensionContext) : emitter.onNext(ShowCustomStreamState(message = "", color = null)) val connectionInfoListener = - BiConsumer { _: DeviceId, connectionInfo: ConnectionInfo -> + BiConsumer { deviceId: DeviceId, connectionInfo: ConnectionInfo -> + this.deviceId = deviceId this.connectionInfo = connectionInfo CoroutineScope(Dispatchers.IO).launch { emitViewUpdate(context, config, emitter) @@ -68,13 +72,16 @@ class ShiftingModeDataType(private val extensionContext: Ki2ExtensionContext) : private suspend fun emitViewUpdate(context: Context, config: ViewConfig, emitter: ViewEmitter) { val shiftingInfo = shiftingInfo + val deviceId = deviceId + val compositionResult = - if (connectionInfo?.isConnected == true && shiftingInfo != null) { + if (deviceId != null && connectionInfo?.isConnected == true && shiftingInfo != null) { glance.compose(context, DpSize.Unspecified) { TextView( shiftingInfo.shiftingMode.mode, config.alignment, - config.textSize + config.textSize, + actionSendBroadcast(ChangeShiftModeReceiver.getIntent(context, deviceId)) ) } } else if (connectionInfo?.isClosed == true) { diff --git a/app/src/main/java/com/valterc/ki2/karoo/datatypes/views/NotAvailable.kt b/app/src/main/java/com/valterc/ki2/karoo/datatypes/views/NotAvailable.kt index 5ad693f4..f10aad4a 100644 --- a/app/src/main/java/com/valterc/ki2/karoo/datatypes/views/NotAvailable.kt +++ b/app/src/main/java/com/valterc/ki2/karoo/datatypes/views/NotAvailable.kt @@ -28,7 +28,7 @@ fun NotAvailable( Box( modifier = GlanceModifier .fillMaxSize() - .padding(5.dp), + .padding(5.dp, 0.dp), contentAlignment = Alignment( vertical = Alignment.Vertical.CenterVertically, horizontal = when (dataAlignment) { diff --git a/app/src/main/java/com/valterc/ki2/karoo/datatypes/views/TextView.kt b/app/src/main/java/com/valterc/ki2/karoo/datatypes/views/TextView.kt index 2902b780..5c19e648 100644 --- a/app/src/main/java/com/valterc/ki2/karoo/datatypes/views/TextView.kt +++ b/app/src/main/java/com/valterc/ki2/karoo/datatypes/views/TextView.kt @@ -5,6 +5,8 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.glance.GlanceModifier +import androidx.glance.action.Action +import androidx.glance.action.clickable import androidx.glance.appwidget.background import androidx.glance.color.ColorProvider import androidx.glance.layout.Alignment @@ -24,12 +26,19 @@ import io.hammerhead.karooext.models.ViewConfig fun TextView( text: String? = "", dataAlignment: ViewConfig.Alignment = ViewConfig.Alignment.RIGHT, - fontSize: Int = 50 + fontSize: Int = 50, + action: Action? = null, ) { + var boxModifier = GlanceModifier + .fillMaxSize() + .padding(start = 5.dp, top = 0.dp, end = 5.dp, bottom = 0.dp) + + if (action != null) { + boxModifier = boxModifier.clickable(action) + } + Box( - modifier = GlanceModifier - .fillMaxSize() - .padding(start = 5.dp, top = 0.dp, end = 5.dp, bottom = 0.dp), + modifier = boxModifier, contentAlignment = Alignment( vertical = Alignment.Vertical.CenterVertically, horizontal = when (dataAlignment) { diff --git a/app/src/main/java/com/valterc/ki2/karoo/datatypes/views/Waiting.kt b/app/src/main/java/com/valterc/ki2/karoo/datatypes/views/Waiting.kt index 9bf954b3..0f63eb88 100644 --- a/app/src/main/java/com/valterc/ki2/karoo/datatypes/views/Waiting.kt +++ b/app/src/main/java/com/valterc/ki2/karoo/datatypes/views/Waiting.kt @@ -28,7 +28,7 @@ fun Waiting( Box( modifier = GlanceModifier .fillMaxSize() - .padding(5.dp), + .padding(5.dp, 0.dp), contentAlignment = Alignment( vertical = Alignment.Vertical.CenterVertically, horizontal = when (dataAlignment) { diff --git a/app/src/main/java/com/valterc/ki2/receivers/BroadcastReceiverServiceClient.kt b/app/src/main/java/com/valterc/ki2/receivers/BroadcastReceiverServiceClient.kt new file mode 100644 index 00000000..54fbdfe2 --- /dev/null +++ b/app/src/main/java/com/valterc/ki2/receivers/BroadcastReceiverServiceClient.kt @@ -0,0 +1,32 @@ +package com.valterc.ki2.receivers + +import android.content.BroadcastReceiver +import android.content.Context +import com.valterc.ki2.data.device.DeviceId +import com.valterc.ki2.services.IKi2Service +import com.valterc.ki2.services.Ki2Service +import timber.log.Timber + +class BroadcastReceiverServiceClient { + + private var service: IKi2Service? = null + + constructor(context: Context, broadcastReceiver: BroadcastReceiver) { + val binder = broadcastReceiver.peekService(context, Ki2Service.getIntent()) + service = IKi2Service.Stub.asInterface(binder) + Timber.i("Peek service: %s", service != null) + } + + fun changeShiftMode(deviceId: DeviceId): Boolean { + service?.let { service -> + try { + service.changeShiftMode(deviceId) + return true + } catch (e: Exception) { + Timber.e(e, "Error changing shift mode for device %s", deviceId) + } + } + + return false + } +} \ No newline at end of file diff --git a/app/src/main/java/com/valterc/ki2/receivers/ChangeShiftModeReceiver.kt b/app/src/main/java/com/valterc/ki2/receivers/ChangeShiftModeReceiver.kt new file mode 100644 index 00000000..2cb3ffae --- /dev/null +++ b/app/src/main/java/com/valterc/ki2/receivers/ChangeShiftModeReceiver.kt @@ -0,0 +1,34 @@ +package com.valterc.ki2.receivers + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import com.valterc.ki2.data.device.DeviceId +import timber.log.Timber + +@Suppress("DEPRECATION") +class ChangeShiftModeReceiver : BroadcastReceiver() { + + override fun onReceive(context: Context, intent: Intent) { + try { + val serviceClient = BroadcastReceiverServiceClient(context, this) + val deviceId = intent.extras?.getParcelable(DEVICE_ID_KEY) + Timber.i("Received intent to change shift mode for device: %s", deviceId) + deviceId?.let { deviceId -> + serviceClient.changeShiftMode(deviceId) + } + } catch (e: Exception) { + Timber.e(e, "Error when receiving broadcast to change shift mode") + } + } + + companion object { + const val DEVICE_ID_KEY = "DeviceId" + + fun getIntent(context: Context, deviceId: DeviceId): Intent { + return Intent(context, ChangeShiftModeReceiver::class.java).apply { + putExtra(DEVICE_ID_KEY, deviceId) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/xml/karoo_extension_info.xml b/app/src/main/res/xml/karoo_extension_info.xml index a8a11385..7518e85c 100644 --- a/app/src/main/res/xml/karoo_extension_info.xml +++ b/app/src/main/res/xml/karoo_extension_info.xml @@ -12,7 +12,7 @@ typeId="DATATYPE_SHIFTING_BATTERY_PERCENTAGE" />