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 4ef514e29a..cab1b1787b 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 @@ -135,9 +135,7 @@ data class ResData(val value: ByteArray, val format: ResFormat) { typealias CwfResDataMap = MutableMap typealias CwfMetadataMap = MutableMap -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 } - +fun CwfResDataMap.isEquals(dataMap: CwfResDataMap) = (this.size == dataMap.size) && this.all { (key, resData) -> dataMap[key]?.value.contentEquals(resData.value) == true } @Serializable data class CwfData(val json: String, var metadata: CwfMetadataMap, val resDatas: CwfResDataMap) { fun simplify(): CwfData? = resDatas[ResFileMap.CUSTOM_WATCHFACE.fileName]?.let { @@ -295,24 +293,24 @@ class ZipWatchfaceFormat { const val CWF_EXTENTION = ".zip" const val CWF_JSON_FILE = "CustomWatchface.json" - fun loadCustomWatchface(zipInputStream: ZipInputStream, zipName: String, authorization: Boolean): CwfFile? { + fun loadCustomWatchface(byteArray: ByteArray, zipName: String, authorization: Boolean): CwfFile? { var json = JSONObject() var metadata: CwfMetadataMap = mutableMapOf() val resDatas: CwfResDataMap = mutableMapOf() - val testZip = byteArrayToZipInputStream(zipInputStreamToByteArray(zipInputStream)) + val zipInputStream = byteArrayToZipInputStream(byteArray) try { - var zipEntry: ZipEntry? = testZip.nextEntry + var zipEntry: ZipEntry? = zipInputStream.nextEntry while (zipEntry != null) { val entryName = zipEntry.name val buffer = ByteArray(2048) val byteArrayOutputStream = ByteArrayOutputStream() - var count = testZip.read(buffer) + var count = zipInputStream.read(buffer) while (count != -1) { byteArrayOutputStream.write(buffer, 0, count) - count = testZip.read(buffer) + count = zipInputStream.read(buffer) } - testZip.closeEntry() + zipInputStream.closeEntry() if (entryName == CWF_JSON_FILE) { val jsonString = byteArrayOutputStream.toByteArray().toString(Charsets.UTF_8) @@ -328,12 +326,12 @@ class ZipWatchfaceFormat { } else if (drawableFormat != ResFormat.UNKNOWN) resDatas[entryName.substringBeforeLast(".")] = ResData(byteArrayOutputStream.toByteArray(), drawableFormat) } - zipEntry = testZip.nextEntry + zipEntry = zipInputStream.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)) - CwfFile(CwfData(json.toString(4), metadata, resDatas), zipInputStreamToByteArray(zipInputStream)) + CwfFile(CwfData(json.toString(4), metadata, resDatas), byteArray) else null @@ -378,16 +376,6 @@ 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) diff --git a/core/utils/src/main/res/values/keys.xml b/core/utils/src/main/res/values/keys.xml index f8d1c22142..b98cdfe2c0 100644 --- a/core/utils/src/main/res/values/keys.xml +++ b/core/utils/src/main/res/values/keys.xml @@ -116,7 +116,9 @@ wearwizard_cob wearwizard_iob wear_custom_watchface_autorization - wear_custom_watchface_save_cwfdata + wear_cwf_watchface_name + wear_cwf_author_version + wear_cwf_filename 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 291470136d..33f1162eca 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 @@ -102,7 +102,7 @@ class PrefFileListProviderImpl @Inject constructor( 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, customWatchfaceAuthorization)?.also { customWatchface -> + ZipWatchfaceFormat.loadCustomWatchface(file.readBytes(), file.name, customWatchfaceAuthorization)?.also { customWatchface -> customWatchfaceFiles.add(customWatchface) } } @@ -111,12 +111,11 @@ class PrefFileListProviderImpl @Inject constructor( val assetFiles = context.assets.list("") ?: arrayOf() for (assetFileName in assetFiles) { if (assetFileName.endsWith(ZipWatchfaceFormat.CWF_EXTENTION)) { - val assetInputStream = context.assets.open(assetFileName) - ZipWatchfaceFormat.loadCustomWatchface(ZipInputStream(assetInputStream), assetFileName, customWatchfaceAuthorization)?.also { customWatchface -> + val assetByteArray = context.assets.open(assetFileName).readBytes() + ZipWatchfaceFormat.loadCustomWatchface(assetByteArray, assetFileName, customWatchfaceAuthorization)?.also { customWatchface -> customWatchfaceFiles.add(customWatchface) - //rxBus.send(EventData.ActionGetCustomWatchface(EventData.ActionSetCustomWatchface(customWatchface.cwfData), exportFile = true, withDate = false)) + rxBus.send(EventData.ActionGetCustomWatchface(EventData.ActionSetCustomWatchface(customWatchface.cwfData), exportFile = true, withDate = false)) } - assetInputStream.close() } } } catch (e: Exception) { 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 b200ea53be..3858a4135d 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 @@ -70,13 +70,13 @@ class CustomWatchfaceImportListActivity : TranslatedDaggerAppCompatActivity() { root.isClickable = true customWatchfaceImportListItemBinding.root.setOnClickListener { 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()) + sp.putString(app.aaps.core.utils.R.string.key_wear_cwf_watchface_name, customWatchfaceFile.cwfData.metadata[CWF_NAME] ?:"") + sp.putString(app.aaps.core.utils.R.string.key_wear_cwf_author_version, customWatchfaceFile.cwfData.metadata[CWF_AUTHOR_VERSION] ?:"") + sp.putString(app.aaps.core.utils.R.string.key_wear_cwf_filename, customWatchfaceFile.cwfData.metadata[CWF_FILENAME] ?:"") + val i = Intent() setResult(FragmentActivity.RESULT_OK, i) rxBus.send(EventMobileDataToWear(customWatchfaceFile.zipByteArray)) - aapsLogger.debug("XXXXX: ${customWatchfaceFile.zipByteArray.size}") finish() } } 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 c02def89b9..46cea0082b 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 @@ -11,7 +11,6 @@ import app.aaps.core.interfaces.rx.bus.RxBus import app.aaps.core.interfaces.rx.events.EventAutosensCalculationFinished import app.aaps.core.interfaces.rx.events.EventDismissBolusProgressIfRunning import app.aaps.core.interfaces.rx.events.EventLoopUpdateGui -import app.aaps.core.interfaces.rx.events.EventMobileDataToWear import app.aaps.core.interfaces.rx.events.EventMobileToWear import app.aaps.core.interfaces.rx.events.EventOverviewBolusProgress import app.aaps.core.interfaces.rx.events.EventPreferenceChange @@ -112,14 +111,23 @@ class WearPlugin @Inject constructor( fun checkCustomWatchfacePreferences() { 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()) { - // 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))) + val cwfAuthorization = sp.getBoolean(app.aaps.core.utils.R.string.key_wear_custom_watchface_autorization, false) + val cwfName = sp.getString(app.aaps.core.utils.R.string.key_wear_cwf_watchface_name, "") + val authorVersion = sp.getString(app.aaps.core.utils.R.string.key_wear_cwf_author_version, "") + val fileName = sp.getString(app.aaps.core.utils.R.string.key_wear_cwf_filename, "") + var toUpdate = false + CwfData("", cwf.metadata, mutableMapOf()).also { + if (cwfAuthorization != cwf.metadata[CwfMetadataKey.CWF_AUTHORIZATION]?.toBooleanStrictOrNull()) { + it.metadata[CwfMetadataKey.CWF_AUTHORIZATION] = cwfAuthorization.toString() + toUpdate = true } + if (cwfName == cwf.metadata[CwfMetadataKey.CWF_NAME] && authorVersion == cwf.metadata[CwfMetadataKey.CWF_AUTHOR_VERSION] && fileName != cwf.metadata[CwfMetadataKey.CWF_FILENAME]) { + it.metadata[CwfMetadataKey.CWF_FILENAME] = fileName + toUpdate = true + } + + if (toUpdate) + 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 09355413aa..7c69e06b5b 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 @@ -1268,27 +1268,19 @@ 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()) + aapsLogger.debug(LTag.WEAR, "Custom Watchface received from ${command.sourceNodeId}") + val cwfData = customWatchface.customWatchfaceData + rxBus.send(EventWearUpdateGui(cwfData, command.exportFile)) + val watchfaceName = sp.getString(app.aaps.core.utils.R.string.key_wear_cwf_watchface_name, "") + val authorVersion = sp.getString(app.aaps.core.utils.R.string.key_wear_cwf_author_version, "") + if (cwfData.metadata[CwfMetadataKey.CWF_NAME] != watchfaceName || cwfData.metadata[CwfMetadataKey.CWF_AUTHOR_VERSION] != authorVersion) { + sp.putString(app.aaps.core.utils.R.string.key_wear_cwf_watchface_name, cwfData.metadata[CwfMetadataKey.CWF_NAME] ?:"") + sp.putString(app.aaps.core.utils.R.string.key_wear_cwf_author_version, cwfData.metadata[CwfMetadataKey.CWF_AUTHOR_VERSION] ?:"") + sp.putString(app.aaps.core.utils.R.string.key_wear_cwf_filename, cwfData.metadata[CwfMetadataKey.CWF_FILENAME] ?:"") } - rxBus.send(EventWearUpdateGui(customWatchface.customWatchfaceData, command.exportFile)) + if (command.exportFile) - importExportPrefs.exportCustomWatchface(customWatchface.customWatchfaceData, command.withDate) + importExportPrefs.exportCustomWatchface(cwfData, 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 ff7254effa..da33906a80 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 @@ -214,7 +214,6 @@ 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/DataLayerListenerServiceWear.kt b/wear/src/main/kotlin/app/aaps/wear/comm/DataLayerListenerServiceWear.kt index 348a705a06..c701b69391 100644 --- a/wear/src/main/kotlin/app/aaps/wear/comm/DataLayerListenerServiceWear.kt +++ b/wear/src/main/kotlin/app/aaps/wear/comm/DataLayerListenerServiceWear.kt @@ -129,11 +129,9 @@ class DataLayerListenerServiceWear : WearableListenerService() { rxDataPath -> { aapsLogger.debug(LTag.WEAR, "onMessageReceived: ${messageEvent.data.size}") - ZipWatchfaceFormat.loadCustomWatchface(ZipWatchfaceFormat.byteArrayToZipInputStream(messageEvent.data), "NewWatchface", false)?.let { + ZipWatchfaceFormat.loadCustomWatchface(messageEvent.data, "", 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 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 d9a1630926..dcf074a80a 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 @@ -203,8 +203,8 @@ open class Persistence @Inject constructor( 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) + // if same name and author version, then resync metadata to watch to update filename and authorization + val newCwfData = CwfData(savedCwData.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") 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 c2f9b6df52..345812cb27 100644 --- a/wear/src/main/kotlin/app/aaps/wear/watchfaces/CustomWatchface.kt +++ b/wear/src/main/kotlin/app/aaps/wear/watchfaces/CustomWatchface.kt @@ -44,8 +44,7 @@ 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.sameMeta -import app.aaps.core.interfaces.rx.weardata.sameRes +import app.aaps.core.interfaces.rx.weardata.isEquals import app.aaps.wear.R import app.aaps.wear.databinding.ActivityCustomBinding import app.aaps.wear.watchfaces.utils.BaseWatchFace @@ -67,7 +66,6 @@ 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) { @@ -155,9 +153,8 @@ class CustomWatchface : BaseWatchFace() { updatePref(it.customWatchfaceData.metadata) try { json = JSONObject(it.customWatchfaceData.json) - if (!resDataMap.sameRes(it.customWatchfaceData.resDatas) || !metadata.sameMeta(it.customWatchfaceData.metadata) || jsonString != it.customWatchfaceData.json) { + if (!resDataMap.isEquals(it.customWatchfaceData.resDatas) || jsonString != it.customWatchfaceData.json) { resDataMap = it.customWatchfaceData.resDatas - metadata = it.customWatchfaceData.metadata jsonString = it.customWatchfaceData.json FontMap.init(this) ViewMap.init(this)