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 20 import static org.mockito.ArgumentMatchers.any; 21 import static org.mockito.ArgumentMatchers.anyInt; 22 import static org.mockito.Mockito.doNothing; 23 import static org.mockito.Mockito.never; 24 import static org.mockito.Mockito.spy; 25 import static org.mockito.Mockito.verify; 26 import static org.mockito.Mockito.when; 27 28 import android.content.Context; 29 import android.content.Intent; 30 import android.content.pm.ActivityInfo; 31 import android.content.pm.ApplicationInfo; 32 import android.content.pm.PackageManager; 33 import android.content.pm.PackageManager.NameNotFoundException; 34 import android.content.pm.ResolveInfo; 35 import android.content.res.Resources; 36 import android.location.LocationManager; 37 import android.os.Bundle; 38 39 import androidx.preference.Preference; 40 import androidx.preference.PreferenceCategory; 41 42 import org.junit.Before; 43 import org.junit.Test; 44 import org.junit.runner.RunWith; 45 import org.mockito.ArgumentCaptor; 46 import org.mockito.Mock; 47 import org.mockito.MockitoAnnotations; 48 import org.robolectric.RobolectricTestRunner; 49 import org.robolectric.RuntimeEnvironment; 50 51 import java.util.ArrayList; 52 import java.util.List; 53 54 @RunWith(RobolectricTestRunner.class) 55 public class LocationFooterPreferenceControllerTest { 56 57 @Mock 58 private PreferenceCategory mPreferenceCategory; 59 @Mock 60 private PackageManager mPackageManager; 61 @Mock 62 private Resources mResources; 63 private LocationFooterPreferenceController mController; 64 private static final int TEST_RES_ID = 1234; 65 private static final String TEST_TEXT = "text"; 66 67 @Before setUp()68 public void setUp() throws NameNotFoundException { 69 MockitoAnnotations.initMocks(this); 70 Context context = spy(RuntimeEnvironment.application); 71 when(context.getPackageManager()).thenReturn(mPackageManager); 72 when(mPreferenceCategory.getContext()).thenReturn(context); 73 mController = spy(new LocationFooterPreferenceController(context, "key")); 74 when(mPackageManager.getResourcesForApplication(any(ApplicationInfo.class))) 75 .thenReturn(mResources); 76 when(mResources.getString(TEST_RES_ID)).thenReturn(TEST_TEXT); 77 doNothing().when(mPreferenceCategory).removeAll(); 78 } 79 80 @Test isAvailable_hasValidFooter_returnsTrue()81 public void isAvailable_hasValidFooter_returnsTrue() { 82 final List<ResolveInfo> testResolveInfos = new ArrayList<>(); 83 testResolveInfos.add( 84 getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true)); 85 when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt())) 86 .thenReturn(testResolveInfos); 87 88 assertThat(mController.isAvailable()).isTrue(); 89 } 90 91 @Test isAvailable_noSystemApp_returnsFalse()92 public void isAvailable_noSystemApp_returnsFalse() { 93 final List<ResolveInfo> testResolveInfos = new ArrayList<>(); 94 testResolveInfos.add( 95 getTestResolveInfo(/*isSystemApp*/ false, /*hasRequiredMetadata*/ true)); 96 when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt())) 97 .thenReturn(testResolveInfos); 98 assertThat(mController.isAvailable()).isFalse(); 99 } 100 101 @Test isAvailable_noRequiredMetadata_returnsFalse()102 public void isAvailable_noRequiredMetadata_returnsFalse() { 103 final List<ResolveInfo> testResolveInfos = new ArrayList<>(); 104 testResolveInfos.add( 105 getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ false)); 106 when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt())) 107 .thenReturn(testResolveInfos); 108 assertThat(mController.isAvailable()).isFalse(); 109 } 110 111 @Test updateState_addPreferences()112 public void updateState_addPreferences() { 113 final List<ResolveInfo> testResolveInfos = new ArrayList<>(); 114 testResolveInfos.add( 115 getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true)); 116 when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt())) 117 .thenReturn(testResolveInfos); 118 mController.updateState(mPreferenceCategory); 119 ArgumentCaptor<Preference> pref = ArgumentCaptor.forClass(Preference.class); 120 verify(mPreferenceCategory).addPreference(pref.capture()); 121 assertThat(pref.getValue().getTitle()).isEqualTo(TEST_TEXT); 122 } 123 124 @Test updateState_notSystemApp_ignore()125 public void updateState_notSystemApp_ignore() { 126 final List<ResolveInfo> testResolveInfos = new ArrayList<>(); 127 testResolveInfos.add( 128 getTestResolveInfo(/*isSystemApp*/ false, /*hasRequiredMetadata*/ true)); 129 when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt())) 130 .thenReturn(testResolveInfos); 131 mController.updateState(mPreferenceCategory); 132 verify(mPreferenceCategory, never()).addPreference(any(Preference.class)); 133 } 134 135 /** 136 * Returns a ResolveInfo object for testing 137 * @param isSystemApp If true, the application is a system app. 138 * @param hasRequiredMetaData If true, the broadcast receiver has a valid value for 139 * {@link LocationManager#METADATA_SETTINGS_FOOTER_STRING} 140 */ getTestResolveInfo(boolean isSystemApp, boolean hasRequiredMetaData)141 private ResolveInfo getTestResolveInfo(boolean isSystemApp, boolean hasRequiredMetaData) { 142 ResolveInfo testResolveInfo = new ResolveInfo(); 143 ApplicationInfo testAppInfo = new ApplicationInfo(); 144 if (isSystemApp) { 145 testAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM; 146 } 147 ActivityInfo testActivityInfo = new ActivityInfo(); 148 testActivityInfo.name = "TestActivityName"; 149 testActivityInfo.packageName = "TestPackageName"; 150 testActivityInfo.applicationInfo = testAppInfo; 151 if (hasRequiredMetaData) { 152 testActivityInfo.metaData = new Bundle(); 153 testActivityInfo.metaData.putInt( 154 LocationManager.METADATA_SETTINGS_FOOTER_STRING, TEST_RES_ID); 155 } 156 testResolveInfo.activityInfo = testActivityInfo; 157 return testResolveInfo; 158 } 159 } 160