1 /* 2 * Copyright (C) 2019 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.Mockito.doNothing; 21 import static org.mockito.Mockito.doReturn; 22 import static org.mockito.Mockito.spy; 23 import static org.mockito.Mockito.verify; 24 import static org.mockito.Mockito.when; 25 26 import android.content.Context; 27 import android.content.Intent; 28 import android.location.LocationManager; 29 import android.os.UserHandle; 30 import android.provider.Settings; 31 import android.view.LayoutInflater; 32 import android.view.View; 33 import android.widget.TextView; 34 35 import androidx.preference.PreferenceCategory; 36 import androidx.preference.PreferenceScreen; 37 38 import com.android.settings.R; 39 import com.android.settings.dashboard.DashboardFragment; 40 import com.android.settings.testutils.shadow.ShadowDeviceConfig; 41 import com.android.settingslib.applications.RecentAppOpsAccess; 42 43 import com.google.common.collect.ImmutableList; 44 45 import org.junit.After; 46 import org.junit.Before; 47 import org.junit.Ignore; 48 import org.junit.Test; 49 import org.junit.runner.RunWith; 50 import org.mockito.Mock; 51 import org.mockito.Mockito; 52 import org.mockito.MockitoAnnotations; 53 import org.robolectric.RobolectricTestRunner; 54 import org.robolectric.RuntimeEnvironment; 55 import org.robolectric.annotation.Config; 56 57 import java.util.ArrayList; 58 59 @RunWith(RobolectricTestRunner.class) 60 @Config(shadows = {ShadowDeviceConfig.class}) 61 public class RecentLocationAccessPreferenceControllerTest { 62 private static final String PREFERENCE_KEY = "test_preference_key"; 63 @Mock 64 private PreferenceCategory mLayoutPreference; 65 @Mock 66 private PreferenceScreen mScreen; 67 @Mock 68 private DashboardFragment mDashboardFragment; 69 @Mock 70 private RecentAppOpsAccess mRecentLocationApps; 71 @Mock 72 private LocationManager mLocationManager; 73 private Context mContext; 74 private RecentLocationAccessPreferenceController mController; 75 private View mAppEntitiesHeaderView; 76 77 @Before setUp()78 public void setUp() { 79 MockitoAnnotations.initMocks(this); 80 mContext = spy(RuntimeEnvironment.application); 81 mController = spy( 82 new RecentLocationAccessPreferenceController(mContext, PREFERENCE_KEY, 83 mRecentLocationApps)); 84 mController.init(mDashboardFragment); 85 final String key = mController.getPreferenceKey(); 86 mAppEntitiesHeaderView = LayoutInflater.from(mContext).inflate( 87 com.android.settingslib.widget.entityheader.R.layout.app_entities_header, null /* root */); 88 when(mScreen.findPreference(key)).thenReturn(mLayoutPreference); 89 when(mLayoutPreference.getKey()).thenReturn(key); 90 when(mLayoutPreference.getContext()).thenReturn(mContext); 91 when(mDashboardFragment.getContext()).thenReturn(mContext); 92 } 93 94 @After tearDown()95 public void tearDown() { 96 ShadowDeviceConfig.reset(); 97 } 98 99 @Test isAvailable_shouldReturnTrue()100 public void isAvailable_shouldReturnTrue() { 101 assertThat(mController.isAvailable()).isEqualTo(true); 102 } 103 104 /** Verifies the title text, details text are correct, and the click listener is set. */ 105 @Test 106 @Ignore updateState_whenAppListIsEmpty_shouldDisplayTitleTextAndDetailsText()107 public void updateState_whenAppListIsEmpty_shouldDisplayTitleTextAndDetailsText() { 108 doReturn(new ArrayList<>()).when(mRecentLocationApps).getAppListSorted(false); 109 mController.displayPreference(mScreen); 110 mController.updateState(mLayoutPreference); 111 112 final TextView title = mAppEntitiesHeaderView.findViewById(R.id.header_title); 113 assertThat(title.getText()).isEqualTo( 114 mContext.getText(R.string.location_category_recent_location_access)); 115 final TextView details = mAppEntitiesHeaderView 116 .findViewById(com.android.settingslib.widget.entityheader.R.id.header_details); 117 assertThat(details.getText()).isEqualTo( 118 mContext.getText(R.string.location_recent_location_access_view_details)); 119 assertThat(details.hasOnClickListeners()).isTrue(); 120 } 121 122 /** Verifies the title text, details text are correct, and the click listener is set. */ 123 @Test updateState_showSystemAccess()124 public void updateState_showSystemAccess() { 125 doReturn(ImmutableList.of( 126 new RecentAppOpsAccess.Access("app", UserHandle.CURRENT, null, "app", "", 0))) 127 .when(mRecentLocationApps).getAppListSorted(false); 128 doReturn(new ArrayList<>()).when(mRecentLocationApps).getAppListSorted(true); 129 mController.displayPreference(mScreen); 130 mController.updateState(mLayoutPreference); 131 verify(mLayoutPreference).addPreference(Mockito.any()); 132 133 Settings.Secure.putInt( 134 mContext.getContentResolver(), Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 1); 135 verify(mLayoutPreference, Mockito.times(1)).addPreference(Mockito.any()); 136 } 137 138 @Test testPreferenceClick_onExtraLocationPackage_startsExtraLocationActivity()139 public void testPreferenceClick_onExtraLocationPackage_startsExtraLocationActivity() { 140 String extraLocationPkgName = "extraLocationPkgName"; 141 when(mContext.getSystemService(LocationManager.class)).thenReturn(mLocationManager); 142 when(mLocationManager.getExtraLocationControllerPackage()).thenReturn(extraLocationPkgName); 143 RecentLocationAccessPreferenceController.PackageEntryClickedListener listener = 144 new RecentLocationAccessPreferenceController.PackageEntryClickedListener( 145 mContext, extraLocationPkgName, UserHandle.CURRENT); 146 doNothing().when(mContext).startActivityAsUser(Mockito.refEq(new Intent( 147 Settings.ACTION_LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS)), 148 Mockito.eq(UserHandle.CURRENT)); 149 150 listener.onPreferenceClick(mLayoutPreference); 151 152 verify(mContext).startActivityAsUser(Mockito.refEq(new Intent( 153 Settings.ACTION_LOCATION_CONTROLLER_EXTRA_PACKAGE_SETTINGS)), 154 Mockito.eq(UserHandle.CURRENT)); 155 } 156 } 157