Merge pull request #2911 from Philoul/wear/cwf_ComRefactoring
CWF Communication refactor between phone and Wear
This commit is contained in:
commit
06737c9fe9
13 changed files with 134 additions and 42 deletions
|
@ -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
|
||||||
}
|
}
|
|
@ -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()
|
|
@ -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
|
||||||
|
@ -135,9 +136,15 @@ 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.isEquals(dataMap: CwfResDataMap) = (this.size == dataMap.size) && this.all { (key, resData) -> dataMap[key]?.value.contentEquals(resData.value) == true }
|
||||||
|
|
||||||
@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) {
|
||||||
|
|
||||||
|
@ -287,11 +294,11 @@ 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(byteArray: ByteArray, 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 zipInputStream = byteArrayToZipInputStream(byteArray)
|
||||||
try {
|
try {
|
||||||
var zipEntry: ZipEntry? = zipInputStream.nextEntry
|
var zipEntry: ZipEntry? = zipInputStream.nextEntry
|
||||||
while (zipEntry != null) {
|
while (zipEntry != null) {
|
||||||
|
@ -325,7 +332,7 @@ class ZipWatchfaceFormat {
|
||||||
|
|
||||||
// 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), byteArray)
|
||||||
else
|
else
|
||||||
null
|
null
|
||||||
|
|
||||||
|
@ -369,5 +376,10 @@ class ZipWatchfaceFormat {
|
||||||
}
|
}
|
||||||
return metadata
|
return metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun byteArrayToZipInputStream(byteArray: ByteArray): ZipInputStream {
|
||||||
|
val byteArrayInputStream = ByteArrayInputStream(byteArray)
|
||||||
|
return ZipInputStream(byteArrayInputStream)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,9 @@
|
||||||
<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_cwf_watchface_name" translatable="false">wear_cwf_watchface_name</string>
|
||||||
|
<string name="key_wear_cwf_author_version" translatable="false">wear_cwf_author_version</string>
|
||||||
|
<string name="key_wear_cwf_filename" translatable="false">wear_cwf_filename</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>
|
||||||
|
|
|
@ -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(file.readBytes(), file.name, customWatchfaceAuthorization)?.also { customWatchface ->
|
||||||
customWatchfaceFiles.add(customWatchface)
|
customWatchfaceFiles.add(customWatchface)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,12 +111,11 @@ class PrefFileListProviderImpl @Inject constructor(
|
||||||
val assetFiles = context.assets.list("") ?: arrayOf()
|
val assetFiles = context.assets.list("") ?: arrayOf()
|
||||||
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 assetByteArray = context.assets.open(assetFileName).readBytes()
|
||||||
ZipWatchfaceFormat.loadCustomWatchface(ZipInputStream(assetInputStream), assetFileName, customAwtchfaceAuthorization)?.also { customWatchface ->
|
ZipWatchfaceFormat.loadCustomWatchface(assetByteArray, 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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|
|
@ -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)
|
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()
|
val i = Intent()
|
||||||
setResult(FragmentActivity.RESULT_OK, i)
|
setResult(FragmentActivity.RESULT_OK, i)
|
||||||
rxBus.send(EventMobileDataToWear(customWF))
|
rxBus.send(EventMobileDataToWear(customWatchfaceFile.zipByteArray))
|
||||||
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)
|
||||||
|
|
|
@ -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.EventAutosensCalculationFinished
|
||||||
import app.aaps.core.interfaces.rx.events.EventDismissBolusProgressIfRunning
|
import app.aaps.core.interfaces.rx.events.EventDismissBolusProgressIfRunning
|
||||||
import app.aaps.core.interfaces.rx.events.EventLoopUpdateGui
|
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.EventMobileToWear
|
||||||
import app.aaps.core.interfaces.rx.events.EventOverviewBolusProgress
|
import app.aaps.core.interfaces.rx.events.EventOverviewBolusProgress
|
||||||
import app.aaps.core.interfaces.rx.events.EventPreferenceChange
|
import app.aaps.core.interfaces.rx.events.EventPreferenceChange
|
||||||
|
@ -112,12 +111,23 @@ class WearPlugin @Inject constructor(
|
||||||
|
|
||||||
fun checkCustomWatchfacePreferences() {
|
fun checkCustomWatchfacePreferences() {
|
||||||
savedCustomWatchface?.let { cwf ->
|
savedCustomWatchface?.let { cwf ->
|
||||||
val cwf_authorization = sp.getBoolean(app.aaps.core.utils.R.string.key_wear_custom_watchface_autorization, false)
|
val cwfAuthorization = sp.getBoolean(app.aaps.core.utils.R.string.key_wear_custom_watchface_autorization, false)
|
||||||
if (cwf_authorization != cwf.metadata[CwfMetadataKey.CWF_AUTHORIZATION]?.toBooleanStrictOrNull()) {
|
val cwfName = sp.getString(app.aaps.core.utils.R.string.key_wear_cwf_watchface_name, "")
|
||||||
// resend new customWatchface to Watch with updated authorization for preferences update
|
val authorVersion = sp.getString(app.aaps.core.utils.R.string.key_wear_cwf_author_version, "")
|
||||||
val newCwf = cwf.copy()
|
val fileName = sp.getString(app.aaps.core.utils.R.string.key_wear_cwf_filename, "")
|
||||||
newCwf.metadata[CwfMetadataKey.CWF_AUTHORIZATION] = sp.getBoolean(app.aaps.core.utils.R.string.key_wear_custom_watchface_autorization, false).toString()
|
var toUpdate = false
|
||||||
rxBus.send(EventMobileDataToWear(EventData.ActionSetCustomWatchface(newCwf)))
|
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)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
@ -1266,10 +1268,19 @@ 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}")
|
||||||
rxBus.send(EventWearUpdateGui(customWatchface.customWatchfaceData, command.exportFile))
|
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] ?:"")
|
||||||
|
}
|
||||||
|
|
||||||
if (command.exportFile)
|
if (command.exportFile)
|
||||||
importExportPrefs.exportCustomWatchface(customWatchface.customWatchfaceData, command.withDate)
|
importExportPrefs.exportCustomWatchface(cwfData, command.withDate)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,11 @@ 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(messageEvent.data, "", false)?.let {
|
||||||
rxBus.send(command.also { it.sourceNodeId = messageEvent.sourceNodeId })
|
val command = EventData.ActionSetCustomWatchface(it.cwfData)
|
||||||
|
rxBus.send(command.also { it.sourceNodeId = messageEvent.sourceNodeId })
|
||||||
|
}
|
||||||
// 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")
|
||||||
|
|
|
@ -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 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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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")
|
||||||
|
|
Loading…
Reference in a new issue