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.server.am;
18 
19 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
20 
21 import static com.android.server.am.ActivityManagerService.Injector;
22 
23 import static com.google.common.truth.Truth.assertWithMessage;
24 
25 import static org.junit.Assert.assertEquals;
26 import static org.mockito.Mockito.anyInt;
27 import static org.mockito.Mockito.mock;
28 import static org.mockito.Mockito.when;
29 
30 import android.content.Context;
31 import android.content.res.Resources;
32 import android.content.res.TypedArray;
33 import android.os.Bundle;
34 import android.os.Handler;
35 import android.provider.Settings;
36 import android.test.mock.MockContentResolver;
37 
38 import androidx.test.filters.SmallTest;
39 
40 import com.android.internal.util.test.FakeSettingsProvider;
41 import com.android.server.appop.AppOpsService;
42 
43 import org.junit.AfterClass;
44 import org.junit.Before;
45 import org.junit.BeforeClass;
46 import org.junit.Rule;
47 import org.junit.Test;
48 import org.mockito.Mock;
49 import org.mockito.MockitoAnnotations;
50 
51 import java.io.File;
52 
53 /**
54  * Test class for {@link CoreSettingsObserver}.
55  *
56  * Build/Install/Run:
57  *  atest FrameworksServicesTests:CoreSettingsObserverTest
58  */
59 @SmallTest
60 public class CoreSettingsObserverTest {
61     private static final String TEST_SETTING_SECURE_INT = "secureInt";
62     private static final String TEST_SETTING_GLOBAL_FLOAT = "globalFloat";
63     private static final String TEST_SETTING_SYSTEM_STRING = "systemString";
64 
65     private static final int TEST_INT = 111;
66     private static final float TEST_FLOAT = 3.14f;
67     private static final String TEST_STRING = "testString";
68 
69     @Rule public ServiceThreadRule mServiceThreadRule = new ServiceThreadRule();
70 
71     private ActivityManagerService mAms;
72     @Mock private Context mContext;
73     @Mock private Resources mResources;
74 
75     private MockContentResolver mContentResolver;
76     private CoreSettingsObserver mCoreSettingsObserver;
77 
78     @BeforeClass
setupOnce()79     public static void setupOnce() {
80         FakeSettingsProvider.clearSettingsProvider();
81         CoreSettingsObserver.sSecureSettingToTypeMap.put(TEST_SETTING_SECURE_INT, int.class);
82         CoreSettingsObserver.sGlobalSettingToTypeMap.put(TEST_SETTING_GLOBAL_FLOAT, float.class);
83         CoreSettingsObserver.sSystemSettingToTypeMap.put(TEST_SETTING_SYSTEM_STRING, String.class);
84     }
85 
86     @AfterClass
tearDownOnce()87     public static void tearDownOnce() {
88         FakeSettingsProvider.clearSettingsProvider();
89     }
90 
91     @Before
setUp()92     public void setUp() {
93         MockitoAnnotations.initMocks(this);
94 
95         final Context originalContext = getInstrumentation().getTargetContext();
96         when(mContext.getApplicationInfo()).thenReturn(originalContext.getApplicationInfo());
97         mContentResolver = new MockContentResolver(mContext);
98         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
99         when(mContext.getContentResolver()).thenReturn(mContentResolver);
100         when(mContext.getCacheDir()).thenReturn(originalContext.getCacheDir());
101         when(mContext.getAttributionSource()).thenReturn(originalContext.getAttributionSource());
102         when(mContext.getResources()).thenReturn(mResources);
103         // To prevent NullPointerException at the constructor of ActivityManagerConstants.
104         when(mResources.getStringArray(anyInt())).thenReturn(new String[0]);
105         when(mResources.getIntArray(anyInt())).thenReturn(new int[0]);
106         final TypedArray mockTypedArray = mock(TypedArray.class);
107         when(mockTypedArray.length()).thenReturn(1);
108         when(mResources.obtainTypedArray(anyInt())).thenReturn(mockTypedArray);
109 
110         mAms = new ActivityManagerService(new TestInjector(mContext),
111                 mServiceThreadRule.getThread());
112         mCoreSettingsObserver = new CoreSettingsObserver(mAms);
113     }
114 
115     @Test
testPopulateSettings()116     public void testPopulateSettings() {
117         Settings.Secure.putInt(mContentResolver, TEST_SETTING_SECURE_INT, TEST_INT);
118         Settings.Global.putFloat(mContentResolver, TEST_SETTING_GLOBAL_FLOAT, TEST_FLOAT);
119         Settings.System.putString(mContentResolver, TEST_SETTING_SYSTEM_STRING, TEST_STRING);
120 
121         final Bundle settingsBundle = getPopulatedBundle();
122 
123         assertEquals("Unexpected value of " + TEST_SETTING_SECURE_INT,
124                 TEST_INT, settingsBundle.getInt(TEST_SETTING_SECURE_INT));
125         assertEquals("Unexpected value of " + TEST_SETTING_GLOBAL_FLOAT,
126                 TEST_FLOAT, settingsBundle.getFloat(TEST_SETTING_GLOBAL_FLOAT), 0);
127         assertEquals("Unexpected value of " + TEST_SETTING_SYSTEM_STRING,
128                 TEST_STRING, settingsBundle.getString(TEST_SETTING_SYSTEM_STRING));
129     }
130 
131     @Test
testPopulateSettings_settingNotSet()132     public void testPopulateSettings_settingNotSet() {
133         final Bundle settingsBundle = getPopulatedBundle();
134 
135         assertWithMessage("Bundle should not contain " + TEST_SETTING_SECURE_INT)
136                 .that(settingsBundle.keySet()).doesNotContain(TEST_SETTING_SECURE_INT);
137         assertWithMessage("Bundle should not contain " + TEST_SETTING_GLOBAL_FLOAT)
138                 .that(settingsBundle.keySet()).doesNotContain(TEST_SETTING_GLOBAL_FLOAT);
139         assertWithMessage("Bundle should not contain " + TEST_SETTING_SYSTEM_STRING)
140                 .that(settingsBundle.keySet()).doesNotContain(TEST_SETTING_SYSTEM_STRING);
141     }
142 
143     @Test
testPopulateSettings_settingDeleted()144     public void testPopulateSettings_settingDeleted() {
145         Settings.Secure.putInt(mContentResolver, TEST_SETTING_SECURE_INT, TEST_INT);
146         Settings.Global.putFloat(mContentResolver, TEST_SETTING_GLOBAL_FLOAT, TEST_FLOAT);
147         Settings.System.putString(mContentResolver, TEST_SETTING_SYSTEM_STRING, TEST_STRING);
148 
149         Bundle settingsBundle = getPopulatedBundle();
150 
151         assertEquals("Unexpected value of " + TEST_SETTING_SECURE_INT,
152                 TEST_INT, settingsBundle.getInt(TEST_SETTING_SECURE_INT));
153         assertEquals("Unexpected value of " + TEST_SETTING_GLOBAL_FLOAT,
154                 TEST_FLOAT, settingsBundle.getFloat(TEST_SETTING_GLOBAL_FLOAT), 0);
155         assertEquals("Unexpected value of " + TEST_SETTING_SYSTEM_STRING,
156                 TEST_STRING, settingsBundle.getString(TEST_SETTING_SYSTEM_STRING));
157 
158         Settings.Global.putString(mContentResolver, TEST_SETTING_GLOBAL_FLOAT, null);
159         settingsBundle = getPopulatedBundle();
160 
161         assertWithMessage("Bundle should not contain " + TEST_SETTING_GLOBAL_FLOAT)
162                 .that(settingsBundle.keySet()).doesNotContain(TEST_SETTING_GLOBAL_FLOAT);
163         assertEquals("Unexpected value of " + TEST_SETTING_SECURE_INT,
164                 TEST_INT, settingsBundle.getInt(TEST_SETTING_SECURE_INT));
165         assertEquals("Unexpected value of " + TEST_SETTING_SYSTEM_STRING,
166                 TEST_STRING, settingsBundle.getString(TEST_SETTING_SYSTEM_STRING));
167 
168     }
169 
getPopulatedBundle()170     private Bundle getPopulatedBundle() {
171         mCoreSettingsObserver.onChange(false);
172         return mCoreSettingsObserver.getCoreSettingsLocked();
173     }
174 
175     private class TestInjector extends Injector {
176 
TestInjector(Context context)177         TestInjector(Context context) {
178             super(context);
179         }
180 
181         @Override
getAppOpsService(File recentAccessesFile, File storageFile, Handler handler)182         public AppOpsService getAppOpsService(File recentAccessesFile, File storageFile,
183                 Handler handler) {
184             return null;
185         }
186 
187         @Override
getUiHandler(ActivityManagerService service)188         public Handler getUiHandler(ActivityManagerService service) {
189             return mServiceThreadRule.getThread().getThreadHandler();
190         }
191     }
192 }
193