• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.alarmmanager.util;
18 
19 import static com.android.compatibility.common.util.TestUtils.waitUntil;
20 
21 import static org.junit.Assert.assertTrue;
22 
23 import android.provider.DeviceConfig;
24 import android.util.Log;
25 
26 import com.android.compatibility.common.util.SystemUtil;
27 
28 import java.util.Collections;
29 import java.util.HashMap;
30 import java.util.Map;
31 
32 public class AlarmManagerDeviceConfigHelper {
33     private static final String TAG = AlarmManagerDeviceConfigHelper.class.getSimpleName();
34 
35     private static final int UPDATE_TIMEOUT_SECONDS = 60;
36 
37     private volatile Map<String, String> mCommittedMap;
38     private final Map<String, String> mInitialPropertiesMap;
39     private final Map<String, String> mPropertiesToSetMap;
40 
AlarmManagerDeviceConfigHelper()41     public AlarmManagerDeviceConfigHelper() {
42         mPropertiesToSetMap = new HashMap<>();
43         DeviceConfig.Properties initialProperties = null;
44         try {
45             initialProperties = SystemUtil.callWithShellPermissionIdentity(
46                     () -> DeviceConfig.getProperties(DeviceConfig.NAMESPACE_ALARM_MANAGER));
47         } catch (Exception e) {
48             Log.e(TAG, "Unexpected exception while fetching device_config properties", e);
49         }
50         if (initialProperties != null) {
51             for (String key : initialProperties.getKeyset()) {
52                 mPropertiesToSetMap.put(key, initialProperties.getString(key, null));
53             }
54             mCommittedMap = mInitialPropertiesMap = Collections.unmodifiableMap(
55                     new HashMap<>(mPropertiesToSetMap));
56         } else {
57             mCommittedMap = mInitialPropertiesMap =  Collections.emptyMap();
58         }
59     }
60 
with(String key, long value)61     public AlarmManagerDeviceConfigHelper with(String key, long value) {
62         return with(key, Long.toString(value));
63     }
64 
with(String key, int value)65     public AlarmManagerDeviceConfigHelper with(String key, int value) {
66         return with(key, Integer.toString(value));
67     }
68 
with(String key, boolean value)69     public AlarmManagerDeviceConfigHelper with(String key, boolean value) {
70         return with(key, Boolean.toString(value));
71     }
72 
with(String key, String value)73     public AlarmManagerDeviceConfigHelper with(String key, String value) {
74         mPropertiesToSetMap.put(key, value);
75         return this;
76     }
77 
without(String key)78     public AlarmManagerDeviceConfigHelper without(String key) {
79         mPropertiesToSetMap.remove(key);
80         return this;
81     }
82 
getCurrentConfigVersion()83     private static int getCurrentConfigVersion() {
84         final String output = SystemUtil.runShellCommand("cmd alarm get-config-version").trim();
85         return Integer.parseInt(output);
86     }
87 
commitAndAwaitPropagation(DeviceConfig.Properties propertiesToSet)88     public static void commitAndAwaitPropagation(DeviceConfig.Properties propertiesToSet) {
89         final int currentVersion = getCurrentConfigVersion();
90         try {
91             assertTrue("setProperties returned false", SystemUtil.callWithShellPermissionIdentity(
92                     () -> DeviceConfig.setProperties(propertiesToSet)));
93         } catch (Exception e) {
94             throw new RuntimeException(e);
95         }
96         try {
97             waitUntil("Could not update config within " + UPDATE_TIMEOUT_SECONDS
98                             + "s. Current version: " + currentVersion, UPDATE_TIMEOUT_SECONDS,
99                     () -> (getCurrentConfigVersion() > currentVersion));
100         } catch (Exception e) {
101             throw new RuntimeException("Unexpected exception while updating config", e);
102         }
103     }
104 
commitAndAwaitPropagation()105     public void commitAndAwaitPropagation() {
106         if (mPropertiesToSetMap.equals(mCommittedMap)) {
107             // This will not cause any change, and will not bump up the config version.
108             return;
109         }
110         commitAndAwaitPropagation(
111                 new DeviceConfig.Properties(DeviceConfig.NAMESPACE_ALARM_MANAGER,
112                         mPropertiesToSetMap));
113         mCommittedMap = Collections.unmodifiableMap(new HashMap<>(mPropertiesToSetMap));
114     }
115 
restoreAll()116     public void restoreAll() {
117         if (mCommittedMap.equals(mInitialPropertiesMap)) {
118             // This will not cause any change, and will not bump up the config version.
119             return;
120         }
121         commitAndAwaitPropagation(new DeviceConfig.Properties(DeviceConfig.NAMESPACE_ALARM_MANAGER,
122                 mInitialPropertiesMap));
123         mCommittedMap = Collections.emptyMap();
124     }
125 }
126