1 /*
<lambda>null2  * Copyright (C) 2022 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.util
18 
19 import android.content.SharedPreferences
20 
21 /**
22  * Fake [SharedPreferences] to use within tests
23  *
24  * This will act in the same way as a real one for a particular file, but will store all the
25  * data in memory in the instance.
26  *
27  * [SharedPreferences.Editor.apply] and [SharedPreferences.Editor.commit] both act in the same way,
28  * synchronously modifying the stored data. Listeners are dispatched in the same thread, also
29  * synchronously.
30  */
31 class FakeSharedPreferences : SharedPreferences {
32     private val data = mutableMapOf<String, Any>()
33     private val listeners = mutableSetOf<SharedPreferences.OnSharedPreferenceChangeListener>()
34 
35     override fun getAll(): Map<String, *> {
36         return data
37     }
38 
39     override fun getString(key: String, defValue: String?): String? {
40         return data.getOrDefault(key, defValue) as? String?
41     }
42 
43     override fun getStringSet(key: String, defValues: MutableSet<String>?): MutableSet<String>? {
44         return (data.getOrDefault(key, defValues) as? Set<String>?)?.toMutableSet()
45     }
46 
47     override fun getInt(key: String, defValue: Int): Int {
48         return data.getOrDefault(key, defValue) as Int
49     }
50 
51     override fun getLong(key: String, defValue: Long): Long {
52         return data.getOrDefault(key, defValue) as Long
53     }
54 
55     override fun getFloat(key: String, defValue: Float): Float {
56         return data.getOrDefault(key, defValue) as Float
57     }
58 
59     override fun getBoolean(key: String, defValue: Boolean): Boolean {
60         return data.getOrDefault(key, defValue) as Boolean
61     }
62 
63     override fun contains(key: String): Boolean {
64         return key in data
65     }
66 
67     override fun edit(): SharedPreferences.Editor {
68         return Editor()
69     }
70 
71     override fun registerOnSharedPreferenceChangeListener(
72         listener: SharedPreferences.OnSharedPreferenceChangeListener
73     ) {
74         listeners.add(listener)
75     }
76 
77     override fun unregisterOnSharedPreferenceChangeListener(
78         listener: SharedPreferences.OnSharedPreferenceChangeListener
79     ) {
80         listeners.remove(listener)
81     }
82 
83     private inner class Editor : SharedPreferences.Editor {
84 
85         private var clear = false
86         private val changes = mutableMapOf<String, Any>()
87         private val removals = mutableSetOf<String>()
88 
89         override fun putString(key: String, value: String?): SharedPreferences.Editor {
90             if (value != null) {
91                 changes[key] = value
92             } else {
93                 removals.add(key)
94             }
95             return this
96         }
97 
98         override fun putStringSet(
99             key: String,
100             values: MutableSet<String>?
101         ): SharedPreferences.Editor {
102             if (values != null) {
103                 changes[key] = values
104             } else {
105                 removals.add(key)
106             }
107             return this
108         }
109 
110         override fun putInt(key: String, value: Int): SharedPreferences.Editor {
111             changes[key] = value
112             return this
113         }
114 
115         override fun putLong(key: String, value: Long): SharedPreferences.Editor {
116             changes[key] = value
117             return this
118         }
119 
120         override fun putFloat(key: String, value: Float): SharedPreferences.Editor {
121             changes[key] = value
122             return this
123         }
124 
125         override fun putBoolean(key: String, value: Boolean): SharedPreferences.Editor {
126             changes[key] = value
127             return this
128         }
129 
130         override fun remove(key: String): SharedPreferences.Editor {
131             removals.add(key)
132             return this
133         }
134 
135         override fun clear(): SharedPreferences.Editor {
136             clear = true
137             return this
138         }
139 
140         override fun commit(): Boolean {
141             if (clear) {
142                 data.clear()
143             }
144             removals.forEach { data.remove(it) }
145             data.putAll(changes)
146             val keys = removals + data.keys
147             if (clear || removals.isNotEmpty() || data.isNotEmpty()) {
148                 listeners.forEach { listener ->
149                     if (clear) {
150                         listener.onSharedPreferenceChanged(this@FakeSharedPreferences, null)
151                     }
152                     keys.forEach {
153                         listener.onSharedPreferenceChanged(this@FakeSharedPreferences, it)
154                     }
155                 }
156             }
157             return true
158         }
159 
160         override fun apply() {
161             commit()
162         }
163     }
164 }
165