Draft Refactor Communication

This commit is contained in:
Philoul 2023-10-12 00:36:54 +02:00
parent 44b8b30637
commit cde1be75ba
14 changed files with 150 additions and 41 deletions

View file

@ -1,6 +1,7 @@
package app.aaps.core.interfaces.maintenance package app.aaps.core.interfaces.maintenance
import app.aaps.core.interfaces.rx.weardata.CwfData import app.aaps.core.interfaces.rx.weardata.CwfData
import app.aaps.core.interfaces.rx.weardata.CwfFile
import java.io.File import java.io.File
interface PrefFileListProvider { interface PrefFileListProvider {
@ -13,7 +14,7 @@ interface PrefFileListProvider {
fun newExportCsvFile(): File fun newExportCsvFile(): File
fun newCwfFile(filename: String, withDate: Boolean = true): File fun newCwfFile(filename: String, withDate: Boolean = true): File
fun listPreferenceFiles(loadMetadata: Boolean = false): MutableList<PrefsFile> fun listPreferenceFiles(loadMetadata: Boolean = false): MutableList<PrefsFile>
fun listCustomWatchfaceFiles(): MutableList<CwfData> fun listCustomWatchfaceFiles(): MutableList<CwfFile>
fun checkMetadata(metadata: Map<PrefsMetadataKey, PrefMetadata>): Map<PrefsMetadataKey, PrefMetadata> fun checkMetadata(metadata: Map<PrefsMetadataKey, PrefMetadata>): Map<PrefsMetadataKey, PrefMetadata>
fun formatExportedAgo(utcTime: String): String fun formatExportedAgo(utcTime: String): String
} }

View file

@ -2,4 +2,4 @@ package app.aaps.core.interfaces.rx.events
import app.aaps.core.interfaces.rx.weardata.EventData import app.aaps.core.interfaces.rx.weardata.EventData
class EventMobileDataToWear(val payload: EventData.ActionSetCustomWatchface) : Event() class EventMobileDataToWear(val payload: ByteArray) : Event()

View file

@ -12,6 +12,7 @@ import com.caverock.androidsvg.SVG
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import org.json.JSONObject import org.json.JSONObject
import java.io.BufferedOutputStream import java.io.BufferedOutputStream
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
@ -134,10 +135,18 @@ data class ResData(val value: ByteArray, val format: ResFormat) {
typealias CwfResDataMap = MutableMap<String, ResData> typealias CwfResDataMap = MutableMap<String, ResData>
typealias CwfMetadataMap = MutableMap<CwfMetadataKey, String> typealias CwfMetadataMap = MutableMap<CwfMetadataKey, String>
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 @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) { 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_EXTENTION = ".zip"
const val CWF_JSON_FILE = "CustomWatchface.json" 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 json = JSONObject()
var metadata: CwfMetadataMap = mutableMapOf() var metadata: CwfMetadataMap = mutableMapOf()
val resDatas: CwfResDataMap = mutableMapOf() val resDatas: CwfResDataMap = mutableMapOf()
val testZip = byteArrayToZipInputStream(zipInputStreamToByteArray(zipInputStream))
try { try {
var zipEntry: ZipEntry? = zipInputStream.nextEntry var zipEntry: ZipEntry? = testZip.nextEntry
while (zipEntry != null) { while (zipEntry != null) {
val entryName = zipEntry.name val entryName = zipEntry.name
val buffer = ByteArray(2048) val buffer = ByteArray(2048)
val byteArrayOutputStream = ByteArrayOutputStream() val byteArrayOutputStream = ByteArrayOutputStream()
var count = zipInputStream.read(buffer) var count = testZip.read(buffer)
while (count != -1) { while (count != -1) {
byteArrayOutputStream.write(buffer, 0, count) byteArrayOutputStream.write(buffer, 0, count)
count = zipInputStream.read(buffer) count = testZip.read(buffer)
} }
zipInputStream.closeEntry() testZip.closeEntry()
if (entryName == CWF_JSON_FILE) { if (entryName == CWF_JSON_FILE) {
val jsonString = byteArrayOutputStream.toByteArray().toString(Charsets.UTF_8) val jsonString = byteArrayOutputStream.toByteArray().toString(Charsets.UTF_8)
@ -319,12 +328,12 @@ class ZipWatchfaceFormat {
} else if (drawableFormat != ResFormat.UNKNOWN) } else if (drawableFormat != ResFormat.UNKNOWN)
resDatas[entryName.substringBeforeLast(".")] = ResData(byteArrayOutputStream.toByteArray(), drawableFormat) 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 // 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)) 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 else
null null
@ -368,5 +377,20 @@ class ZipWatchfaceFormat {
} }
return metadata 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)
}
} }
} }

