<!-- [CHAR LIMIT=30] Location settings screen. It's a link that directs the user to a page that
shows the location permission setting for each installed app -->
<string name="location_app_level_permissions">App-level permissions</string>
- <!-- [CHAR LIMIT=42] Location settings screen, sub category for recent location requests -->
- <string name="location_category_recent_location_requests">Recent location requests</string>
- <!-- Location settings screen, displayed when there're more than three recent location requests -->
- <string name="location_recent_location_requests_see_all">See all</string>
+ <!-- [CHAR LIMIT=50] Location settings screen, sub category for recent location access -->
+ <string name="location_category_recent_location_access">Recent location access</string>
+ <!-- [CHAR LIMIT=30] Location settings screen, button to bring the user to view the details of recent location access -->
+ <string name="location_recent_location_access_view_details">View details</string>
<!-- Location settings screen, displayed when there's no recent app accessing location -->
<string name="location_no_recent_apps">No apps have requested location recently</string>
- <!-- [CHAR LIMIT=30] Location settings screen, sub category for location services -->
- <string name="location_category_location_services">Location services</string>
<!-- [CHAR LIMIT=30] Location settings screen, recent location requests high battery use-->
<string name="location_high_battery_use">High battery use</string>
<!-- [CHAR LIMIT=30] Location settings screen, recent location requests low battery use-->
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 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.
--->
-
-
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
- android:title="@string/location_category_recent_location_requests"
- android:key="recent_location_requests_see_all">
-
- <PreferenceCategory
- android:key="all_recent_location_requests"/>
-</PreferenceScreen>
\ No newline at end of file
android:title="@string/location_settings_title"
settings:keywords="@string/keywords_location">
- <PreferenceCategory
- android:key="recent_location_requests"
- android:title="@string/location_category_recent_location_requests"/>
-
- <Preference
- android:key="recent_location_requests_see_all_button"
- android:title="@string/location_recent_location_requests_see_all"
- android:icon="@drawable/ic_chevron_right_24dp"
- android:selectable="true"
- android:fragment="com.android.settings.location.RecentLocationRequestSeeAllFragment"
- settings:searchable="false"/>
+ <com.android.settingslib.widget.LayoutPreference
+ android:key="apps_dashboard"
+ android:layout="@layout/app_entities_header"
+ settings:allowDividerBelow="true" />
<PreferenceCategory
android:key="location_advanced_settings"
- settings:initialExpandedChildrenCount="1">
+ settings:initialExpandedChildrenCount="0">
<!-- This preference category gets removed if new_recent_location_ui is disabled -->
<Preference
android:selectable="true" />
<PreferenceCategory
- android:key="location_services"
- android:title="@string/location_category_location_services"/>
+ android:key="location_services" />
</PreferenceCategory>
<PreferenceCategory
import com.android.settings.widget.SwitchBar;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.location.RecentLocationApps;
+import com.android.settingslib.location.RecentLocationAccesses;
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
* <li>In switch bar: location master switch. Used to toggle location on and off.
* </li>
* </ul>
- * <li>Recent location requests: automatically populated by {@link RecentLocationApps}</li>
+ * <li>Recent location requests: automatically populated by {@link RecentLocationAccesses}</li>
* <li>Location services: multi-app settings provided from outside the Android framework. Each
* is injected by a system-partition app via the {@link SettingInjectorService} API.</li>
* </ul>
final List<AbstractPreferenceController> 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;
}
--- /dev/null
+/*
+ * 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.Access> 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();
+ }
+}
+++ /dev/null
-/*
- * 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<RecentLocationApps.Request> 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;
- }
-}
+++ /dev/null
-/*
- * 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<AbstractPreferenceController> createPreferenceControllers(Context context) {
- return buildPreferenceControllers(context, getSettingsLifecycle(), this);
- }
-
- private static List<AbstractPreferenceController> buildPreferenceControllers(
- Context context, Lifecycle lifecycle, RecentLocationRequestSeeAllFragment fragment) {
- final List<AbstractPreferenceController> 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<SearchIndexableResource> 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<AbstractPreferenceController> getPreferenceControllers(Context
- context) {
- return buildPreferenceControllers(
- context, /* lifecycle = */ null, /* fragment = */ null);
- }
- };
-}
+++ /dev/null
-/*
- * 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<RecentLocationApps.Request> 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;
- }
-}
+++ /dev/null
-/*
- * 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<Request> 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<Request> 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<RecentLocationApps.Request> 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> 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<Preference> titleMatches(String expected) {
- return preference -> TextUtils.equals(expected, preference.getTitle());
- }
-
- private List<RecentLocationApps.Request> createMockRequests(int count) {
- List<RecentLocationApps.Request> 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
+++ /dev/null
-/*
- * 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);
- }
-}