• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.localepicker;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.Mockito.mock;
22 import static org.mockito.Mockito.spy;
23 import static org.mockito.Mockito.times;
24 import static org.mockito.Mockito.verify;
25 import static org.mockito.Mockito.when;
26 
27 import android.app.Activity;
28 import android.app.ApplicationPackageManager;
29 import android.app.LocaleConfig;
30 import android.content.Context;
31 import android.content.Intent;
32 import android.content.pm.ApplicationInfo;
33 import android.content.pm.InstallSourceInfo;
34 import android.content.pm.PackageInfo;
35 import android.content.pm.ResolveInfo;
36 import android.content.res.Resources;
37 import android.net.Uri;
38 import android.os.LocaleList;
39 import android.os.Process;
40 import android.os.UserHandle;
41 import android.telephony.TelephonyManager;
42 
43 import androidx.annotation.ArrayRes;
44 
45 import com.android.internal.app.LocaleStore;
46 import com.android.settings.applications.AppInfoBase;
47 import com.android.settings.applications.AppLocaleUtil;
48 
49 import org.junit.After;
50 import org.junit.Before;
51 import org.junit.Rule;
52 import org.junit.Test;
53 import org.junit.runner.RunWith;
54 import org.mockito.Mock;
55 import org.mockito.junit.MockitoJUnit;
56 import org.mockito.junit.MockitoRule;
57 import org.robolectric.Robolectric;
58 import org.robolectric.RobolectricTestRunner;
59 import org.robolectric.RuntimeEnvironment;
60 import org.robolectric.Shadows;
61 import org.robolectric.android.controller.ActivityController;
62 import org.robolectric.annotation.Config;
63 import org.robolectric.annotation.Implementation;
64 import org.robolectric.annotation.Implements;
65 import org.robolectric.shadows.ShadowPackageManager;
66 import org.robolectric.shadows.ShadowTelephonyManager;
67 import org.robolectric.util.ReflectionHelpers;
68 
69 import java.util.ArrayList;
70 import java.util.List;
71 import java.util.Locale;
72 
73 @RunWith(RobolectricTestRunner.class)
74 @Config(
75         shadows = {
76                 AppLocalePickerActivityTest.ShadowApplicationPackageManager.class,
77                 AppLocalePickerActivityTest.ShadowResources.class,
78         })
79 public class AppLocalePickerActivityTest {
80     private static final String TEST_PACKAGE_NAME = "com.android.settings";
81     private static final Uri TEST_PACKAGE_URI = Uri.parse("package:" + TEST_PACKAGE_NAME);
82 
83     @Mock
84     LocaleStore.LocaleInfo mLocaleInfo;
85     @Mock
86     private LocaleConfig mLocaleConfig;
87 
88     @Rule
89     public MockitoRule rule = MockitoJUnit.rule();
90 
91     private Context mContext;
92     private ShadowPackageManager mPackageManager;
93 
94     @Before
setUp()95     public void setUp() {
96         mContext = spy(RuntimeEnvironment.application);
97         mPackageManager = Shadows.shadowOf(mContext.getPackageManager());
98         mLocaleConfig = mock(LocaleConfig.class);
99         when(mLocaleConfig.getStatus()).thenReturn(LocaleConfig.STATUS_SUCCESS);
100         when(mLocaleConfig.getSupportedLocales()).thenReturn(LocaleList.forLanguageTags("en-US"));
101         ReflectionHelpers.setStaticField(AppLocaleUtil.class, "sLocaleConfig", mLocaleConfig);
102     }
103 
104     @After
tearDown()105     public void tearDown() {
106         mPackageManager.removePackage(TEST_PACKAGE_NAME);
107         ReflectionHelpers.setStaticField(AppLocaleUtil.class, "sLocaleConfig", null);
108         ShadowResources.setDisAllowPackage(false);
109         ShadowApplicationPackageManager.setNoLaunchEntry(false);
110     }
111 
112     @Test
launchAppLocalePickerActivity_hasPackageName_success()113     public void launchAppLocalePickerActivity_hasPackageName_success() {
114         ActivityController<TestAppLocalePickerActivity> controller =
115                 initActivityController(true);
116         controller.create();
117 
118         assertThat(controller.get().isFinishing()).isFalse();
119     }
120 
121     @Test
launchAppLocalePickerActivity_appNoLocaleConfig_failed()122     public void launchAppLocalePickerActivity_appNoLocaleConfig_failed() {
123         when(mLocaleConfig.getStatus()).thenReturn(LocaleConfig.STATUS_NOT_SPECIFIED);
124 
125         ActivityController<TestAppLocalePickerActivity> controller =
126                 initActivityController(true);
127         controller.create();
128 
129         assertThat(controller.get().isFinishing()).isTrue();
130     }
131 
132     @Test
launchAppLocalePickerActivity_appSignPlatformKey_failed()133     public void launchAppLocalePickerActivity_appSignPlatformKey_failed() {
134         final ApplicationInfo applicationInfo = new ApplicationInfo();
135         applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY;
136         applicationInfo.packageName = TEST_PACKAGE_NAME;
137 
138         final PackageInfo packageInfo = new PackageInfo();
139         packageInfo.packageName = TEST_PACKAGE_NAME;
140         packageInfo.applicationInfo = applicationInfo;
141         mPackageManager.installPackage(packageInfo);
142 
143         ActivityController<TestAppLocalePickerActivity> controller =
144                 initActivityController(true);
145         controller.create();
146 
147         assertThat(controller.get().isFinishing()).isTrue();
148     }
149 
150     @Test
launchAppLocalePickerActivity_appMatchDisallowedPackage_failed()151     public void launchAppLocalePickerActivity_appMatchDisallowedPackage_failed() {
152         ShadowResources.setDisAllowPackage(true);
153 
154         ActivityController<TestAppLocalePickerActivity> controller =
155                 initActivityController(true);
156         controller.create();
157 
158         assertThat(controller.get().isFinishing()).isTrue();
159     }
160 
161     @Test
launchAppLocalePickerActivity_appNoLaunchEntry_failed()162     public void launchAppLocalePickerActivity_appNoLaunchEntry_failed() {
163         ShadowApplicationPackageManager.setNoLaunchEntry(true);
164 
165         ActivityController<TestAppLocalePickerActivity> controller =
166                 initActivityController(true);
167         controller.create();
168 
169         assertThat(controller.get().isFinishing()).isTrue();
170     }
171 
172     @Test
launchAppLocalePickerActivity_intentWithoutPackageName_failed()173     public void launchAppLocalePickerActivity_intentWithoutPackageName_failed() {
174         ActivityController<TestAppLocalePickerActivity> controller =
175                 initActivityController(false);
176         controller.create();
177 
178         assertThat(controller.get().isFinishing()).isTrue();
179     }
180 
181     @Test
onLocaleSelected_getLocaleNotNull_getLanguageTag()182     public void onLocaleSelected_getLocaleNotNull_getLanguageTag() {
183         ActivityController<TestAppLocalePickerActivity> controller =
184                 initActivityController(true);
185         Locale locale = new Locale("en", "US");
186         when(mLocaleInfo.getLocale()).thenReturn(locale);
187         when(mLocaleInfo.isSystemLocale()).thenReturn(false);
188 
189         controller.create();
190         AppLocalePickerActivity mActivity = controller.get();
191         mActivity.onLocaleSelected(mLocaleInfo);
192 
193         verify(mLocaleInfo, times(2)).getLocale();
194         assertThat(mLocaleInfo.getLocale().toLanguageTag()).isEqualTo("en-US");
195         assertThat(controller.get().isFinishing()).isTrue();
196     }
197 
198     @Test
onLocaleSelected_getLocaleNull_getEmptyLanguageTag()199     public void onLocaleSelected_getLocaleNull_getEmptyLanguageTag() {
200         ActivityController<TestAppLocalePickerActivity> controller =
201                 initActivityController(true);
202         when(mLocaleInfo.getLocale()).thenReturn(null);
203         when(mLocaleInfo.isSystemLocale()).thenReturn(false);
204 
205         controller.create();
206         AppLocalePickerActivity mActivity = controller.get();
207         mActivity.onLocaleSelected(mLocaleInfo);
208 
209         verify(mLocaleInfo, times(1)).getLocale();
210         assertThat(controller.get().isFinishing()).isTrue();
211     }
212 
initActivityController( boolean hasPackageName)213     private ActivityController<TestAppLocalePickerActivity> initActivityController(
214             boolean hasPackageName) {
215         Intent data = new Intent();
216         if (hasPackageName) {
217             data.setData(TEST_PACKAGE_URI);
218         }
219         data.putExtra(AppInfoBase.ARG_PACKAGE_UID, Process.myUid());
220         ActivityController<TestAppLocalePickerActivity> activityController =
221                 Robolectric.buildActivity(TestAppLocalePickerActivity.class, data);
222         Activity activity = activityController.get();
223 
224         ShadowTelephonyManager shadowTelephonyManager = Shadows.shadowOf(
225                 activity.getSystemService(TelephonyManager.class));
226         shadowTelephonyManager.setSimCountryIso("US");
227         shadowTelephonyManager.setNetworkCountryIso("US");
228 
229         return activityController;
230     }
231 
232     private static class TestAppLocalePickerActivity extends AppLocalePickerActivity {
233         @Override
createContextAsUser(UserHandle user, int flags)234         public Context createContextAsUser(UserHandle user, int flags) {
235             // return the current context as a work profile
236             return this;
237         }
238     }
239 
240     @Implements(ApplicationPackageManager.class)
241     public static class ShadowApplicationPackageManager extends
242             org.robolectric.shadows.ShadowApplicationPackageManager {
243         private static boolean sNoLaunchEntry = false;
244 
245         @Implementation
getInstallSourceInfo(String packageName)246         protected Object getInstallSourceInfo(String packageName) {
247             return new InstallSourceInfo("", null, null, "");
248         }
249 
250         @Implementation
queryIntentActivities(Intent intent, int flags)251         protected List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
252             if (sNoLaunchEntry) {
253                 return new ArrayList();
254             } else {
255                 return super.queryIntentActivities(intent, flags);
256             }
257         }
258 
setNoLaunchEntry(boolean noLaunchEntry)259         private static void setNoLaunchEntry(boolean noLaunchEntry) {
260             sNoLaunchEntry = noLaunchEntry;
261         }
262     }
263 
264     @Implements(Resources.class)
265     public static class ShadowResources extends
266             org.robolectric.shadows.ShadowResources {
267         private static boolean sDisAllowPackage = false;
268 
269         @Implementation
getStringArray(@rrayRes int id)270         public String[] getStringArray(@ArrayRes int id) {
271             if (sDisAllowPackage) {
272                 return new String[]{TEST_PACKAGE_NAME};
273             } else {
274                 return new String[0];
275             }
276         }
277 
setDisAllowPackage(boolean disAllowPackage)278         private static void setDisAllowPackage(boolean disAllowPackage) {
279             sDisAllowPackage = disAllowPackage;
280         }
281     }
282 }
283