View file

@ -292,10 +292,9 @@ sealed class EventData : Event() {
} }
@Serializable @Serializable
data class ActionSetCustomWatchface( data class ActionSetCustomWatchface(val customWatchfaceData: CwfData) : EventData()
val customWatchfaceData: CwfData @Serializable
) : EventData() data class ActionUpdateCustomWatchface(val customWatchfaceData: CwfData) : EventData()
@Serializable @Serializable
data class ActionrequestCustomWatchface(val exportFile: Boolean) : EventData() data class ActionrequestCustomWatchface(val exportFile: Boolean) : EventData()

View file

@ -116,6 +116,7 @@
<string name="key_wearwizard_cob" translatable="false">wearwizard_cob</string> <string name="key_wearwizard_cob" translatable="false">wearwizard_cob</string>
<string name="key_wearwizard_iob" translatable="false">wearwizard_iob</string> <string name="key_wearwizard_iob" translatable="false">wearwizard_iob</string>
<string name="key_wear_custom_watchface_autorization" translatable="false">wear_custom_watchface_autorization</string> <string name="key_wear_custom_watchface_autorization" translatable="false">wear_custom_watchface_autorization</string>
<string name="key_wear_custom_watchface_save_cwfData" translatable="false">wear_custom_watchface_save_cwfdata</string>
<string name="key_objectives_bg_is_available_in_ns" translatable="false">ObjectivesbgIsAvailableInNS</string> <string name="key_objectives_bg_is_available_in_ns" translatable="false">ObjectivesbgIsAvailableInNS</string>
<string name="key_objectives_pump_status_is_available_in_ns" translatable="false">ObjectivespumpStatusIsAvailableInNS</string> <string name="key_objectives_pump_status_is_available_in_ns" translatable="false">ObjectivespumpStatusIsAvailableInNS</string>
<string name="key_statuslights_cage_warning" translatable="false">statuslights_cage_warning</string> <string name="key_statuslights_cage_warning" translatable="false">statuslights_cage_warning</string>

View file

