• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 package com.android.settings.location;
17 
18 import static com.google.common.truth.Truth.assertThat;
19 import static org.mockito.Matchers.any;
20 import static org.mockito.Matchers.anyInt;
21 import static org.mockito.Mockito.doNothing;
22 import static org.mockito.Mockito.never;
23 import static org.mockito.Mockito.spy;
24 import static org.mockito.Mockito.times;
25 import static org.mockito.Mockito.verify;
26 import static org.mockito.Mockito.when;
27 
28 import android.arch.lifecycle.LifecycleOwner;
29 import android.content.ComponentName;
30 import android.content.Context;
31 import android.content.Intent;
32 import android.content.pm.ActivityInfo;
33 import android.content.pm.ApplicationInfo;
34 import android.content.pm.PackageManager;
35 import android.content.pm.PackageManager.NameNotFoundException;
36 import android.content.pm.ResolveInfo;
37 import android.content.res.Resources;
38 import android.location.LocationManager;
39 import android.os.Bundle;
40 import android.support.v7.preference.Preference;
41 import android.support.v7.preference.PreferenceCategory;
42 
43 import com.android.settings.testutils.SettingsRobolectricTestRunner;
44 import com.android.settingslib.core.lifecycle.Lifecycle;
45 
46 import org.junit.Before;
47 import org.junit.Test;
48 import org.junit.runner.RunWith;
49 import org.mockito.ArgumentCaptor;
50 import org.mockito.Mock;
51 import org.mockito.MockitoAnnotations;
52 import org.robolectric.RuntimeEnvironment;
53 
54 import java.util.ArrayList;
55 import java.util.List;
56 
57 @RunWith(SettingsRobolectricTestRunner.class)
58 public class LocationFooterPreferenceControllerTest {
59 
60     @Mock
61     private PreferenceCategory mPreferenceCategory;
62     @Mock
63     private PackageManager mPackageManager;
64     @Mock
65     private Resources mResources;
66     private Context mContext;
67     private LocationFooterPreferenceController mController;
68     private LifecycleOwner mLifecycleOwner;
69     private Lifecycle mLifecycle;
70     private static final int TEST_RES_ID = 1234;
71     private static final String TEST_TEXT = "text";
72 
73     @Before
setUp()74     public void setUp() throws NameNotFoundException {
75         MockitoAnnotations.initMocks(this);
76         mContext = spy(RuntimeEnvironment.application);
77         when(mContext.getPackageManager()).thenReturn(mPackageManager);
78         mLifecycleOwner = () -> mLifecycle;
79         mLifecycle = new Lifecycle(mLifecycleOwner);
80         when(mPreferenceCategory.getContext()).thenReturn(mContext);
81         mController = spy(new LocationFooterPreferenceController(mContext, mLifecycle));
82         when(mPackageManager.getResourcesForApplication(any(ApplicationInfo.class)))
83                 .thenReturn(mResources);
84         when(mResources.getString(TEST_RES_ID)).thenReturn(TEST_TEXT);
85         doNothing().when(mPreferenceCategory).removeAll();
86     }
87 
88     @Test
isAvailable_hasValidFooter_returnsTrue()89     public void isAvailable_hasValidFooter_returnsTrue() throws NameNotFoundException {
90         final List<ResolveInfo> testResolveInfos = new ArrayList<>();
91         testResolveInfos.add(
92                 getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true));
93         when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
94                 .thenReturn(testResolveInfos);
95 
96         assertThat(mController.isAvailable()).isTrue();
97     }
98 
99     @Test
isAvailable_noSystemApp_returnsFalse()100     public void isAvailable_noSystemApp_returnsFalse() throws NameNotFoundException {
101         final List<ResolveInfo> testResolveInfos = new ArrayList<>();
102         testResolveInfos.add(
103                 getTestResolveInfo(/*isSystemApp*/ false, /*hasRequiredMetadata*/ true));
104         when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
105                 .thenReturn(testResolveInfos);
106         assertThat(mController.isAvailable()).isFalse();
107     }
108 
109     @Test
isAvailable_noRequiredMetadata_returnsFalse()110     public void isAvailable_noRequiredMetadata_returnsFalse() throws NameNotFoundException {
111         final List<ResolveInfo> testResolveInfos = new ArrayList<>();
112         testResolveInfos.add(
113                 getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ false));
114         when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
115                 .thenReturn(testResolveInfos);
116         assertThat(mController.isAvailable()).isFalse();
117     }
118 
119     @Test
sendBroadcastFooterInject()120     public void sendBroadcastFooterInject() {
121         ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
122         final ActivityInfo activityInfo =
123                 getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true).activityInfo;
124         mController.sendBroadcastFooterDisplayed(
125                 new ComponentName(activityInfo.packageName, activityInfo.name));
126         verify(mContext).sendBroadcast(intent.capture());
127         assertThat(intent.getValue().getAction())
128                 .isEqualTo(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
129     }
130 
131     @Test
updateState_sendBroadcast()132     public void updateState_sendBroadcast() throws NameNotFoundException {
133         final List<ResolveInfo> testResolveInfos = new ArrayList<>();
134         testResolveInfos.add(
135                 getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true));
136         when(mPackageManager.queryBroadcastReceivers(any(), anyInt()))
137                 .thenReturn(testResolveInfos);
138         mController.updateState(mPreferenceCategory);
139         ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
140         verify(mContext).sendBroadcast(intent.capture());
141         assertThat(intent.getValue().getAction())
142                 .isEqualTo(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
143     }
144 
145     @Test
updateState_addPreferences()146     public void updateState_addPreferences() throws NameNotFoundException {
147         final List<ResolveInfo> testResolveInfos = new ArrayList<>();
148         testResolveInfos.add(
149                 getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true));
150         when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
151                 .thenReturn(testResolveInfos);
152         mController.updateState(mPreferenceCategory);
153         ArgumentCaptor<Preference> pref = ArgumentCaptor.forClass(Preference.class);
154         verify(mPreferenceCategory).addPreference(pref.capture());
155         assertThat(pref.getValue().getTitle()).isEqualTo(TEST_TEXT);
156     }
157 
158     @Test
updateState_notSystemApp_ignore()159     public void updateState_notSystemApp_ignore() throws NameNotFoundException {
160         final List<ResolveInfo> testResolveInfos = new ArrayList<>();
161         testResolveInfos.add(
162                 getTestResolveInfo(/*isSystemApp*/ false, /*hasRequiredMetadata*/ true));
163         when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
164                 .thenReturn(testResolveInfos);
165         mController.updateState(mPreferenceCategory);
166         verify(mPreferenceCategory, never()).addPreference(any(Preference.class));
167         verify(mContext, never()).sendBroadcast(any(Intent.class));
168     }
169 
170     @Test
updateState_thenOnPause_sendBroadcasts()171     public void updateState_thenOnPause_sendBroadcasts() throws NameNotFoundException {
172         final List<ResolveInfo> testResolveInfos = new ArrayList<>();
173         testResolveInfos.add(
174                 getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true));
175         when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
176                 .thenReturn(testResolveInfos);
177         mController.updateState(mPreferenceCategory);
178         ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
179         verify(mContext).sendBroadcast(intent.capture());
180         assertThat(intent.getValue().getAction())
181                 .isEqualTo(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
182 
183         mController.onPause();
184         verify(mContext, times(2)).sendBroadcast(intent.capture());
185         assertThat(intent.getValue().getAction())
186                 .isEqualTo(LocationManager.SETTINGS_FOOTER_REMOVED_ACTION);
187     }
188 
189     @Test
onPause_doNotSendBroadcast()190     public void onPause_doNotSendBroadcast() {
191         mController.onPause();
192         verify(mContext, never()).sendBroadcast(any(Intent.class));
193     }
194 
195     /**
196      * Returns a ResolveInfo object for testing
197      * @param isSystemApp If true, the application is a system app.
198      * @param hasRequiredMetaData If true, the broadcast receiver has a valid value for
199      *                            {@link LocationManager#METADATA_SETTINGS_FOOTER_STRING}
200      */
getTestResolveInfo(boolean isSystemApp, boolean hasRequiredMetaData)201     private ResolveInfo getTestResolveInfo(boolean isSystemApp, boolean hasRequiredMetaData) {
202         ResolveInfo testResolveInfo = new ResolveInfo();
203         ApplicationInfo testAppInfo = new ApplicationInfo();
204         if (isSystemApp) {
205             testAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
206         }
207         ActivityInfo testActivityInfo = new ActivityInfo();
208         testActivityInfo.name = "TestActivityName";
209         testActivityInfo.packageName = "TestPackageName";
210         testActivityInfo.applicationInfo = testAppInfo;
211         if (hasRequiredMetaData) {
212             testActivityInfo.metaData = new Bundle();
213             testActivityInfo.metaData.putInt(
214                     LocationManager.METADATA_SETTINGS_FOOTER_STRING, TEST_RES_ID);
215         }
216         testResolveInfo.activityInfo = testActivityInfo;
217         return testResolveInfo;
218     }
219 }
220