1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.flags
18 
19 import android.util.Log
20 import org.json.JSONException
21 import org.json.JSONObject
22 
23 private const val FIELD_VALUE = "value"
24 private const val FIELD_TYPE = "type"
25 private const val TYPE_BOOLEAN = "boolean"
26 private const val TYPE_STRING = "string"
27 private const val TYPE_INT = "int"
28 
29 private const val TAG = "FlagSerializer"
30 
31 abstract class FlagSerializer<T>(
32     private val type: String,
33     private val setter: (JSONObject, String, T) -> Unit,
34     private val getter: (JSONObject, String) -> T
35 ) {
toSettingsDatanull36     fun toSettingsData(value: T): String? {
37         return try {
38             JSONObject()
39                 .put(FIELD_TYPE, type)
40                 .also { setter(it, FIELD_VALUE, value) }
41                 .toString()
42         } catch (e: JSONException) {
43             Log.w(TAG, "write error", e)
44             null
45         }
46     }
47 
48     /**
49      * @throws InvalidFlagStorageException
50      */
fromSettingsDatanull51     fun fromSettingsData(data: String?): T? {
52         if (data == null || data.isEmpty()) {
53             return null
54         }
55         try {
56             val json = JSONObject(data)
57             return if (json.getString(FIELD_TYPE) == type) {
58                 getter(json, FIELD_VALUE)
59             } else {
60                 null
61             }
62         } catch (e: JSONException) {
63             Log.w(TAG, "read error", e)
64             throw InvalidFlagStorageException()
65         }
66     }
67 }
68 
69 object BooleanFlagSerializer : FlagSerializer<Boolean>(
70     TYPE_BOOLEAN,
71     JSONObject::put,
72     JSONObject::getBoolean
73 )
74 
75 object StringFlagSerializer : FlagSerializer<String>(
76     TYPE_STRING,
77     JSONObject::put,
78     JSONObject::getString
79 )
80 
81 object IntFlagSerializer : FlagSerializer<Int>(
82     TYPE_INT,
83     JSONObject::put,
84     JSONObject::getInt
85 )
86 
87 class InvalidFlagStorageException : Exception("Data found but is invalid")
88