@ -12,6 +12,7 @@ import app.aaps.core.interfaces.maintenance.PrefsMetadataKey
import app.aaps.core.interfaces.resources.ResourceHelper import app.aaps.core.interfaces.resources.ResourceHelper
import app.aaps.core.interfaces.rx.bus.RxBus import app.aaps.core.interfaces.rx.bus.RxBus
import app.aaps.core.interfaces.rx.weardata.CwfData 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.EventData
import app.aaps.core.interfaces.rx.weardata.ZipWatchfaceFormat import app.aaps.core.interfaces.rx.weardata.ZipWatchfaceFormat
import app.aaps.core.interfaces.sharedPreferences.SP import app.aaps.core.interfaces.sharedPreferences.SP
@ -97,11 +98,11 @@ class PrefFileListProviderImpl @Inject constructor(
return prefFiles return prefFiles
} }
override fun listCustomWatchfaceFiles(): MutableList<CwfData> { override fun listCustomWatchfaceFiles(): MutableList<CwfFile> {
val customWatchfaceFiles = mutableListOf<CwfData>() val customWatchfaceFiles = mutableListOf<CwfFile>()
val customAwtchfaceAuthorization = sp.getBoolean(app.aaps.core.utils.R.string.key_wear_custom_watchface_autorization, false) 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 -> 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) customWatchfaceFiles.add(customWatchface)
} }
} }
@ -111,9 +112,9 @@ class PrefFileListProviderImpl @Inject constructor(
for (assetFileName in assetFiles) { for (assetFileName in assetFiles) {
if (assetFileName.endsWith(ZipWatchfaceFormat.CWF_EXTENTION)) { if (assetFileName.endsWith(ZipWatchfaceFormat.CWF_EXTENTION)) {
val assetInputStream = context.assets.open(assetFileName) 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) 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() assetInputStream.close()
} }

View file

@ -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.events.EventMobileDataToWear
import app.aaps.core.interfaces.rx.weardata.CUSTOM_VERSION import app.aaps.core.interfaces.rx.weardata.CUSTOM_VERSION
import app.aaps.core.interfaces.rx.weardata.CwfData 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
import app.aaps.core.interfaces.rx.weardata.CwfMetadataKey.CWF_AUTHOR_VERSION import app.aaps.core.interfaces.rx.weardata.CwfMetadataKey.CWF_AUTHOR_VERSION
import app.aaps.core.interfaces.rx.weardata.CwfMetadataKey.CWF_CREATED_AT 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_NAME
import app.aaps.core.interfaces.rx.weardata.CwfMetadataKey.CWF_VERSION 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.CwfMetadataMap
import app.aaps.core.interfaces.rx.weardata.CwfResDataMap
import app.aaps.core.interfaces.rx.weardata.EventData import app.aaps.core.interfaces.rx.weardata.EventData
import app.aaps.core.interfaces.rx.weardata.ResFileMap import app.aaps.core.interfaces.rx.weardata.ResFileMap
import app.aaps.core.interfaces.rx.weardata.ZipWatchfaceFormat import app.aaps.core.interfaces.rx.weardata.ZipWatchfaceFormat
@ -56,10 +58,10 @@ class CustomWatchfaceImportListActivity : TranslatedDaggerAppCompatActivity() {
supportActionBar?.setDisplayShowTitleEnabled(true) supportActionBar?.setDisplayShowTitleEnabled(true)
binding.recyclerview.layoutManager = LinearLayoutManager(this) 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<CwfData>) : RecyclerView.Adapter<RecyclerViewAdapter.CwfFileViewHolder>() { inner class RecyclerViewAdapter internal constructor(private var customWatchfaceFileList: List<CwfFile>) : RecyclerView.Adapter<RecyclerViewAdapter.CwfFileViewHolder>() {
inner class CwfFileViewHolder(val customWatchfaceImportListItemBinding: CustomWatchfaceImportListItemBinding) : RecyclerView.ViewHolder(customWatchfaceImportListItemBinding.root) { inner class CwfFileViewHolder(val customWatchfaceImportListItemBinding: CustomWatchfaceImportListItemBinding) : RecyclerView.ViewHolder(customWatchfaceImportListItemBinding.root) {
@ -67,11 +69,14 @@ class CustomWatchfaceImportListActivity : TranslatedDaggerAppCompatActivity() {
with(customWatchfaceImportListItemBinding) { with(customWatchfaceImportListItemBinding) {
root.isClickable = true root.isClickable = true
customWatchfaceImportListItemBinding.root.setOnClickListener { customWatchfaceImportListItemBinding.root.setOnClickListener {
val customWatchfaceFile = filelistName.tag as CwfData val customWatchfaceFile = filelistName.tag as CwfFile
val customWF = EventData.ActionSetCustomWatchface(customWatchfaceFile) 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() val i = Intent()
setResult(FragmentActivity.RESULT_OK, i) setResult(FragmentActivity.RESULT_OK, i)
rxBus.send(EventMobileDataToWear(customWF)) rxBus.send(EventMobileDataToWear(customWatchfaceFile.zipByteArray))
aapsLogger.debug("XXXXX: ${customWatchfaceFile.zipByteArray.size}")
finish() finish()
} }
} }
@ -89,8 +94,8 @@ class CustomWatchfaceImportListActivity : TranslatedDaggerAppCompatActivity() {
override fun onBindViewHolder(holder: CwfFileViewHolder, position: Int) { override fun onBindViewHolder(holder: CwfFileViewHolder, position: Int) {
val customWatchfaceFile = customWatchfaceFileList[position] val customWatchfaceFile = customWatchfaceFileList[position]
val metadata = customWatchfaceFile.metadata val metadata = customWatchfaceFile.cwfData.metadata
val drawable = customWatchfaceFile.resDatas[ResFileMap.CUSTOM_WATCHFACE.fileName]?.toDrawable(resources) val drawable = customWatchfaceFile.cwfData.resDatas[ResFileMap.CUSTOM_WATCHFACE.fileName]?.toDrawable(resources)
with(holder.customWatchfaceImportListItemBinding) { with(holder.customWatchfaceImportListItemBinding) {
val fileName = metadata[CWF_FILENAME]?.let { "$it${ZipWatchfaceFormat.CWF_EXTENTION}" } ?: "" 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) filelistName.text = rh.gs(app.aaps.core.interfaces.R.string.metadata_wear_import_filename, fileName)

View file

@ -114,10 +114,12 @@ class WearPlugin @Inject constructor(
savedCustomWatchface?.let { cwf -> savedCustomWatchface?.let { cwf ->
val cwf_authorization = sp.getBoolean(app.aaps.core.utils.R.string.key_wear_custom_watchface_autorization, false) 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()) { if (cwf_authorization != cwf.metadata[CwfMetadataKey.CWF_AUTHORIZATION]?.toBooleanStrictOrNull()) {
// resend new customWatchface to Watch with updated authorization for preferences update // update new customWatchface to Watch with updated authorization for preferences update
val newCwf = cwf.copy() CwfData(cwf.json, cwf.metadata, mutableMapOf()).also {
newCwf.metadata[CwfMetadataKey.CWF_AUTHORIZATION] = sp.getBoolean(app.aaps.core.utils.R.string.key_wear_custom_watchface_autorization, false).toString() it.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))) sp.putString(app.aaps.core.utils.R.string.key_wear_custom_watchface_save_cwfData, EventData.ActionSetCustomWatchface(it).serialize())
rxBus.send(EventMobileToWear(EventData.ActionUpdateCustomWatchface(it)))
}
} }
} }
} }

View file

@ -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.bus.RxBus
import app.aaps.core.interfaces.rx.events.EventMobileToWear import app.aaps.core.interfaces.rx.events.EventMobileToWear
import app.aaps.core.interfaces.rx.events.EventWearUpdateGui 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.rx.weardata.EventData
import app.aaps.core.interfaces.sharedPreferences.SP import app.aaps.core.interfaces.sharedPreferences.SP
import app.aaps.core.interfaces.ui.UiInteraction import app.aaps.core.interfaces.ui.UiInteraction
@ -70,6 +71,7 @@ import app.aaps.plugins.main.R
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign import io.reactivex.rxjava3.kotlin.plusAssign
import org.json.JSONObject
import java.text.DateFormat import java.text.DateFormat
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
@ -1267,6 +1269,23 @@ class DataHandlerMobile @Inject constructor(
private fun handleGetCustomWatchface(command: EventData.ActionGetCustomWatchface) { private fun handleGetCustomWatchface(command: EventData.ActionGetCustomWatchface) {
val customWatchface = command.customWatchface val customWatchface = command.customWatchface
aapsLogger.debug(LTag.WEAR, "Custom Watchface received from ${command.sourceNodeId}: ${customWatchface.customWatchfaceData.json}") 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)) rxBus.send(EventWearUpdateGui(customWatchface.customWatchfaceData, command.exportFile))
if (command.exportFile) if (command.exportFile)
importExportPrefs.exportCustomWatchface(customWatchface.customWatchfaceData, command.withDate) importExportPrefs.exportCustomWatchface(customWatchface.customWatchfaceData, command.withDate)

View file

@ -93,7 +93,7 @@ class DataLayerListenerServiceMobile : WearableListenerService() {
disposable += rxBus disposable += rxBus
.toObservable(EventMobileDataToWear::class.java) .toObservable(EventMobileDataToWear::class.java)
.observeOn(aapsSchedulers.io) .observeOn(aapsSchedulers.io)
.subscribe { sendMessage(rxDataPath, it.payload.serializeByte()) } .subscribe { sendMessage(rxDataPath, it.payload) }
} }
override fun onCapabilityChanged(p0: CapabilityInfo) { override fun onCapabilityChanged(p0: CapabilityInfo) {
@ -214,6 +214,7 @@ class DataLayerListenerServiceMobile : WearableListenerService() {
private fun sendMessage(path: String, data: ByteArray) { private fun sendMessage(path: String, data: ByteArray) {
aapsLogger.debug(LTag.WEAR, "sendMessage: $path") aapsLogger.debug(LTag.WEAR, "sendMessage: $path")
aapsLogger.debug("XXXXX: $path, ${data.size}")
transcriptionNodeId?.also { nodeId -> transcriptionNodeId?.also { nodeId ->
messageClient messageClient
.sendMessage(nodeId, path, data).apply { .sendMessage(nodeId, path, data).apply {

View file

@ -186,7 +186,17 @@ class DataHandlerWear @Inject constructor(
.subscribe { .subscribe {
aapsLogger.debug(LTag.WEAR, "Custom Watchface received from ${it.sourceNodeId}") aapsLogger.debug(LTag.WEAR, "Custom Watchface received from ${it.sourceNodeId}")
persistence.store(it) 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))) rxBus.send(EventWearDataToMobile(EventData.ActionGetCustomWatchface(it, false)))
} }
} }
@ -205,7 +215,7 @@ class DataHandlerWear @Inject constructor(
.observeOn(aapsSchedulers.io) .observeOn(aapsSchedulers.io)
.subscribe { eventData -> .subscribe { eventData ->
aapsLogger.debug(LTag.WEAR, "Custom Watchface requested from ${eventData.sourceNodeId} export ${eventData.exportFile}") 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))) rxBus.send(EventWearDataToMobile(EventData.ActionGetCustomWatchface(it, eventData.exportFile)))
} }
} }

View file

@ -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.EventWearDataToMobile
import app.aaps.core.interfaces.rx.events.EventWearToMobile import app.aaps.core.interfaces.rx.events.EventWearToMobile
import app.aaps.core.interfaces.rx.weardata.EventData 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.core.interfaces.sharedPreferences.SP
import app.aaps.wear.interaction.utils.Persistence import app.aaps.wear.interaction.utils.Persistence
import app.aaps.wear.interaction.utils.WearUtil import app.aaps.wear.interaction.utils.WearUtil
@ -127,9 +128,13 @@ class DataLayerListenerServiceWear : WearableListenerService() {
} }
rxDataPath -> { rxDataPath -> {
aapsLogger.debug(LTag.WEAR, "onMessageReceived: ${messageEvent.data}") aapsLogger.debug(LTag.WEAR, "onMessageReceived: ${messageEvent.data.size}")
val command = EventData.deserializeByte(messageEvent.data) ZipWatchfaceFormat.loadCustomWatchface(ZipWatchfaceFormat.byteArrayToZipInputStream(messageEvent.data), "NewWatchface", false)?.let {
val command = EventData.ActionSetCustomWatchface(it.cwfData)
rxBus.send(command.also { it.sourceNodeId = messageEvent.sourceNodeId }) rxBus.send(command.also { it.sourceNodeId = messageEvent.sourceNodeId })
aapsLogger.debug("XXXXX: ${it.cwfData.json}")
}
// Use this sender // Use this sender
transcriptionNodeId = messageEvent.sourceNodeId transcriptionNodeId = messageEvent.sourceNodeId
aapsLogger.debug(LTag.WEAR, "Updated node: $transcriptionNodeId") aapsLogger.debug(LTag.WEAR, "Updated node: $transcriptionNodeId")

View file

@ -3,6 +3,9 @@ package app.aaps.wear.interaction.utils
import app.aaps.annotations.OpenForTesting import app.aaps.annotations.OpenForTesting
import app.aaps.core.interfaces.logging.AAPSLogger import app.aaps.core.interfaces.logging.AAPSLogger
import app.aaps.core.interfaces.logging.LTag 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
import app.aaps.core.interfaces.rx.weardata.EventData.Companion.deserialize import app.aaps.core.interfaces.rx.weardata.EventData.Companion.deserialize
import app.aaps.core.interfaces.rx.weardata.EventData.SingleBg import app.aaps.core.interfaces.rx.weardata.EventData.SingleBg
@ -149,6 +152,26 @@ open class Persistence @Inject constructor(
return null 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) { fun store(singleBg: SingleBg) {
putString(BG_DATA_PERSISTENCE_KEY, singleBg.serialize()) putString(BG_DATA_PERSISTENCE_KEY, singleBg.serialize())
aapsLogger.debug(LTag.WEAR, "Stored BG data: $singleBg") 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") 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() { fun setDefaultWatchface() {
readCustomWatchface(true)?.let { store(it) } readCustomWatchface(true)?.let { store(it) }
aapsLogger.debug(LTag.WEAR, "Custom Watchface reset to default") aapsLogger.debug(LTag.WEAR, "Custom Watchface reset to default")

View file

@ -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.ResFormat
import app.aaps.core.interfaces.rx.weardata.ViewKeys import app.aaps.core.interfaces.rx.weardata.ViewKeys
import app.aaps.core.interfaces.rx.weardata.ZipWatchfaceFormat 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.R
import app.aaps.wear.databinding.ActivityCustomBinding import app.aaps.wear.databinding.ActivityCustomBinding
import app.aaps.wear.watchfaces.utils.BaseWatchFace import app.aaps.wear.watchfaces.utils.BaseWatchFace
@ -66,6 +67,7 @@ class CustomWatchface : BaseWatchFace() {
private var lowBatColor = Color.RED private var lowBatColor = Color.RED
private var resDataMap: CwfResDataMap = mutableMapOf() private var resDataMap: CwfResDataMap = mutableMapOf()
private var json = JSONObject() private var json = JSONObject()
private var metadata: CwfMetadataMap = mutableMapOf()
private var jsonString = "" private var jsonString = ""
private val bgColor: Int private val bgColor: Int
get() = when (singleBg.sgvLevel) { get() = when (singleBg.sgvLevel) {
@ -153,8 +155,9 @@ class CustomWatchface : BaseWatchFace() {
updatePref(it.customWatchfaceData.metadata) updatePref(it.customWatchfaceData.metadata)
try { try {
json = JSONObject(it.customWatchfaceData.json) 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 resDataMap = it.customWatchfaceData.resDatas
metadata = it.customWatchfaceData.metadata
jsonString = it.customWatchfaceData.json jsonString = it.customWatchfaceData.json
FontMap.init(this) FontMap.init(this)
ViewMap.init(this) ViewMap.init(this)