1 /*
2  * Copyright (C) 2023 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.server.utils;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.provider.DeviceConfig;
22 import android.util.KeyValueListParser;
23 
24 /**
25  * Helper class to mediate the value to use when a constant exists in both a key=value pair Settings
26  * constant (that can be parsed by {@link KeyValueListParser})
27  * and the {@link DeviceConfig} properties.
28  */
29 public abstract class UserSettingDeviceConfigMediator {
30     private static final String TAG = UserSettingDeviceConfigMediator.class.getSimpleName();
31 
32     @Nullable
33     protected DeviceConfig.Properties mProperties;
34     @NonNull
35     protected final KeyValueListParser mSettingsParser;
36 
37     /**
38      * @param keyValueListDelimiter The delimiter passed into the {@link KeyValueListParser}.
39      */
UserSettingDeviceConfigMediator(char keyValueListDelimiter)40     protected UserSettingDeviceConfigMediator(char keyValueListDelimiter) {
41         mSettingsParser = new KeyValueListParser(keyValueListDelimiter);
42     }
43 
44     /**
45      * Sets the key=value list string to read from. Setting {@code null} will clear any previously
46      * set string.
47      */
setSettingsString(@ullable String settings)48     public void setSettingsString(@Nullable String settings) {
49         mSettingsParser.setString(settings);
50     }
51 
52     /**
53      * Sets the DeviceConfig Properties to read from. Setting {@code null} will clear any previously
54      * set properties.
55      */
setDeviceConfigProperties(@ullable DeviceConfig.Properties properties)56     public void setDeviceConfigProperties(@Nullable DeviceConfig.Properties properties) {
57         mProperties = properties;
58     }
59 
60     /**
61      * Get the value for key as a boolean.
62      *
63      * @param key          The key to lookup.
64      * @param defaultValue The value to return if the key was not found, or not properly defined.
65      */
getBoolean(@onNull String key, boolean defaultValue)66     public abstract boolean getBoolean(@NonNull String key, boolean defaultValue);
67 
68     /**
69      * Get the value for key as a float.
70      *
71      * @param key          The key to lookup.
72      * @param defaultValue The value to return if the key was not found, or not properly defined.
73      */
getFloat(@onNull String key, float defaultValue)74     public abstract float getFloat(@NonNull String key, float defaultValue);
75 
76     /**
77      * Get the value for key as an int.
78      *
79      * @param key          The key to lookup.
80      * @param defaultValue The value to return if the key was not found, or not properly defined.
81      */
getInt(@onNull String key, int defaultValue)82     public abstract int getInt(@NonNull String key, int defaultValue);
83 
84     /**
85      * Get the value for key as a long.
86      *
87      * @param key          The key to lookup.
88      * @param defaultValue The value to return if the key was not found, or not properly defined.
89      */
getLong(@onNull String key, long defaultValue)90     public abstract long getLong(@NonNull String key, long defaultValue);
91 
92     /**
93      * Get the value for key as a String.
94      *
95      * @param key          The key to lookup.
96      * @param defaultValue The value to return if the key was not found, or not properly defined.
97      */
getString(@onNull String key, @Nullable String defaultValue)98     public abstract String getString(@NonNull String key, @Nullable String defaultValue);
99 
100     /**
101      * A mediator in which the existence of a single settings key-value pair will override usage
102      * of DeviceConfig properties. That is, if the Settings constant has any values set,
103      * then everything in the DeviceConfig namespace will be ignored.
104      */
105     public static class SettingsOverridesAllMediator extends UserSettingDeviceConfigMediator {
SettingsOverridesAllMediator(char keyValueListDelimiter)106         public SettingsOverridesAllMediator(char keyValueListDelimiter) {
107             super(keyValueListDelimiter);
108         }
109 
110         @Override
getBoolean(@onNull String key, boolean defaultValue)111         public boolean getBoolean(@NonNull String key, boolean defaultValue) {
112             if (mSettingsParser.size() == 0) {
113                 return mProperties == null
114                         ? defaultValue : mProperties.getBoolean(key, defaultValue);
115             }
116             return mSettingsParser.getBoolean(key, defaultValue);
117         }
118 
119         @Override
getFloat(@onNull String key, float defaultValue)120         public float getFloat(@NonNull String key, float defaultValue) {
121             if (mSettingsParser.size() == 0) {
122                 return mProperties == null ? defaultValue : mProperties.getFloat(key, defaultValue);
123             }
124             return mSettingsParser.getFloat(key, defaultValue);
125         }
126 
127         @Override
getInt(@onNull String key, int defaultValue)128         public int getInt(@NonNull String key, int defaultValue) {
129             if (mSettingsParser.size() == 0) {
130                 return mProperties == null ? defaultValue : mProperties.getInt(key, defaultValue);
131             }
132             return mSettingsParser.getInt(key, defaultValue);
133         }
134 
135         @Override
getLong(@onNull String key, long defaultValue)136         public long getLong(@NonNull String key, long defaultValue) {
137             if (mSettingsParser.size() == 0) {
138                 return mProperties == null ? defaultValue : mProperties.getLong(key, defaultValue);
139             }
140             return mSettingsParser.getLong(key, defaultValue);
141         }
142 
143         @Override
getString(@onNull String key, @Nullable String defaultValue)144         public String getString(@NonNull String key, @Nullable String defaultValue) {
145             if (mSettingsParser.size() == 0) {
146                 return mProperties == null
147                         ? defaultValue : mProperties.getString(key, defaultValue);
148             }
149             return mSettingsParser.getString(key, defaultValue);
150         }
151     }
152 
153     /**
154      * A mediator in which only individual keys in the DeviceConfig namespace will be overridden
155      * by the same key in the Settings constant. If the Settings constant does not have a specific
156      * key set, then the DeviceConfig value will be used instead.
157      */
158     public static class SettingsOverridesIndividualMediator
159             extends UserSettingDeviceConfigMediator {
SettingsOverridesIndividualMediator(char keyValueListDelimiter)160         public SettingsOverridesIndividualMediator(char keyValueListDelimiter) {
161             super(keyValueListDelimiter);
162         }
163 
164         @Override
getBoolean(@onNull String key, boolean defaultValue)165         public boolean getBoolean(@NonNull String key, boolean defaultValue) {
166             return mSettingsParser.getBoolean(key,
167                     mProperties == null ? defaultValue : mProperties.getBoolean(key, defaultValue));
168         }
169 
170         @Override
getFloat(@onNull String key, float defaultValue)171         public float getFloat(@NonNull String key, float defaultValue) {
172             return mSettingsParser.getFloat(key,
173                     mProperties == null ? defaultValue : mProperties.getFloat(key, defaultValue));
174         }
175 
176         @Override
getInt(@onNull String key, int defaultValue)177         public int getInt(@NonNull String key, int defaultValue) {
178             return mSettingsParser.getInt(key,
179                     mProperties == null ? defaultValue : mProperties.getInt(key, defaultValue));
180         }
181 
182         @Override
getLong(@onNull String key, long defaultValue)183         public long getLong(@NonNull String key, long defaultValue) {
184             return mSettingsParser.getLong(key,
185                     mProperties == null ? defaultValue : mProperties.getLong(key, defaultValue));
186         }
187 
188         @Override
getString(@onNull String key, @Nullable String defaultValue)189         public String getString(@NonNull String key, @Nullable String defaultValue) {
190             return mSettingsParser.getString(key,
191                     mProperties == null ? defaultValue : mProperties.getString(key, defaultValue));
192         }
193     }
194 }
195