From cde1be75ba189fbf73c61623db85f7e4d2cc62e9 Mon Sep 17 00:00:00 2001 From: Philoul Date: Thu, 12 Oct 2023 00:36:54 +0200 Subject: [PATCH] Draft Refactor Communication --- .../maintenance/PrefFileListProvider.kt | 3 +- .../rx/events/EventMobileDataToWear.kt | 2 +- .../rx/weardata/CustomWatchfaceFormat.kt | 44 ++++++++++++++----- .../core/interfaces/rx/weardata/EventData.kt | 7 ++- core/utils/src/main/res/values/keys.xml | 1 + .../maintenance/PrefFileListProviderImpl.kt | 13 +++--- .../CustomWatchfaceImportListActivity.kt | 19 +++++--- .../plugins/main/general/wear/WearPlugin.kt | 10 +++-- .../wear/wearintegration/DataHandlerMobile.kt | 19 ++++++++ .../DataLayerListenerServiceMobile.kt | 3 +- .../app/aaps/wear/comm/DataHandlerWear.kt | 14 +++++- .../wear/comm/DataLayerListenerServiceWear.kt | 11 +++-- .../wear/interaction/utils/Persistence.kt | 38 ++++++++++++++++ .../aaps/wear/watchfaces/CustomWatchface.kt | 7 ++- 14 files changed, 150 insertions(+), 41 deletions(-) diff --git a/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/maintenance/PrefFileListProvider.kt b/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/maintenance/PrefFileListProvider.kt index ed0f3745cc..263cf8e052 100644 --- a/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/maintenance/PrefFileListProvider.kt +++ b/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/maintenance/PrefFileListProvider.kt @@ -1,6 +1,7 @@ package app.aaps.core.interfaces.maintenance import app.aaps.core.interfaces.rx.weardata.CwfData +import app.aaps.core.interfaces.rx.weardata.CwfFile import java.io.File interface PrefFileListProvider { @@ -13,7 +14,7 @@ interface PrefFileListProvider { fun newExportCsvFile(): File fun newCwfFile(filename: String, withDate: Boolean = true): File fun listPreferenceFiles(loadMetadata: Boolean = false): MutableList - fun listCustomWatchfaceFiles(): MutableList + fun listCustomWatchfaceFiles(): MutableList fun checkMetadata(metadata: Map): Map fun formatExportedAgo(utcTime: String): String } \ No newline at end of file diff --git a/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/rx/events/EventMobileDataToWear.kt b/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/rx/events/EventMobileDataToWear.kt index 6f3ef85b9b..05a7bfcec8 100644 --- a/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/rx/events/EventMobileDataToWear.kt +++ b/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/rx/events/EventMobileDataToWear.kt @@ -2,4 +2,4 @@ package app.aaps.core.interfaces.rx.events import app.aaps.core.interfaces.rx.weardata.EventData -class EventMobileDataToWear(val payload: EventData.ActionSetCustomWatchface) : Event() \ No newline at end of file +class EventMobileDataToWear(val payload: ByteArray) : Event() \ No newline at end of file diff --git a/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/rx/weardata/CustomWatchfaceFormat.kt b/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/rx/weardata/CustomWatchfaceFormat.kt index d20837ca88..4ef514e29a 100644 --- a/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/rx/weardata/CustomWatchfaceFormat.kt +++ b/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/rx/weardata/CustomWatchfaceFormat.kt @@ -12,6 +12,7 @@ import com.caverock.androidsvg.SVG import kotlinx.serialization.Serializable import org.json.JSONObject import java.io.BufferedOutputStream +import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.File import java.io.FileOutputStream @@ -134,10 +135,18 @@ data class ResData(val value: ByteArray, val format: ResFormat) { typealias CwfResDataMap = MutableMap typealias CwfMetadataMap = MutableMap -fun CwfResDataMap.isEquals(dataMap: CwfResDataMap) = (this.size == dataMap.size) && this.all { (key, resData) -> dataMap[key]?.value.contentEquals(resData.value) == true } +fun CwfResDataMap.sameRes(dataMap: CwfResDataMap) = (this.size == dataMap.size) && this.all { (key, resData) -> dataMap[key]?.value.contentEquals(resData.value) == true } +fun CwfMetadataMap.sameMeta(metaDataMap: CwfMetadataMap) = (this.size == metaDataMap.size) && this.all { (key, string) -> metaDataMap[key] == string } @Serializable -data class CwfData(val json: String, var metadata: CwfMetadataMap, val resDatas: CwfResDataMap) +data class CwfData(val json: String, var metadata: CwfMetadataMap, val resDatas: CwfResDataMap) { + fun simplify(): CwfData? = resDatas[ResFileMap.CUSTOM_WATCHFACE.fileName]?.let { + val simplifiedDatas: CwfResDataMap = mutableMapOf() + simplifiedDatas[ResFileMap.CUSTOM_WATCHFACE.fileName] = it + CwfData(json, metadata, simplifiedDatas) + } +} +data class CwfFile(val cwfData: CwfData, val zipByteArray: ByteArray) enum class CwfMetadataKey(val key: String, @StringRes val label: Int, val isPref: Boolean) { @@ -286,24 +295,24 @@ class ZipWatchfaceFormat { const val CWF_EXTENTION = ".zip" const val CWF_JSON_FILE = "CustomWatchface.json" - fun loadCustomWatchface(zipInputStream: ZipInputStream, zipName: String, authorization: Boolean): CwfData? { + fun loadCustomWatchface(zipInputStream: ZipInputStream, zipName: String, authorization: Boolean): CwfFile? { var json = JSONObject() var metadata: CwfMetadataMap = mutableMapOf() val resDatas: CwfResDataMap = mutableMapOf() - + val testZip = byteArrayToZipInputStream(zipInputStreamToByteArray(zipInputStream)) try { - var zipEntry: ZipEntry? = zipInputStream.nextEntry + var zipEntry: ZipEntry? = testZip.nextEntry while (zipEntry != null) { val entryName = zipEntry.name val buffer = ByteArray(2048) val byteArrayOutputStream = ByteArrayOutputStream() - var count = zipInputStream.read(buffer) + var count = testZip.read(buffer) while (count != -1) { byteArrayOutputStream.write(buffer, 0, count) - count = zipInputStream.read(buffer) + count = testZip.read(buffer) } - zipInputStream.closeEntry() + testZip.closeEntry() if (entryName == CWF_JSON_FILE) { val jsonString = byteArrayOutputStream.toByteArray().toString(Charsets.UTF_8) @@ -319,12 +328,12 @@ class ZipWatchfaceFormat { } else if (drawableFormat != ResFormat.UNKNOWN) resDatas[entryName.substringBeforeLast(".")] = ResData(byteArrayOutputStream.toByteArray(), drawableFormat) } - zipEntry = zipInputStream.nextEntry + zipEntry = testZip.nextEntry } // Valid CWF file must contains a valid json file with a name within metadata and a custom watchface image return if (metadata.containsKey(CwfMetadataKey.CWF_NAME) && resDatas.containsKey(ResFileMap.CUSTOM_WATCHFACE.fileName)) - CwfData(json.toString(4), metadata, resDatas) + CwfFile(CwfData(json.toString(4), metadata, resDatas), zipInputStreamToByteArray(zipInputStream)) else null @@ -368,5 +377,20 @@ class ZipWatchfaceFormat { } return metadata } + + fun zipInputStreamToByteArray(zipInputStream: ZipInputStream): ByteArray { + val buffer = ByteArray(1024) + val byteArrayOutputStream = ByteArrayOutputStream() + var len: Int + while (zipInputStream.read(buffer).also { len = it } > 0) { + byteArrayOutputStream.write(buffer, 0, len) + } + return byteArrayOutputStream.toByteArray() + } + + fun byteArrayToZipInputStream(byteArray: ByteArray): ZipInputStream { + val byteArrayInputStream = ByteArrayInputStream(byteArray) + return ZipInputStream(byteArrayInputStream) + } } } \ No newline at end of file diff --git a/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/rx/weardata/EventData.kt b/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/rx/weardata/EventData.kt index e20a0796b9..744712d139 100644 --- a/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/rx/weardata/EventData.kt +++ b/core/interfaces/src/main/kotlin/app/aaps/core/interfaces/rx/weardata/EventData.kt @@ -292,10 +292,9 @@ sealed class EventData : Event() { } @Serializable - data class ActionSetCustomWatchface( - val customWatchfaceData: CwfData - ) : EventData() - + data class ActionSetCustomWatchface(val customWatchfaceData: CwfData) : EventData() + @Serializable + data class ActionUpdateCustomWatchface(val customWatchfaceData: CwfData) : EventData() @Serializable data class ActionrequestCustomWatchface(val exportFile: Boolean) : EventData() diff --git a/core/utils/src/main/res/values/keys.xml b/core/utils/src/main/res/values/keys.xml index f8e845faa9..f8d1c22142 100644 --- a/core/utils/src/main/res/values/keys.xml +++ b/core/utils/src/main/res/values/keys.xml @@ -116,6 +116,7 @@ wearwizard_cob wearwizard_iob wear_custom_watchface_autorization + wear_custom_watchface_save_cwfdata ObjectivesbgIsAvailableInNS ObjectivespumpStatusIsAvailableInNS statuslights_cage_warning diff --git a/plugins/configuration/src/main/kotlin/app/aaps/plugins/configuration/maintenance/PrefFileListProviderImpl.kt b/plugins/configuration/src/main/kotlin/app/aaps/plugins/configuration/maintenance/PrefFileListProviderImpl.kt index fe466ef4e9..291470136d 100644 --- a/plugins/configuration/src/main/kotlin/app/aaps/plugins/configuration/maintenance/PrefFileListProviderImpl.kt +++ b/plugins/configuration/src/main/kotlin/app/aaps/plugins/configuration/maintenance/PrefFileListProviderImpl.kt @@ -12,6 +12,7 @@ import app.aaps.core.interfaces.maintenance.PrefsMetadataKey import app.aaps.core.interfaces.resources.ResourceHelper import app.aaps.core.interfaces.rx.bus.RxBus import app.aaps.core.interfaces.rx.weardata.CwfData +import app.aaps.core.interfaces.rx.weardata.CwfFile import app.aaps.core.interfaces.rx.weardata.EventData import app.aaps.core.interfaces.rx.weardata.ZipWatchfaceFormat import app.aaps.core.interfaces.sharedPreferences.SP @@ -97,11 +98,11 @@ class PrefFileListProviderImpl @Inject constructor( return prefFiles } - override fun listCustomWatchfaceFiles(): MutableList { - val customWatchfaceFiles = mutableListOf() - val customAwtchfaceAuthorization = sp.getBoolean(app.aaps.core.utils.R.string.key_wear_custom_watchface_autorization, false) + override fun listCustomWatchfaceFiles(): MutableList { + val customWatchfaceFiles = mutableListOf() + val customWatchfaceAuthorization = sp.getBoolean(app.aaps.core.utils.R.string.key_wear_custom_watchface_autorization, false) exportsPath.walk().filter { it.isFile && it.name.endsWith(ZipWatchfaceFormat.CWF_EXTENTION) }.forEach { file -> - ZipWatchfaceFormat.loadCustomWatchface(ZipInputStream(file.inputStream()), file.name, customAwtchfaceAuthorization)?.also { customWatchface -> + ZipWatchfaceFormat.loadCustomWatchface(ZipInputStream(file.inputStream()), file.name, customWatchfaceAuthorization)?.also { customWatchface -> customWatchfaceFiles.add(customWatchface) } } @@ -111,9 +112,9 @@ class PrefFileListProviderImpl @Inject constructor( for (assetFileName in assetFiles) { if (assetFileName.endsWith(ZipWatchfaceFormat.CWF_EXTENTION)) { val assetInputStream = context.assets.open(assetFileName) - ZipWatchfaceFormat.loadCustomWatchface(ZipInputStream(assetInputStream), assetFileName, customAwtchfaceAuthorization)?.also { customWatchface -> + ZipWatchfaceFormat.loadCustomWatchface(ZipInputStream(assetInputStream), assetFileName, customWatchfaceAuthorization)?.also { customWatchface -> customWatchfaceFiles.add(customWatchface) - rxBus.send(EventData.ActionGetCustomWatchface(EventData.ActionSetCustomWatchface(customWatchface), exportFile = true, withDate = false)) + //rxBus.send(EventData.ActionGetCustomWatchface(EventData.ActionSetCustomWatchface(customWatchface.cwfData), exportFile = true, withDate = false)) } assetInputStream.close() } diff --git a/plugins/configuration/src/main/kotlin/app/aaps/plugins/configuration/maintenance/activities/CustomWatchfaceImportListActivity.kt b/plugins/configuration/src/main/kotlin/app/aaps/plugins/configuration/maintenance/activities/CustomWatchfaceImportListActivity.kt index f42849b993..b200ea53be 100644 --- a/plugins/configuration/src/main/kotlin/app/aaps/plugins/configuration/maintenance/activities/CustomWatchfaceImportListActivity.kt +++ b/plugins/configuration/src/main/kotlin/app/aaps/plugins/configuration/maintenance/activities/CustomWatchfaceImportListActivity.kt @@ -15,6 +15,7 @@ import app.aaps.core.interfaces.rx.bus.RxBus import app.aaps.core.interfaces.rx.events.EventMobileDataToWear import app.aaps.core.interfaces.rx.weardata.CUSTOM_VERSION import app.aaps.core.interfaces.rx.weardata.CwfData +import app.aaps.core.interfaces.rx.weardata.CwfFile import app.aaps.core.interfaces.rx.weardata.CwfMetadataKey.CWF_AUTHOR import app.aaps.core.interfaces.rx.weardata.CwfMetadataKey.CWF_AUTHOR_VERSION import app.aaps.core.interfaces.rx.weardata.CwfMetadataKey.CWF_CREATED_AT @@ -22,6 +23,7 @@ import app.aaps.core.interfaces.rx.weardata.CwfMetadataKey.CWF_FILENAME import app.aaps.core.interfaces.rx.weardata.CwfMetadataKey.CWF_NAME import app.aaps.core.interfaces.rx.weardata.CwfMetadataKey.CWF_VERSION import app.aaps.core.interfaces.rx.weardata.CwfMetadataMap +import app.aaps.core.interfaces.rx.weardata.CwfResDataMap import app.aaps.core.interfaces.rx.weardata.EventData import app.aaps.core.interfaces.rx.weardata.ResFileMap import app.aaps.core.interfaces.rx.weardata.ZipWatchfaceFormat @@ -56,10 +58,10 @@ class CustomWatchfaceImportListActivity : TranslatedDaggerAppCompatActivity() { supportActionBar?.setDisplayShowTitleEnabled(true) binding.recyclerview.layoutManager = LinearLayoutManager(this) - binding.recyclerview.adapter = RecyclerViewAdapter(prefFileListProvider.listCustomWatchfaceFiles().sortedBy { it.metadata[CWF_NAME] }) + binding.recyclerview.adapter = RecyclerViewAdapter(prefFileListProvider.listCustomWatchfaceFiles().sortedBy { it.cwfData.metadata[CWF_NAME] }) } - inner class RecyclerViewAdapter internal constructor(private var customWatchfaceFileList: List) : RecyclerView.Adapter() { + inner class RecyclerViewAdapter internal constructor(private var customWatchfaceFileList: List) : RecyclerView.Adapter() { inner class CwfFileViewHolder(val customWatchfaceImportListItemBinding: CustomWatchfaceImportListItemBinding) : RecyclerView.ViewHolder(customWatchfaceImportListItemBinding.root) { @@ -67,11 +69,14 @@ class CustomWatchfaceImportListActivity : TranslatedDaggerAppCompatActivity() { with(customWatchfaceImportListItemBinding) { root.isClickable = true customWatchfaceImportListItemBinding.root.setOnClickListener { - val customWatchfaceFile = filelistName.tag as CwfData - val customWF = EventData.ActionSetCustomWatchface(customWatchfaceFile) + val customWatchfaceFile = filelistName.tag as CwfFile + val cwfData = CwfData(customWatchfaceFile.cwfData.json, customWatchfaceFile.cwfData.metadata, mutableMapOf()) + //Save json and metadata + sp.putString(app.aaps.core.utils.R.string.key_wear_custom_watchface_save_cwfData, EventData.ActionSetCustomWatchface(cwfData).serialize()) val i = Intent() setResult(FragmentActivity.RESULT_OK, i) - rxBus.send(EventMobileDataToWear(customWF)) + rxBus.send(EventMobileDataToWear(customWatchfaceFile.zipByteArray)) + aapsLogger.debug("XXXXX: ${customWatchfaceFile.zipByteArray.size}") finish() } } @@ -89,8 +94,8 @@ class CustomWatchfaceImportListActivity : TranslatedDaggerAppCompatActivity() { override fun onBindViewHolder(holder: CwfFileViewHolder, position: Int) { val customWatchfaceFile = customWatchfaceFileList[position] - val metadata = customWatchfaceFile.metadata - val drawable = customWatchfaceFile.resDatas[ResFileMap.CUSTOM_WATCHFACE.fileName]?.toDrawable(resources) + val metadata = customWatchfaceFile.cwfData.metadata + val drawable = customWatchfaceFile.cwfData.resDatas[ResFileMap.CUSTOM_WATCHFACE.fileName]?.toDrawable(resources) with(holder.customWatchfaceImportListItemBinding) { val fileName = metadata[CWF_FILENAME]?.let { "$it${ZipWatchfaceFormat.CWF_EXTENTION}" } ?: "" filelistName.text = rh.gs(app.aaps.core.interfaces.R.string.metadata_wear_import_filename, fileName) diff --git a/plugins/main/src/main/kotlin/app/aaps/plugins/main/general/wear/WearPlugin.kt b/plugins/main/src/main/kotlin/app/aaps/plugins/main/general/wear/WearPlugin.kt index 391a731c9c..c02def89b9 100644 --- a/plugins/main/src/main/kotlin/app/aaps/plugins/main/general/wear/WearPlugin.kt +++ b/plugins/main/src/main/kotlin/app/aaps/plugins/main/general/wear/WearPlugin.kt @@ -114,10 +114,12 @@ class WearPlugin @Inject constructor( savedCustomWatchface?.let { cwf -> val cwf_authorization = sp.getBoolean(app.aaps.core.utils.R.string.key_wear_custom_watchface_autorization, false) if (cwf_authorization != cwf.metadata[CwfMetadataKey.CWF_AUTHORIZATION]?.toBooleanStrictOrNull()) { - // resend new customWatchface to Watch with updated authorization for preferences update - val newCwf = cwf.copy() - newCwf.metadata[CwfMetadataKey.CWF_AUTHORIZATION] = sp.getBoolean(app.aaps.core.utils.R.string.key_wear_custom_watchface_autorization, false).toString() - rxBus.send(EventMobileDataToWear(EventData.ActionSetCustomWatchface(newCwf))) + // update new customWatchface to Watch with updated authorization for preferences update + CwfData(cwf.json, cwf.metadata, mutableMapOf()).also { + it.metadata[CwfMetadataKey.CWF_AUTHORIZATION] = sp.getBoolean(app.aaps.core.utils.R.string.key_wear_custom_watchface_autorization, false).toString() + sp.putString(app.aaps.core.utils.R.string.key_wear_custom_watchface_save_cwfData, EventData.ActionSetCustomWatchface(it).serialize()) + rxBus.send(EventMobileToWear(EventData.ActionUpdateCustomWatchface(it))) + } } } } diff --git a/plugins/main/src/main/kotlin/app/aaps/plugins/main/general/wear/wearintegration/DataHandlerMobile.kt b/plugins/main/src/main/kotlin/app/aaps/plugins/main/general/wear/wearintegration/DataHandlerMobile.kt index c55939ecbc..09355413aa 100644 --- a/plugins/main/src/main/kotlin/app/aaps/plugins/main/general/wear/wearintegration/DataHandlerMobile.kt +++ b/plugins/main/src/main/kotlin/app/aaps/plugins/main/general/wear/wearintegration/DataHandlerMobile.kt @@ -31,6 +31,7 @@ import app.aaps.core.interfaces.rx.AapsSchedulers import app.aaps.core.interfaces.rx.bus.RxBus import app.aaps.core.interfaces.rx.events.EventMobileToWear import app.aaps.core.interfaces.rx.events.EventWearUpdateGui +import app.aaps.core.interfaces.rx.weardata.CwfMetadataKey import app.aaps.core.interfaces.rx.weardata.EventData import app.aaps.core.interfaces.sharedPreferences.SP import app.aaps.core.interfaces.ui.UiInteraction @@ -70,6 +71,7 @@ import app.aaps.plugins.main.R import dagger.android.HasAndroidInjector import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign +import org.json.JSONObject import java.text.DateFormat import java.text.SimpleDateFormat import java.util.Date @@ -1267,6 +1269,23 @@ class DataHandlerMobile @Inject constructor( private fun handleGetCustomWatchface(command: EventData.ActionGetCustomWatchface) { val customWatchface = command.customWatchface aapsLogger.debug(LTag.WEAR, "Custom Watchface received from ${command.sourceNodeId}: ${customWatchface.customWatchfaceData.json}") + try { + + var s = sp.getStringOrNull(app.aaps.core.utils.R.string.key_wear_custom_watchface_save_cwfData, null) + if (s != null) { + (EventData.deserialize(s) as EventData.ActionSetCustomWatchface).also { savedCwData -> + if (customWatchface.customWatchfaceData.json != savedCwData.customWatchfaceData.json && + customWatchface.customWatchfaceData.metadata[CwfMetadataKey.CWF_NAME] == savedCwData.customWatchfaceData.metadata[CwfMetadataKey.CWF_NAME] && + customWatchface.customWatchfaceData.metadata[CwfMetadataKey.CWF_AUTHOR_VERSION] == savedCwData.customWatchfaceData.metadata[CwfMetadataKey.CWF_AUTHOR_VERSION] + ) { + // if different json but same name and author version, then resync json and metadata to watch to update filename and authorization + rxBus.send(EventMobileToWear(EventData.ActionUpdateCustomWatchface(savedCwData.customWatchfaceData))) + } + } + } + } catch (exception: Exception) { + aapsLogger.error(LTag.WEAR, exception.toString()) + } rxBus.send(EventWearUpdateGui(customWatchface.customWatchfaceData, command.exportFile)) if (command.exportFile) importExportPrefs.exportCustomWatchface(customWatchface.customWatchfaceData, command.withDate) diff --git a/plugins/main/src/main/kotlin/app/aaps/plugins/main/general/wear/wearintegration/DataLayerListenerServiceMobile.kt b/plugins/main/src/main/kotlin/app/aaps/plugins/main/general/wear/wearintegration/DataLayerListenerServiceMobile.kt index ec3685409c..ff7254effa 100644 --- a/plugins/main/src/main/kotlin/app/aaps/plugins/main/general/wear/wearintegration/DataLayerListenerServiceMobile.kt +++ b/plugins/main/src/main/kotlin/app/aaps/plugins/main/general/wear/wearintegration/DataLayerListenerServiceMobile.kt @@ -93,7 +93,7 @@ class DataLayerListenerServiceMobile : WearableListenerService() { disposable += rxBus .toObservable(EventMobileDataToWear::class.java) .observeOn(aapsSchedulers.io) - .subscribe { sendMessage(rxDataPath, it.payload.serializeByte()) } + .subscribe { sendMessage(rxDataPath, it.payload) } } override fun onCapabilityChanged(p0: CapabilityInfo) { @@ -214,6 +214,7 @@ class DataLayerListenerServiceMobile : WearableListenerService() { private fun sendMessage(path: String, data: ByteArray) { aapsLogger.debug(LTag.WEAR, "sendMessage: $path") + aapsLogger.debug("XXXXX: $path, ${data.size}") transcriptionNodeId?.also { nodeId -> messageClient .sendMessage(nodeId, path, data).apply { diff --git a/wear/src/main/kotlin/app/aaps/wear/comm/DataHandlerWear.kt b/wear/src/main/kotlin/app/aaps/wear/comm/DataHandlerWear.kt index 119fc92587..038f2124f8 100644 --- a/wear/src/main/kotlin/app/aaps/wear/comm/DataHandlerWear.kt +++ b/wear/src/main/kotlin/app/aaps/wear/comm/DataHandlerWear.kt @@ -186,7 +186,17 @@ class DataHandlerWear @Inject constructor( .subscribe { aapsLogger.debug(LTag.WEAR, "Custom Watchface received from ${it.sourceNodeId}") persistence.store(it) - persistence.readCustomWatchface()?.let { + persistence.readSimplifiedCwf()?.let { + rxBus.send(EventWearDataToMobile(EventData.ActionGetCustomWatchface(it, false))) + } + } + disposable += rxBus + .toObservable(EventData.ActionUpdateCustomWatchface::class.java) + .observeOn(aapsSchedulers.io) + .subscribe { + aapsLogger.debug(LTag.WEAR, "Custom Watchface received from ${it.sourceNodeId}") + persistence.store(it) + persistence.readSimplifiedCwf()?.let { rxBus.send(EventWearDataToMobile(EventData.ActionGetCustomWatchface(it, false))) } } @@ -205,7 +215,7 @@ class DataHandlerWear @Inject constructor( .observeOn(aapsSchedulers.io) .subscribe { eventData -> aapsLogger.debug(LTag.WEAR, "Custom Watchface requested from ${eventData.sourceNodeId} export ${eventData.exportFile}") - persistence.readCustomWatchface(eventData.exportFile)?.let { + persistence.readSimplifiedCwf(eventData.exportFile)?.let { rxBus.send(EventWearDataToMobile(EventData.ActionGetCustomWatchface(it, eventData.exportFile))) } } diff --git a/wear/src/main/kotlin/app/aaps/wear/comm/DataLayerListenerServiceWear.kt b/wear/src/main/kotlin/app/aaps/wear/comm/DataLayerListenerServiceWear.kt index 11914555ad..348a705a06 100644 --- a/wear/src/main/kotlin/app/aaps/wear/comm/DataLayerListenerServiceWear.kt +++ b/wear/src/main/kotlin/app/aaps/wear/comm/DataLayerListenerServiceWear.kt @@ -12,6 +12,7 @@ import app.aaps.core.interfaces.rx.bus.RxBus import app.aaps.core.interfaces.rx.events.EventWearDataToMobile import app.aaps.core.interfaces.rx.events.EventWearToMobile import app.aaps.core.interfaces.rx.weardata.EventData +import app.aaps.core.interfaces.rx.weardata.ZipWatchfaceFormat import app.aaps.core.interfaces.sharedPreferences.SP import app.aaps.wear.interaction.utils.Persistence import app.aaps.wear.interaction.utils.WearUtil @@ -127,9 +128,13 @@ class DataLayerListenerServiceWear : WearableListenerService() { } rxDataPath -> { - aapsLogger.debug(LTag.WEAR, "onMessageReceived: ${messageEvent.data}") - val command = EventData.deserializeByte(messageEvent.data) - rxBus.send(command.also { it.sourceNodeId = messageEvent.sourceNodeId }) + aapsLogger.debug(LTag.WEAR, "onMessageReceived: ${messageEvent.data.size}") + ZipWatchfaceFormat.loadCustomWatchface(ZipWatchfaceFormat.byteArrayToZipInputStream(messageEvent.data), "NewWatchface", false)?.let { + val command = EventData.ActionSetCustomWatchface(it.cwfData) + rxBus.send(command.also { it.sourceNodeId = messageEvent.sourceNodeId }) + + aapsLogger.debug("XXXXX: ${it.cwfData.json}") + } // Use this sender transcriptionNodeId = messageEvent.sourceNodeId aapsLogger.debug(LTag.WEAR, "Updated node: $transcriptionNodeId") diff --git a/wear/src/main/kotlin/app/aaps/wear/interaction/utils/Persistence.kt b/wear/src/main/kotlin/app/aaps/wear/interaction/utils/Persistence.kt index 67dcf70797..d9a1630926 100644 --- a/wear/src/main/kotlin/app/aaps/wear/interaction/utils/Persistence.kt +++ b/wear/src/main/kotlin/app/aaps/wear/interaction/utils/Persistence.kt @@ -3,6 +3,9 @@ package app.aaps.wear.interaction.utils import app.aaps.annotations.OpenForTesting import app.aaps.core.interfaces.logging.AAPSLogger import app.aaps.core.interfaces.logging.LTag +import app.aaps.core.interfaces.rx.events.EventMobileToWear +import app.aaps.core.interfaces.rx.weardata.CwfData +import app.aaps.core.interfaces.rx.weardata.CwfMetadataKey import app.aaps.core.interfaces.rx.weardata.EventData import app.aaps.core.interfaces.rx.weardata.EventData.Companion.deserialize import app.aaps.core.interfaces.rx.weardata.EventData.SingleBg @@ -149,6 +152,26 @@ open class Persistence @Inject constructor( return null } + fun readSimplifiedCwf(isDefault: Boolean = false): EventData.ActionSetCustomWatchface? { + try { + var s = sp.getStringOrNull(if (isDefault) CUSTOM_DEFAULT_WATCHFACE else CUSTOM_WATCHFACE, null) + if (s != null) { + return (deserialize(s) as EventData.ActionSetCustomWatchface).let { + EventData.ActionSetCustomWatchface(it.customWatchfaceData.simplify() ?:it.customWatchfaceData) + } + + } else { + s = sp.getStringOrNull(CUSTOM_DEFAULT_WATCHFACE, null) + if (s != null) { + return deserialize(s) as EventData.ActionSetCustomWatchface + } + } + } catch (exception: Exception) { + aapsLogger.error(LTag.WEAR, exception.toString()) + } + return null + } + fun store(singleBg: SingleBg) { putString(BG_DATA_PERSISTENCE_KEY, singleBg.serialize()) aapsLogger.debug(LTag.WEAR, "Stored BG data: $singleBg") @@ -175,6 +198,21 @@ open class Persistence @Inject constructor( aapsLogger.debug(LTag.WEAR, "Stored Custom Watchface ${customWatchface.customWatchfaceData} ${isdefault}: $customWatchface") } + fun store(customWatchface: EventData.ActionUpdateCustomWatchface) { + readCustomWatchface()?.let { savedCwData -> + if (customWatchface.customWatchfaceData.metadata[CwfMetadataKey.CWF_NAME] == savedCwData.customWatchfaceData.metadata[CwfMetadataKey.CWF_NAME] && + customWatchface.customWatchfaceData.metadata[CwfMetadataKey.CWF_AUTHOR_VERSION] == savedCwData.customWatchfaceData.metadata[CwfMetadataKey.CWF_AUTHOR_VERSION] + ) { + // if different json but same name and author version, then resync json and metadata to watch to update filename and authorization + val newCwfData = CwfData(customWatchface.customWatchfaceData.json, customWatchface.customWatchfaceData.metadata, savedCwData.customWatchfaceData.resDatas) + EventData.ActionSetCustomWatchface(newCwfData).also { + putString(CUSTOM_WATCHFACE, it.serialize()) + aapsLogger.debug(LTag.WEAR, "Update Custom Watchface ${it.customWatchfaceData} : $customWatchface") + } + } + } +} + fun setDefaultWatchface() { readCustomWatchface(true)?.let { store(it) } aapsLogger.debug(LTag.WEAR, "Custom Watchface reset to default") diff --git a/wear/src/main/kotlin/app/aaps/wear/watchfaces/CustomWatchface.kt b/wear/src/main/kotlin/app/aaps/wear/watchfaces/CustomWatchface.kt index 345812cb27..c2f9b6df52 100644 --- a/wear/src/main/kotlin/app/aaps/wear/watchfaces/CustomWatchface.kt +++ b/wear/src/main/kotlin/app/aaps/wear/watchfaces/CustomWatchface.kt @@ -44,7 +44,8 @@ import app.aaps.core.interfaces.rx.weardata.ResFileMap import app.aaps.core.interfaces.rx.weardata.ResFormat import app.aaps.core.interfaces.rx.weardata.ViewKeys import app.aaps.core.interfaces.rx.weardata.ZipWatchfaceFormat -import app.aaps.core.interfaces.rx.weardata.isEquals +import app.aaps.core.interfaces.rx.weardata.sameMeta +import app.aaps.core.interfaces.rx.weardata.sameRes import app.aaps.wear.R import app.aaps.wear.databinding.ActivityCustomBinding import app.aaps.wear.watchfaces.utils.BaseWatchFace @@ -66,6 +67,7 @@ class CustomWatchface : BaseWatchFace() { private var lowBatColor = Color.RED private var resDataMap: CwfResDataMap = mutableMapOf() private var json = JSONObject() + private var metadata: CwfMetadataMap = mutableMapOf() private var jsonString = "" private val bgColor: Int get() = when (singleBg.sgvLevel) { @@ -153,8 +155,9 @@ class CustomWatchface : BaseWatchFace() { updatePref(it.customWatchfaceData.metadata) try { json = JSONObject(it.customWatchfaceData.json) - if (!resDataMap.isEquals(it.customWatchfaceData.resDatas) || jsonString != it.customWatchfaceData.json) { + if (!resDataMap.sameRes(it.customWatchfaceData.resDatas) || !metadata.sameMeta(it.customWatchfaceData.metadata) || jsonString != it.customWatchfaceData.json) { resDataMap = it.customWatchfaceData.resDatas + metadata = it.customWatchfaceData.metadata jsonString = it.customWatchfaceData.json FontMap.init(this) ViewMap.init(this)