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.server.am;
18 
19 import android.annotation.NonNull;
20 import android.provider.DeviceConfig;
21 
22 import com.android.compatibility.common.util.SystemUtil;
23 import com.android.internal.util.function.TriFunction;
24 
25 /**
26  * An utility class to set/restore the given device_config item.
27  */
28 public class DeviceConfigSession<T> implements AutoCloseable {
29     private final TriFunction<String, String, T, T> mGetter;
30 
31     private final String mNamespace;
32     private final String mKey;
33     private final T mInitialValue;
34     private final T mDefaultValue;
35     private boolean mHasInitalValue;
36 
DeviceConfigSession(String namespace, String key, TriFunction<String, String, T, T> getter, T defaultValue)37     DeviceConfigSession(String namespace, String key,
38             TriFunction<String, String, T, T> getter, T defaultValue) {
39         mNamespace = namespace;
40         mKey = key;
41         mGetter = getter;
42         mDefaultValue = defaultValue;
43         // Try {@DeviceConfig#getString} firstly since the DeviceConfig API doesn't
44         // support "not found" exception.
45         final String initialStringValue = DeviceConfig.getString(namespace, key, null);
46         if (initialStringValue == null) {
47             mHasInitalValue = false;
48             mInitialValue = defaultValue;
49         } else {
50             mHasInitalValue = true;
51             mInitialValue = getter.apply(namespace, key, defaultValue);
52         }
53     }
54 
set(final @NonNull T value)55     public void set(final @NonNull T value) {
56         DeviceConfig.setProperty(mNamespace, mKey,
57                 value == null ? null : value.toString(), false);
58     }
59 
get()60     public T get() {
61         return mGetter.apply(mNamespace, mKey, mDefaultValue);
62     }
63 
64     @Override
close()65     public void close() throws Exception {
66         if (mHasInitalValue) {
67             set(mInitialValue);
68         } else {
69             SystemUtil.runShellCommand("device_config delete " + mNamespace + " " + mKey);
70         }
71     }
72 }
73