• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 package com.android.systemui.plugins.clocks
15 
16 import com.android.internal.annotations.Keep
17 import org.json.JSONArray
18 import org.json.JSONObject
19 
20 @Keep
21 /** Structure for keeping clock-specific settings */
22 data class ClockSettings(
23     val clockId: ClockId? = null,
24     val seedColor: Int? = null,
25     val axes: ClockAxisStyle = ClockAxisStyle(),
26 ) {
27     // Exclude metadata from equality checks
28     var metadata: JSONObject = JSONObject()
29 
30     companion object {
31         private val KEY_CLOCK_ID = "clockId"
32         private val KEY_SEED_COLOR = "seedColor"
33         private val KEY_METADATA = "metadata"
34         private val KEY_AXIS_LIST = "axes"
35 
toJsonnull36         fun toJson(setting: ClockSettings): JSONObject {
37             return JSONObject().apply {
38                 put(KEY_CLOCK_ID, setting.clockId)
39                 put(KEY_SEED_COLOR, setting.seedColor)
40                 put(KEY_METADATA, setting.metadata)
41                 put(KEY_AXIS_LIST, ClockAxisStyle.toJson(setting.axes))
42             }
43         }
44 
fromJsonnull45         fun fromJson(json: JSONObject): ClockSettings {
46             val clockId = if (!json.isNull(KEY_CLOCK_ID)) json.getString(KEY_CLOCK_ID) else null
47             val seedColor = if (!json.isNull(KEY_SEED_COLOR)) json.getInt(KEY_SEED_COLOR) else null
48             val axisList = json.optJSONArray(KEY_AXIS_LIST)?.let(ClockAxisStyle::fromJson)
49             return ClockSettings(clockId, seedColor, axisList ?: ClockAxisStyle()).apply {
50                 metadata = json.optJSONObject(KEY_METADATA) ?: JSONObject()
51             }
52         }
53     }
54 }
55 
56 @Keep
57 class ClockAxisStyle {
58     private val settings: MutableMap<String, Float>
59 
60     // Iterable would be implemented on ClockAxisStyle directly,
61     // but that doesn't appear to work with plugins/dynamic libs.
62     val items: Iterable<Map.Entry<String, Float>>
63         get() = settings.asIterable()
64 
65     val isEmpty: Boolean
66         get() = settings.isEmpty()
67 
<lambda>null68     constructor(initialize: ClockAxisStyle.() -> Unit = {}) {
69         settings = mutableMapOf()
70         this.initialize()
71     }
72 
73     constructor(style: ClockAxisStyle) {
74         settings = style.settings.toMutableMap()
75     }
76 
77     constructor(items: Map<String, Float>) {
78         settings = items.toMutableMap()
79     }
80 
81     constructor(key: String, value: Float) {
82         settings = mutableMapOf(key to value)
83     }
84 
85     constructor(items: List<ClockFontAxis>) {
<lambda>null86         settings = items.associate { it.key to it.currentValue }.toMutableMap()
87     }
88 
copynull89     fun copy(initialize: ClockAxisStyle.() -> Unit): ClockAxisStyle {
90         return ClockAxisStyle(this).apply { initialize() }
91     }
92 
getnull93     operator fun get(key: String): Float? = settings[key]
94 
95     operator fun set(key: String, value: Float) = put(key, value)
96 
97     fun put(key: String, value: Float) {
98         settings.put(key, value)
99     }
100 
toFVarnull101     fun toFVar(): String {
102         val sb = StringBuilder()
103         for (axis in settings) {
104             if (sb.length > 0) sb.append(", ")
105             sb.append("'${axis.key}' ${axis.value.toInt()}")
106         }
107         return sb.toString()
108     }
109 
copyWithnull110     fun copyWith(replacements: ClockAxisStyle): ClockAxisStyle {
111         val result = ClockAxisStyle(this)
112         for ((key, value) in replacements.settings) {
113             result[key] = value
114         }
115         return result
116     }
117 
equalsnull118     override fun equals(other: Any?): Boolean {
119         if (this === other) return true
120         if (other !is ClockAxisStyle) return false
121         return settings == other.settings
122     }
123 
124     companion object {
125         private val KEY_AXIS_KEY = "key"
126         private val KEY_AXIS_VALUE = "value"
127 
fromJsonnull128         fun fromJson(jsonArray: JSONArray): ClockAxisStyle {
129             val result = ClockAxisStyle()
130             for (i in 0..jsonArray.length() - 1) {
131                 val obj = jsonArray.getJSONObject(i)
132                 if (obj == null) continue
133 
134                 result.put(
135                     key = obj.getString(KEY_AXIS_KEY),
136                     value = obj.getDouble(KEY_AXIS_VALUE).toFloat(),
137                 )
138             }
139             return result
140         }
141 
toJsonnull142         fun toJson(style: ClockAxisStyle): JSONArray {
143             return JSONArray().apply {
144                 for ((key, value) in style.settings) {
145                     put(
146                         JSONObject().apply {
147                             put(KEY_AXIS_KEY, key)
148                             put(KEY_AXIS_VALUE, value)
149                         }
150                     )
151                 }
152             }
153         }
154     }
155 }
156