From 811d95c373f94c0aef9795634fa9de2283465165 Mon Sep 17 00:00:00 2001 From: Lifu Tang Date: Mon, 10 Dec 2018 16:38:33 -0800 Subject: [PATCH] Display recent location access in the widget Bug: 120239674 Test: manually Change-Id: Iaf899486bf27c55189eea4c0e913ff1baaf529e5 --- res/values/strings.xml | 10 +- res/xml/location_recent_requests_see_all.xml | 24 -- res/xml/location_settings.xml | 20 +- .../settings/location/LocationSettings.java | 10 +- ...entLocationAccessPreferenceController.java | 103 +++++++++ ...ntLocationRequestPreferenceController.java | 155 ------------- .../RecentLocationRequestSeeAllFragment.java | 93 -------- ...tionRequestSeeAllPreferenceController.java | 98 -------- ...cationRequestPreferenceControllerTest.java | 217 ------------------ ...RequestSeeAllPreferenceControllerTest.java | 126 ---------- 10 files changed, 117 insertions(+), 739 deletions(-) delete mode 100644 res/xml/location_recent_requests_see_all.xml create mode 100644 src/com/android/settings/location/RecentLocationAccessPreferenceController.java delete mode 100644 src/com/android/settings/location/RecentLocationRequestPreferenceController.java delete mode 100644 src/com/android/settings/location/RecentLocationRequestSeeAllFragment.java delete mode 100644 src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceController.java delete mode 100644 tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java delete mode 100644 tests/robotests/src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceControllerTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 57897dc0ffe..4abea447d9f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3631,14 +3631,12 @@ App-level permissions - - Recent location requests - - See all + + Recent location access + + View details No apps have requested location recently - - Location services High battery use diff --git a/res/xml/location_recent_requests_see_all.xml b/res/xml/location_recent_requests_see_all.xml deleted file mode 100644 index 38db1426995..00000000000 --- a/res/xml/location_recent_requests_see_all.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/res/xml/location_settings.xml b/res/xml/location_settings.xml index b53e9861642..f1c13cf6ecd 100644 --- a/res/xml/location_settings.xml +++ b/res/xml/location_settings.xml @@ -20,21 +20,14 @@ android:title="@string/location_settings_title" settings:keywords="@string/keywords_location"> - - - + + settings:initialExpandedChildrenCount="0"> + android:key="location_services" /> In switch bar: location master switch. Used to toggle location on and off. * * - *
  • Recent location requests: automatically populated by {@link RecentLocationApps}
  • + *
  • Recent location requests: automatically populated by {@link RecentLocationAccesses}
  • *
  • Location services: multi-app settings provided from outside the Android framework. Each * is injected by a system-partition app via the {@link SettingInjectorService} API.
  • * @@ -124,11 +124,9 @@ public class LocationSettings extends DashboardFragment { final List controllers = new ArrayList<>(); controllers.add(new AppLocationPermissionPreferenceController(context)); controllers.add(new LocationForWorkPreferenceController(context, lifecycle)); - controllers.add( - new RecentLocationRequestPreferenceController(context, fragment, lifecycle)); + controllers.add(new RecentLocationAccessPreferenceController(context)); controllers.add(new LocationScanningPreferenceController(context)); - controllers.add( - new LocationServicePreferenceController(context, fragment, lifecycle)); + controllers.add(new LocationServicePreferenceController(context, fragment, lifecycle)); controllers.add(new LocationFooterPreferenceController(context, lifecycle)); return controllers; } diff --git a/src/com/android/settings/location/RecentLocationAccessPreferenceController.java b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java new file mode 100644 index 00000000000..0d5cca50f99 --- /dev/null +++ b/src/com/android/settings/location/RecentLocationAccessPreferenceController.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package com.android.settings.location; + +import android.Manifest; +import android.content.Context; +import android.content.Intent; +import android.view.View; + +import androidx.annotation.VisibleForTesting; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.location.RecentLocationAccesses; +import com.android.settingslib.widget.AppEntitiesHeaderController; +import com.android.settingslib.widget.LayoutPreference; + +import java.util.List; + +public class RecentLocationAccessPreferenceController extends AbstractPreferenceController + implements PreferenceControllerMixin { + /** Key for the recent location apps dashboard */ + private static final String KEY_APPS_DASHBOARD = "apps_dashboard"; + private final RecentLocationAccesses mRecentLocationAccesses; + private AppEntitiesHeaderController mController; + private static final int MAXIMUM_APP_COUNT = 3; + + public RecentLocationAccessPreferenceController(Context context) { + this(context, new RecentLocationAccesses(context)); + } + + @VisibleForTesting + RecentLocationAccessPreferenceController(Context context, + RecentLocationAccesses recentAccesses) { + super(context); + mRecentLocationAccesses = recentAccesses; + } + + @Override + public String getPreferenceKey() { + return KEY_APPS_DASHBOARD; + } + + @Override + public boolean isAvailable() { + return true; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + final LayoutPreference preference = (LayoutPreference) screen.findPreference( + KEY_APPS_DASHBOARD); + final View view = preference.findViewById(R.id.app_entities_header); + mController = AppEntitiesHeaderController.newInstance(mContext, view) + .setHeaderTitleRes(R.string.location_category_recent_location_access) + .setHeaderDetailsRes(R.string.location_recent_location_access_view_details) + .setHeaderDetailsClickListener((View v) -> { + final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE); + intent.putExtra(Intent.EXTRA_PERMISSION_NAME, + Manifest.permission.ACCESS_FINE_LOCATION); + mContext.startActivity(intent); + }); + } + + @Override + public void updateState(Preference preference) { + updateRecentApps(); + } + + private void updateRecentApps() { + final List recentLocationAccesses = + mRecentLocationAccesses.getAppListSorted(); + if (recentLocationAccesses.size() > 0) { + // Display the top 3 preferences to container in original order. + int i = 0; + for (; i < Math.min(recentLocationAccesses.size(), MAXIMUM_APP_COUNT); i++) { + final RecentLocationAccesses.Access access = recentLocationAccesses.get(i); + mController.setAppEntity(i, access.icon, access.label, access.contentDescription); + } + for (; i < MAXIMUM_APP_COUNT; i++) { + mController.removeAppEntity(i); + } + } else { + // If there's no item to display, add a "No recent apps" item. + } + mController.apply(); + } +} diff --git a/src/com/android/settings/location/RecentLocationRequestPreferenceController.java b/src/com/android/settings/location/RecentLocationRequestPreferenceController.java deleted file mode 100644 index 60374eb5dda..00000000000 --- a/src/com/android/settings/location/RecentLocationRequestPreferenceController.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the - * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ -package com.android.settings.location; - -import android.content.Context; -import android.os.Bundle; -import android.os.UserHandle; - -import androidx.annotation.VisibleForTesting; -import androidx.preference.Preference; -import androidx.preference.PreferenceCategory; -import androidx.preference.PreferenceScreen; - -import com.android.settings.R; -import com.android.settings.applications.appinfo.AppInfoDashboardFragment; -import com.android.settings.core.SubSettingLauncher; -import com.android.settings.dashboard.DashboardFragment; -import com.android.settingslib.core.lifecycle.Lifecycle; -import com.android.settingslib.location.RecentLocationApps; -import com.android.settingslib.widget.apppreference.AppPreference; - -import java.util.List; - -public class RecentLocationRequestPreferenceController extends LocationBasePreferenceController { - - /** Key for preference category "Recent location requests" */ - private static final String KEY_RECENT_LOCATION_REQUESTS = "recent_location_requests"; - @VisibleForTesting - static final String KEY_SEE_ALL_BUTTON = "recent_location_requests_see_all_button"; - private final LocationSettings mFragment; - private final RecentLocationApps mRecentLocationApps; - private PreferenceCategory mCategoryRecentLocationRequests; - private Preference mSeeAllButton; - - /** Used in this class and {@link RecentLocationRequestSeeAllPreferenceController} */ - static class PackageEntryClickedListener implements Preference.OnPreferenceClickListener { - private final DashboardFragment mFragment; - private final String mPackage; - private final UserHandle mUserHandle; - - public PackageEntryClickedListener(DashboardFragment fragment, String packageName, - UserHandle userHandle) { - mFragment = fragment; - mPackage = packageName; - mUserHandle = userHandle; - } - - @Override - public boolean onPreferenceClick(Preference preference) { - // start new fragment to display extended information - final Bundle args = new Bundle(); - args.putString(AppInfoDashboardFragment.ARG_PACKAGE_NAME, mPackage); - - new SubSettingLauncher(mFragment.getContext()) - .setDestination(AppInfoDashboardFragment.class.getName()) - .setArguments(args) - .setTitleRes(R.string.application_info_label) - .setUserHandle(mUserHandle) - .setSourceMetricsCategory(mFragment.getMetricsCategory()) - .launch(); - return true; - } - } - - public RecentLocationRequestPreferenceController(Context context, LocationSettings fragment, - Lifecycle lifecycle) { - this(context, fragment, lifecycle, new RecentLocationApps(context)); - } - - @VisibleForTesting - RecentLocationRequestPreferenceController(Context context, LocationSettings fragment, - Lifecycle lifecycle, RecentLocationApps recentApps) { - super(context, lifecycle); - mFragment = fragment; - mRecentLocationApps = recentApps; - } - - @Override - public String getPreferenceKey() { - return KEY_RECENT_LOCATION_REQUESTS; - } - - @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - mCategoryRecentLocationRequests = - (PreferenceCategory) screen.findPreference(KEY_RECENT_LOCATION_REQUESTS); - mSeeAllButton = screen.findPreference(KEY_SEE_ALL_BUTTON); - - } - - @Override - public void updateState(Preference preference) { - mCategoryRecentLocationRequests.removeAll(); - mSeeAllButton.setVisible(false); - - final Context prefContext = preference.getContext(); - final List recentLocationRequests = - mRecentLocationApps.getAppListSorted(); - - if (recentLocationRequests.size() > 3) { - // Display the top 3 preferences to container in original order. - for (int i = 0; i < 3; i++) { - mCategoryRecentLocationRequests.addPreference( - createAppPreference(prefContext, recentLocationRequests.get(i))); - } - // Display a button to list all requests - mSeeAllButton.setVisible(true); - } else if (recentLocationRequests.size() > 0) { - // Add preferences to container in original order (already sorted by recency). - for (RecentLocationApps.Request request : recentLocationRequests) { - mCategoryRecentLocationRequests.addPreference( - createAppPreference(prefContext, request)); - } - } else { - // If there's no item to display, add a "No recent apps" item. - final Preference banner = createAppPreference(prefContext); - banner.setTitle(R.string.location_no_recent_apps); - banner.setSelectable(false); - mCategoryRecentLocationRequests.addPreference(banner); - } - } - - @Override - public void onLocationModeChanged(int mode, boolean restricted) { - mCategoryRecentLocationRequests.setEnabled(mLocationEnabler.isEnabled(mode)); - } - - @VisibleForTesting - AppPreference createAppPreference(Context prefContext) { - return new AppPreference(prefContext); - } - - @VisibleForTesting - AppPreference createAppPreference(Context prefContext, RecentLocationApps.Request request) { - final AppPreference pref = createAppPreference(prefContext); - pref.setSummary(request.contentDescription); - pref.setIcon(request.icon); - pref.setTitle(request.label); - pref.setOnPreferenceClickListener(new PackageEntryClickedListener( - mFragment, request.packageName, request.userHandle)); - return pref; - } -} diff --git a/src/com/android/settings/location/RecentLocationRequestSeeAllFragment.java b/src/com/android/settings/location/RecentLocationRequestSeeAllFragment.java deleted file mode 100644 index d256b9b804e..00000000000 --- a/src/com/android/settings/location/RecentLocationRequestSeeAllFragment.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.location; - - -import android.content.Context; -import android.provider.SearchIndexableResource; - -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.settings.R; -import com.android.settings.dashboard.DashboardFragment; -import com.android.settings.search.BaseSearchIndexProvider; -import com.android.settings.search.Indexable; -import com.android.settingslib.core.AbstractPreferenceController; -import com.android.settingslib.core.lifecycle.Lifecycle; -import com.android.settingslib.search.SearchIndexable; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** Dashboard Fragment to display all recent location requests, sorted by recency. */ -@SearchIndexable -public class RecentLocationRequestSeeAllFragment extends DashboardFragment { - - private static final String TAG = "RecentLocationReqAll"; - - public static final String PATH = - "com.android.settings.location.RecentLocationRequestSeeAllFragment"; - - @Override - public int getMetricsCategory() { - return MetricsEvent.RECENT_LOCATION_REQUESTS_ALL; - } - - @Override - protected int getPreferenceScreenResId() { - return R.xml.location_recent_requests_see_all; - } - - @Override - protected String getLogTag() { - return TAG; - } - - @Override - protected List createPreferenceControllers(Context context) { - return buildPreferenceControllers(context, getSettingsLifecycle(), this); - } - - private static List buildPreferenceControllers( - Context context, Lifecycle lifecycle, RecentLocationRequestSeeAllFragment fragment) { - final List controllers = new ArrayList<>(); - controllers.add( - new RecentLocationRequestSeeAllPreferenceController(context, lifecycle, fragment)); - return controllers; - } - - /** - * For Search. - */ - public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider() { - @Override - public List getXmlResourcesToIndex( - Context context, boolean enabled) { - final SearchIndexableResource sir = new SearchIndexableResource(context); - sir.xmlResId = R.xml.location_recent_requests_see_all; - return Arrays.asList(sir); - } - - @Override - public List getPreferenceControllers(Context - context) { - return buildPreferenceControllers( - context, /* lifecycle = */ null, /* fragment = */ null); - } - }; -} diff --git a/src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceController.java b/src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceController.java deleted file mode 100644 index 3fa0f00e610..00000000000 --- a/src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceController.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.location; - -import android.content.Context; - -import androidx.annotation.VisibleForTesting; -import androidx.preference.Preference; -import androidx.preference.PreferenceCategory; -import androidx.preference.PreferenceScreen; - -import com.android.settingslib.core.lifecycle.Lifecycle; -import com.android.settingslib.location.RecentLocationApps; -import com.android.settingslib.widget.apppreference.AppPreference; - -import java.util.List; - -/** Preference controller for preference category displaying all recent location requests. */ -public class RecentLocationRequestSeeAllPreferenceController - extends LocationBasePreferenceController { - - /** Key for preference category "All recent location requests" */ - private static final String KEY_ALL_RECENT_LOCATION_REQUESTS = "all_recent_location_requests"; - private final RecentLocationRequestSeeAllFragment mFragment; - private PreferenceCategory mCategoryAllRecentLocationRequests; - private RecentLocationApps mRecentLocationApps; - - public RecentLocationRequestSeeAllPreferenceController( - Context context, Lifecycle lifecycle, RecentLocationRequestSeeAllFragment fragment) { - this(context, lifecycle, fragment, new RecentLocationApps(context)); - } - - @VisibleForTesting - RecentLocationRequestSeeAllPreferenceController( - Context context, - Lifecycle lifecycle, - RecentLocationRequestSeeAllFragment fragment, - RecentLocationApps recentLocationApps) { - super(context, lifecycle); - mFragment = fragment; - mRecentLocationApps = recentLocationApps; - } - - @Override - public String getPreferenceKey() { - return KEY_ALL_RECENT_LOCATION_REQUESTS; - } - - @Override - public void onLocationModeChanged(int mode, boolean restricted) { - mCategoryAllRecentLocationRequests.setEnabled(mLocationEnabler.isEnabled(mode)); - } - - @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - mCategoryAllRecentLocationRequests = - (PreferenceCategory) screen.findPreference(KEY_ALL_RECENT_LOCATION_REQUESTS); - - } - - @Override - public void updateState(Preference preference) { - mCategoryAllRecentLocationRequests.removeAll(); - List requests = mRecentLocationApps.getAppListSorted(); - for (RecentLocationApps.Request request : requests) { - Preference appPreference = createAppPreference(preference.getContext(), request); - mCategoryAllRecentLocationRequests.addPreference(appPreference); - } - } - - @VisibleForTesting - AppPreference createAppPreference( - Context prefContext, RecentLocationApps.Request request) { - final AppPreference pref = new AppPreference(prefContext); - pref.setSummary(request.contentDescription); - pref.setIcon(request.icon); - pref.setTitle(request.label); - pref.setOnPreferenceClickListener( - new RecentLocationRequestPreferenceController.PackageEntryClickedListener( - mFragment, request.packageName, request.userHandle)); - return pref; - } -} diff --git a/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java deleted file mode 100644 index d4b4ac31bd1..00000000000 --- a/tests/robotests/src/com/android/settings/location/RecentLocationRequestPreferenceControllerTest.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.settings.location; - -import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.Intent; -import android.provider.Settings; -import android.text.TextUtils; - -import androidx.lifecycle.LifecycleOwner; -import androidx.preference.Preference; -import androidx.preference.PreferenceCategory; -import androidx.preference.PreferenceScreen; - -import com.android.settings.R; -import com.android.settings.applications.appinfo.AppInfoDashboardFragment; -import com.android.settingslib.core.lifecycle.Lifecycle; -import com.android.settingslib.location.RecentLocationApps; -import com.android.settingslib.location.RecentLocationApps.Request; -import com.android.settingslib.widget.apppreference.AppPreference; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatcher; -import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -import java.util.ArrayList; -import java.util.List; - -@RunWith(RobolectricTestRunner.class) -public class RecentLocationRequestPreferenceControllerTest { - - @Mock - private LocationSettings mFragment; - @Mock - private PreferenceCategory mCategory; - @Mock - private PreferenceScreen mScreen; - @Mock - private RecentLocationApps mRecentLocationApps; - @Mock - private Preference mSeeAllButton; - - private Context mContext; - private RecentLocationRequestPreferenceController mController; - private LifecycleOwner mLifecycleOwner; - private Lifecycle mLifecycle; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application); - mLifecycleOwner = () -> mLifecycle; - mLifecycle = new Lifecycle(mLifecycleOwner); - mController = spy(new RecentLocationRequestPreferenceController( - mContext, mFragment, mLifecycle, mRecentLocationApps)); - when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mCategory); - when(mScreen.findPreference(mController.KEY_SEE_ALL_BUTTON)).thenReturn(mSeeAllButton); - final String key = mController.getPreferenceKey(); - when(mCategory.getKey()).thenReturn(key); - when(mCategory.getContext()).thenReturn(mContext); - } - - @Test - public void onLocationModeChanged_LocationOn_shouldEnablePreference() { - mController.displayPreference(mScreen); - - mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_BATTERY_SAVING, false); - - verify(mCategory).setEnabled(true); - } - - @Test - public void onLocationModeChanged_LocationOff_shouldDisablePreference() { - mController.displayPreference(mScreen); - - mController.onLocationModeChanged(Settings.Secure.LOCATION_MODE_OFF, false); - - verify(mCategory).setEnabled(false); - } - - @Test - public void updateState_noRecentRequest_shouldRemoveAllAndAddBanner() { - doReturn(new ArrayList<>()).when(mRecentLocationApps).getAppListSorted(); - mController.displayPreference(mScreen); - - mController.updateState(mCategory); - - verify(mCategory).removeAll(); - final String title = mContext.getString(R.string.location_no_recent_apps); - verify(mCategory).addPreference(argThat(titleMatches(title))); - } - - @Test - public void updateState_hasRecentRequest_shouldRemoveAllAndAddInjectedSettings() { - List requests = createMockRequests(2); - doReturn(requests).when(mRecentLocationApps).getAppListSorted(); - - mController.displayPreference(mScreen); - mController.updateState(mCategory); - - verify(mCategory).removeAll(); - // Verifies two preferences are added in original order - InOrder inOrder = Mockito.inOrder(mCategory); - inOrder.verify(mCategory).addPreference(argThat(titleMatches("appTitle0"))); - inOrder.verify(mCategory).addPreference(argThat(titleMatches("appTitle1"))); - } - - @Test - public void updateState_hasOverThreeRequests_shouldDisplaySeeAllButton() { - List requests = createMockRequests(6); - when(mRecentLocationApps.getAppListSorted()).thenReturn(requests); - - mController.displayPreference(mScreen); - mController.updateState(mCategory); - - verify(mCategory).removeAll(); - // Verifies the first three preferences are added - InOrder inOrder = Mockito.inOrder(mCategory); - inOrder.verify(mCategory).addPreference(argThat(titleMatches("appTitle0"))); - inOrder.verify(mCategory).addPreference(argThat(titleMatches("appTitle1"))); - inOrder.verify(mCategory).addPreference(argThat(titleMatches("appTitle2"))); - verify(mCategory, never()).addPreference(argThat(titleMatches("appTitle3"))); - // Verifies the "See all" preference is visible - verify(mSeeAllButton).setVisible(true); - } - - @Test - public void createAppPreference_shouldAddClickListener() { - final Request request = mock(Request.class); - final AppPreference preference = mock(AppPreference.class); - doReturn(preference).when(mController).createAppPreference(any(Context.class)); - - mController.createAppPreference(mContext, request); - - verify(preference).setOnPreferenceClickListener( - any(RecentLocationRequestPreferenceController.PackageEntryClickedListener.class)); - } - - @Test - public void onPreferenceClick_shouldLaunchAppDetails() { - final Context context = mock(Context.class); - when(mFragment.getContext()).thenReturn(context); - - final List requests = new ArrayList<>(); - final Request request = mock(Request.class); - requests.add(request); - doReturn(requests).when(mRecentLocationApps).getAppListSorted(); - final AppPreference preference = new AppPreference(mContext); - doReturn(preference).when(mController).createAppPreference(any(Context.class)); - mController.displayPreference(mScreen); - mController.updateState(mCategory); - - final ArgumentCaptor intent = ArgumentCaptor.forClass(Intent.class); - - preference.performClick(); - - verify(context).startActivity(intent.capture()); - - assertThat(intent.getValue().getStringExtra(EXTRA_SHOW_FRAGMENT)) - .isEqualTo(AppInfoDashboardFragment.class.getName()); - } - - private static ArgumentMatcher titleMatches(String expected) { - return preference -> TextUtils.equals(expected, preference.getTitle()); - } - - private List createMockRequests(int count) { - List requests = new ArrayList<>(); - for (int i = 0; i < count; i++) { - // Add mock requests - Request req = mock(Request.class, "request" + i); - requests.add(req); - // Map mock AppPreferences with mock requests - String title = "appTitle" + i; - AppPreference appPreference = mock(AppPreference.class, "AppPreference" + i); - doReturn(title).when(appPreference).getTitle(); - doReturn(appPreference) - .when(mController).createAppPreference(any(Context.class), eq(req)); - } - return requests; - } -} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceControllerTest.java deleted file mode 100644 index 7411afe1b4b..00000000000 --- a/tests/robotests/src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceControllerTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.location; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.provider.Settings.Secure; - -import androidx.lifecycle.LifecycleOwner; -import androidx.preference.PreferenceCategory; -import androidx.preference.PreferenceScreen; - -import com.android.settingslib.core.lifecycle.Lifecycle; -import com.android.settingslib.location.RecentLocationApps; -import com.android.settingslib.location.RecentLocationApps.Request; -import com.android.settingslib.widget.apppreference.AppPreference; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -import java.util.ArrayList; -import java.util.Collections; - -/** Unit tests for {@link RecentLocationRequestSeeAllPreferenceController} */ -@RunWith(RobolectricTestRunner.class) -public class RecentLocationRequestSeeAllPreferenceControllerTest { - - @Mock - RecentLocationRequestSeeAllFragment mFragment; - @Mock - private PreferenceScreen mScreen; - @Mock - private PreferenceCategory mCategory; - @Mock - private RecentLocationApps mRecentLocationApps; - - private Context mContext; - private LifecycleOwner mLifecycleOwner; - private Lifecycle mLifecycle; - private RecentLocationRequestSeeAllPreferenceController mController; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application); - mLifecycleOwner = () -> mLifecycle; - mLifecycle = new Lifecycle(mLifecycleOwner); - mController = spy( - new RecentLocationRequestSeeAllPreferenceController( - mContext, mLifecycle, mFragment, mRecentLocationApps)); - when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mCategory); - final String key = mController.getPreferenceKey(); - when(mCategory.getKey()).thenReturn(key); - when(mCategory.getContext()).thenReturn(mContext); - } - - @Test - public void onLocationModeChanged_locationOn_shouldEnablePreference() { - mController.displayPreference(mScreen); - - mController.onLocationModeChanged(Secure.LOCATION_MODE_HIGH_ACCURACY, false); - - verify(mCategory).setEnabled(true); - } - - @Test - public void onLocationModeChanged_locationOff_shouldDisablePreference() { - mController.displayPreference(mScreen); - - mController.onLocationModeChanged(Secure.LOCATION_MODE_OFF, false); - - verify(mCategory).setEnabled(false); - } - - @Test - public void updateState_shouldRemoveAll() { - doReturn(Collections.EMPTY_LIST).when(mRecentLocationApps).getAppListSorted(); - - mController.displayPreference(mScreen); - mController.updateState(mCategory); - - verify(mCategory).removeAll(); - } - - @Test - public void updateState_hasRecentLocationRequest_shouldAddPreference() { - Request request = mock(Request.class); - AppPreference appPreference = mock(AppPreference.class); - doReturn(appPreference) - .when(mController).createAppPreference(any(Context.class), eq(request)); - when(mRecentLocationApps.getAppListSorted()) - .thenReturn(new ArrayList<>(Collections.singletonList(request))); - - mController.displayPreference(mScreen); - mController.updateState(mCategory); - - verify(mCategory).removeAll(); - verify(mCategory).addPreference(appPreference); - } -}