1 /*
2  * Copyright (C) 2017 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.settings.testutils.shadow;
18 
19 import android.content.ContentResolver;
20 import android.provider.Settings;
21 
22 import com.google.common.collect.HashBasedTable;
23 import com.google.common.collect.Table;
24 
25 import org.robolectric.annotation.Implementation;
26 import org.robolectric.annotation.Implements;
27 
28 import java.util.Map;
29 import java.util.WeakHashMap;
30 
31 @Implements(Settings.Secure.class)
32 public class ShadowSecureSettings {
33 
34     private static final Map<ContentResolver, Table<Integer, String, Object>> sUserDataMap =
35         new WeakHashMap<>();
36 
37     @Implementation
putStringForUser(ContentResolver resolver, String name, String value, String tag, boolean makeDefault, int userHandle)38     public static boolean putStringForUser(ContentResolver resolver, String name, String value,
39         String tag, boolean makeDefault, int userHandle) {
40         final Table<Integer, String, Object> userTable = getUserTable(resolver);
41         synchronized (userTable) {
42             if (value != null) {
43                 userTable.put(userHandle, name, value);
44             } else {
45                 userTable.remove(userHandle, name);
46             }
47             return true;
48         }
49     }
50 
51     @Implementation
getStringForUser(ContentResolver resolver, String name, int userHandle)52     public static String getStringForUser(ContentResolver resolver, String name, int userHandle) {
53         final Table<Integer, String, Object> userTable = getUserTable(resolver);
54         synchronized (userTable) {
55             return (String) userTable.get(userHandle, name);
56         }
57     }
58 
59     @Implementation
putIntForUser(ContentResolver resolver, String name, int value, int userHandle)60     public static boolean putIntForUser(ContentResolver resolver, String name, int value,
61         int userHandle) {
62         final Table<Integer, String, Object> userTable = getUserTable(resolver);
63         synchronized (userTable) {
64             userTable.put(userHandle, name, value);
65             return true;
66         }
67     }
68 
69     @Implementation
getIntForUser(ContentResolver resolver, String name, int def, int userHandle)70     public static int getIntForUser(ContentResolver resolver, String name, int def,
71         int userHandle) {
72         final Table<Integer, String, Object> userTable = getUserTable(resolver);
73         synchronized (userTable) {
74             final Object object = userTable.get(userHandle, name);
75             return object instanceof Integer ? (Integer) object : def;
76         }
77     }
78 
79     @Implementation
putLongForUser(ContentResolver resolver, String name, long value, int userHandle)80     public static boolean putLongForUser(ContentResolver resolver, String name, long value,
81         int userHandle) {
82         final Table<Integer, String, Object> userTable = getUserTable(resolver);
83         synchronized (userTable) {
84             userTable.put(userHandle, name, value);
85             return true;
86         }
87     }
88 
89     @Implementation
getLongForUser(ContentResolver resolver, String name, long def, int userHandle)90     public static long getLongForUser(ContentResolver resolver, String name, long def,
91         int userHandle) {
92         final Table<Integer, String, Object> userTable = getUserTable(resolver);
93         synchronized (userTable) {
94             final Object object = userTable.get(userHandle, name);
95             return object instanceof Long ? (Long) object : def;
96         }
97     }
98 
99     @Implementation
putFloatForUser( ContentResolver resolver, String name, float value, int userHandle)100     public static boolean putFloatForUser(
101             ContentResolver resolver, String name, float value, int userHandle) {
102         final Table<Integer, String, Object> userTable = getUserTable(resolver);
103         synchronized (userTable) {
104             userTable.put(userHandle, name, value);
105             return true;
106         }
107     }
108 
109     @Implementation
getFloatForUser( ContentResolver resolver, String name, float def, int userHandle)110     public static float getFloatForUser(
111             ContentResolver resolver, String name, float def, int userHandle) {
112         final Table<Integer, String, Object> userTable = getUserTable(resolver);
113         synchronized (userTable) {
114             final Object object = userTable.get(userHandle, name);
115             return object instanceof Float ? (Float) object : def;
116         }
117     }
118 
clear()119     public static void clear() {
120         synchronized (sUserDataMap) {
121             sUserDataMap.clear();
122         }
123     }
124 
getUserTable(ContentResolver contentResolver)125     private static Table<Integer, String, Object> getUserTable(ContentResolver contentResolver) {
126         synchronized (sUserDataMap) {
127             Table<Integer, String, Object> table = sUserDataMap.get(contentResolver);
128             if (table == null) {
129                 table = HashBasedTable.create();
130                 sUserDataMap.put(contentResolver, table);
131             }
132             return table;
133         }
134     }
135 }
136