• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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.providers.settings;
18 
19 import android.content.ContentResolver;
20 import android.content.ContentValues;
21 import android.content.Context;
22 import android.content.pm.UserInfo;
23 import android.database.Cursor;
24 import android.net.Uri;
25 import android.os.UserHandle;
26 import android.os.UserManager;
27 import android.provider.Settings;
28 import android.support.test.InstrumentationRegistry;
29 import android.support.test.runner.AndroidJUnit4;
30 import libcore.io.Streams;
31 import org.junit.runner.RunWith;
32 
33 import java.io.FileInputStream;
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.util.List;
37 
38 /**
39  * Base class for the SettingContentProvider tests.
40  */
41 @RunWith(AndroidJUnit4.class)
42 abstract class BaseSettingsProviderTest {
43     protected static final int SETTING_TYPE_GLOBAL = 1;
44     protected static final int SETTING_TYPE_SECURE = 2;
45     protected static final int SETTING_TYPE_SYSTEM = 3;
46 
47     protected static final String FAKE_SETTING_NAME = "fake_setting_name";
48     protected static final String FAKE_SETTING_NAME_1 = "fake_setting_name1";
49     protected static final String FAKE_SETTING_NAME_2 = "fake_setting_name2";
50     protected static final String FAKE_SETTING_VALUE = "fake_setting_value";
51     protected static final String FAKE_SETTING_VALUE_1 = SettingsStateTest.CRAZY_STRING;
52     protected static final String FAKE_SETTING_VALUE_2 = null;
53 
54     private static final String[] NAME_VALUE_COLUMNS = new String[] {
55             Settings.NameValueTable.NAME, Settings.NameValueTable.VALUE
56     };
57 
58     private int mSecondaryUserId = Integer.MIN_VALUE;
59 
setStringViaFrontEndApiSetting(int type, String name, String value, int userId)60     protected void setStringViaFrontEndApiSetting(int type, String name, String value, int userId) {
61         ContentResolver contentResolver = getContext().getContentResolver();
62 
63         switch (type) {
64             case SETTING_TYPE_GLOBAL: {
65                 Settings.Global.putStringForUser(contentResolver, name, value, userId);
66             } break;
67 
68             case SETTING_TYPE_SECURE: {
69                 Settings.Secure.putStringForUser(contentResolver, name, value, userId);
70             } break;
71 
72             case SETTING_TYPE_SYSTEM: {
73                 Settings.System.putStringForUser(contentResolver, name, value, userId);
74             } break;
75 
76             default: {
77                 throw new IllegalArgumentException("Invalid type: " + type);
78             }
79         }
80     }
81 
getStringViaFrontEndApiSetting(int type, String name, int userId)82     protected String getStringViaFrontEndApiSetting(int type, String name, int userId) {
83         ContentResolver contentResolver = getContext().getContentResolver();
84 
85         switch (type) {
86             case SETTING_TYPE_GLOBAL: {
87                 return Settings.Global.getStringForUser(contentResolver, name, userId);
88             }
89 
90             case SETTING_TYPE_SECURE: {
91                 return Settings.Secure.getStringForUser(contentResolver, name, userId);
92             }
93 
94             case SETTING_TYPE_SYSTEM: {
95                 return Settings.System.getStringForUser(contentResolver, name, userId);
96             }
97 
98             default: {
99                 throw new IllegalArgumentException("Invalid type: " + type);
100             }
101         }
102     }
103 
insertStringViaProviderApi(int type, String name, String value, boolean withTableRowUri)104     protected Uri insertStringViaProviderApi(int type, String name, String value,
105             boolean withTableRowUri) {
106         Uri uri = getBaseUriForType(type);
107         if (withTableRowUri) {
108             uri = Uri.withAppendedPath(uri, name);
109         }
110         ContentValues values = new ContentValues();
111         values.put(Settings.NameValueTable.NAME, name);
112         values.put(Settings.NameValueTable.VALUE, value);
113 
114         return getContext().getContentResolver().insert(uri, values);
115     }
116 
deleteStringViaProviderApi(int type, String name)117     protected int deleteStringViaProviderApi(int type, String name) {
118         Uri uri = getBaseUriForType(type);
119         return getContext().getContentResolver().delete(uri, "name=?", new String[]{name});
120     }
121 
updateStringViaProviderApiSetting(int type, String name, String value)122     protected int updateStringViaProviderApiSetting(int type, String name, String value) {
123         Uri uri = getBaseUriForType(type);
124         ContentValues values = new ContentValues();
125         values.put(Settings.NameValueTable.NAME, name);
126         values.put(Settings.NameValueTable.VALUE, value);
127         return getContext().getContentResolver().update(uri, values, "name=?",
128                 new String[]{name});
129     }
130 
queryStringViaProviderApi(int type, String name)131     protected String queryStringViaProviderApi(int type, String name) {
132         return queryStringViaProviderApi(type, name, false, false);
133     }
134 
queryStringViaProviderApi(int type, String name, boolean queryStringInQuotes, boolean appendNameToUri)135     protected String queryStringViaProviderApi(int type, String name, boolean queryStringInQuotes,
136             boolean appendNameToUri) {
137         final Uri uri;
138         final String queryString;
139         final String[] queryArgs;
140 
141         if (appendNameToUri) {
142             uri = Uri.withAppendedPath(getBaseUriForType(type), name);
143             queryString = null;
144             queryArgs = null;
145         } else {
146             uri = getBaseUriForType(type);
147             queryString = queryStringInQuotes ? "(name=?)" : "name=?";
148             queryArgs = new String[]{name};
149         }
150 
151         Cursor cursor = getContext().getContentResolver().query(uri, NAME_VALUE_COLUMNS,
152                 queryString, queryArgs, null);
153 
154         if (cursor == null) {
155             return null;
156         }
157 
158         try {
159             if (cursor.moveToFirst()) {
160                 final int valueColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.VALUE);
161                 return cursor.getString(valueColumnIdx);
162             }
163         } finally {
164             cursor.close();
165         }
166 
167         return null;
168     }
169 
resetSettingsViaShell(int type, int resetMode)170     protected static void resetSettingsViaShell(int type, int resetMode) throws IOException {
171         final String modeString;
172         switch (resetMode) {
173             case Settings.RESET_MODE_UNTRUSTED_DEFAULTS: {
174                 modeString = "untrusted_defaults";
175             } break;
176 
177             case Settings.RESET_MODE_UNTRUSTED_CHANGES: {
178                 modeString = "untrusted_clear";
179             } break;
180 
181             case Settings.RESET_MODE_TRUSTED_DEFAULTS: {
182                 modeString = "trusted_defaults";
183             } break;
184 
185             default: {
186                 throw new IllegalArgumentException("Invalid reset mode: " + resetMode);
187             }
188         }
189 
190         switch (type) {
191             case SETTING_TYPE_GLOBAL: {
192                 executeShellCommand("settings reset global " + modeString);
193             } break;
194 
195             case SETTING_TYPE_SECURE: {
196                 executeShellCommand("settings reset secure " + modeString);
197             } break;
198 
199             default: {
200                 throw new IllegalArgumentException("Invalid type: " + type);
201             }
202         }
203     }
204 
resetToDefaultsViaShell(int type, String packageName)205     protected static void resetToDefaultsViaShell(int type, String packageName) throws IOException {
206         resetToDefaultsViaShell(type, packageName, null);
207     }
208 
resetToDefaultsViaShell(int type, String packageName, String tag)209     protected static void resetToDefaultsViaShell(int type, String packageName, String tag)
210             throws IOException {
211         switch (type) {
212             case SETTING_TYPE_GLOBAL: {
213                 executeShellCommand("settings reset global " + packageName + " "
214                         + (tag != null ? tag : ""));
215             } break;
216 
217             case SETTING_TYPE_SECURE: {
218                 executeShellCommand("settings reset secure " + packageName + " "
219                         + (tag != null ? tag : ""));
220             } break;
221 
222             case SETTING_TYPE_SYSTEM: {
223                 executeShellCommand("settings reset system " + packageName + " "
224                         + (tag != null ? tag : ""));
225             } break;
226 
227             default: {
228                 throw new IllegalArgumentException("Invalid type: " + type);
229             }
230         }
231     }
232 
getSetting(int type, String name)233     protected String getSetting(int type, String name) {
234         switch (type) {
235             case SETTING_TYPE_GLOBAL: {
236                 return Settings.Global.getString(getContext().getContentResolver(), name);
237             }
238 
239             case SETTING_TYPE_SECURE: {
240                 return Settings.Secure.getString(getContext().getContentResolver(), name);
241             }
242 
243             case SETTING_TYPE_SYSTEM: {
244                 return Settings.System.getString(getContext().getContentResolver(), name);
245             }
246 
247             default: {
248                 throw new IllegalArgumentException("Invalid type: " + type);
249             }
250         }
251     }
252 
putSetting(int type, String name, String value)253     protected void putSetting(int type, String name, String value) {
254         switch (type) {
255             case SETTING_TYPE_GLOBAL: {
256                 Settings.Global.putString(getContext().getContentResolver(), name, value);
257             } break;
258 
259             case SETTING_TYPE_SECURE: {
260                 Settings.Secure.putString(getContext().getContentResolver(), name, value);
261             } break;
262 
263             case SETTING_TYPE_SYSTEM: {
264                 Settings.System.putString(getContext().getContentResolver(), name, value);
265             } break;
266 
267             default: {
268                 throw new IllegalArgumentException("Invalid type: " + type);
269             }
270         }
271     }
272 
setSettingViaShell(int type, String name, String value, boolean makeDefault)273     protected static void setSettingViaShell(int type, String name, String value,
274             boolean makeDefault) throws IOException {
275         setSettingViaShell(type, name, value, null, makeDefault);
276     }
277 
setSettingViaShell(int type, String name, String value, String token, boolean makeDefault)278     protected static void setSettingViaShell(int type, String name, String value,
279             String token, boolean makeDefault) throws IOException {
280         switch (type) {
281             case SETTING_TYPE_GLOBAL: {
282                 executeShellCommand("settings put global " + name + " "
283                         + value + (token != null ? " " + token : "")
284                         + (makeDefault ? " default" : ""));
285 
286             } break;
287 
288             case SETTING_TYPE_SECURE: {
289                 executeShellCommand("settings put secure " + name + " "
290                         + value + (token != null ? " " + token : "")
291                         + (makeDefault ? " default" : ""));
292             } break;
293 
294             case SETTING_TYPE_SYSTEM: {
295                 executeShellCommand("settings put system " + name + " "
296                         + value + (token != null ? " " + token : "")
297                         + (makeDefault ? " default" : ""));
298             } break;
299 
300             default: {
301                 throw new IllegalArgumentException("Invalid type: " + type);
302             }
303         }
304     }
305 
getContext()306     protected Context getContext() {
307         return InstrumentationRegistry.getContext();
308     }
309 
getSecondaryUserId()310     protected int getSecondaryUserId() {
311         if (mSecondaryUserId == Integer.MIN_VALUE) {
312             UserManager userManager = (UserManager) getContext()
313                     .getSystemService(Context.USER_SERVICE);
314             List<UserInfo> users = userManager.getUsers();
315             final int userCount = users.size();
316             for (int i = 0; i < userCount; i++) {
317                 UserInfo user = users.get(i);
318                 if (!user.isPrimary() && !user.isManagedProfile()) {
319                     mSecondaryUserId = user.id;
320                     return mSecondaryUserId;
321                 }
322             }
323         }
324         if (mSecondaryUserId == Integer.MIN_VALUE) {
325             mSecondaryUserId =  UserHandle.USER_SYSTEM;
326         }
327         return mSecondaryUserId;
328     }
329 
getBaseUriForType(int type)330     protected static Uri getBaseUriForType(int type) {
331         switch (type) {
332             case SETTING_TYPE_GLOBAL: {
333                 return Settings.Global.CONTENT_URI;
334             }
335 
336             case SETTING_TYPE_SECURE: {
337                 return Settings.Secure.CONTENT_URI;
338             }
339 
340             case SETTING_TYPE_SYSTEM: {
341                 return Settings.System.CONTENT_URI;
342             }
343 
344             default: {
345                 throw new IllegalArgumentException("Invalid type: " + type);
346             }
347         }
348     }
349 
executeShellCommand(String command)350     protected static void executeShellCommand(String command) throws IOException {
351         InputStream is = new FileInputStream(InstrumentationRegistry.getInstrumentation()
352                 .getUiAutomation().executeShellCommand(command).getFileDescriptor());
353         Streams.readFully(is);
354     }
355 }
356