diff options
Diffstat (limited to 'src/com/android/settings/location')
4 files changed, 399 insertions, 3 deletions
diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java index 68714281c8..71424867d6 100644 --- a/src/com/android/settings/location/LocationSettings.java +++ b/src/com/android/settings/location/LocationSettings.java @@ -33,7 +33,7 @@ import com.android.settings.search.Indexable; import com.android.settings.widget.SwitchBar; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; -import com.android.settingslib.location.RecentLocationAccesses; +import com.android.settingslib.location.RecentLocationApps; import com.android.settingslib.search.SearchIndexable; import java.util.ArrayList; @@ -50,7 +50,7 @@ import java.util.List; * <li>In switch bar: location master switch. Used to toggle location on and off. * </li> * </ul> - * <li>Recent location requests: automatically populated by {@link RecentLocationAccesses}</li> + * <li>Recent location requests: automatically populated by {@link RecentLocationApps}</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> @@ -118,7 +118,7 @@ public class LocationSettings extends DashboardFragment { final List<AbstractPreferenceController> controllers = new ArrayList<>(); controllers.add(new AppLocationPermissionPreferenceController(context, lifecycle)); controllers.add(new LocationForWorkPreferenceController(context, lifecycle)); - controllers.add(new RecentLocationAccessPreferenceController(context)); + controllers.add(new RecentLocationRequestPreferenceController(context, fragment, lifecycle)); controllers.add(new LocationScanningPreferenceController(context)); controllers.add(new LocationServicePreferenceController(context, fragment, lifecycle)); controllers.add(new LocationFooterPreferenceController(context, lifecycle)); diff --git a/src/com/android/settings/location/RecentLocationRequestPreferenceController.java b/src/com/android/settings/location/RecentLocationRequestPreferenceController.java new file mode 100644 index 0000000000..fb8c62c657 --- /dev/null +++ b/src/com/android/settings/location/RecentLocationRequestPreferenceController.java @@ -0,0 +1,145 @@ +/* + * 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; + + /** 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); + } + + @Override + public void updateState(Preference preference) { + mCategoryRecentLocationRequests.removeAll(); + final Context prefContext = preference.getContext(); + final List<RecentLocationApps.Request> recentLocationRequests = + mRecentLocationApps.getAppListSorted(false); + 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))); + } + } 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 new file mode 100644 index 0000000000..9e4a77fdb2 --- /dev/null +++ b/src/com/android/settings/location/RecentLocationRequestSeeAllFragment.java @@ -0,0 +1,135 @@ +/* + * 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 android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; + +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"; + + private static final int MENU_SHOW_SYSTEM = Menu.FIRST + 1; + private static final int MENU_HIDE_SYSTEM = Menu.FIRST + 2; + + private boolean mShowSystem = false; + private MenuItem mShowSystemMenu; + private MenuItem mHideSystemMenu; + private RecentLocationRequestSeeAllPreferenceController mController; + + @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); + } + + @Override + public boolean onOptionsItemSelected(MenuItem menuItem) { + switch (menuItem.getItemId()) { + case MENU_SHOW_SYSTEM: + case MENU_HIDE_SYSTEM: + mShowSystem = menuItem.getItemId() == MENU_SHOW_SYSTEM; + updateMenu(); + if (mController != null) { + mController.setShowSystem(mShowSystem); + } + return true; + default: + return super.onOptionsItemSelected(menuItem); + } + } + + private void updateMenu() { + mShowSystemMenu.setVisible(!mShowSystem); + mHideSystemMenu.setVisible(mShowSystem); + } + + private static List<AbstractPreferenceController> buildPreferenceControllers( + Context context, Lifecycle lifecycle, RecentLocationRequestSeeAllFragment fragment) { + final List<AbstractPreferenceController> controllers = new ArrayList<>(); + final RecentLocationRequestSeeAllPreferenceController controller = + new RecentLocationRequestSeeAllPreferenceController(context, lifecycle, fragment); + controllers.add(controller); + if (fragment != null) { + fragment.mController = controller; + } + 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); + } + }; + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + mShowSystemMenu = menu.add(Menu.NONE, MENU_SHOW_SYSTEM, Menu.NONE, + R.string.menu_show_system); + mHideSystemMenu = menu.add(Menu.NONE, MENU_HIDE_SYSTEM, Menu.NONE, + R.string.menu_hide_system); + updateMenu(); + } +} diff --git a/src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceController.java b/src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceController.java new file mode 100644 index 0000000000..3abccf7d23 --- /dev/null +++ b/src/com/android/settings/location/RecentLocationRequestSeeAllPreferenceController.java @@ -0,0 +1,116 @@ +/* + * 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; + +import com.android.settings.R; + +/** 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; + private boolean mShowSystem = false; + private Preference mPreference; + + 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(); + mPreference = preference; + List<RecentLocationApps.Request> requests = mRecentLocationApps.getAppListSorted( + mShowSystem); + if (requests.isEmpty()) { + // If there's no item to display, add a "No recent apps" item. + final Preference banner = new AppPreference(mContext); + banner.setTitle(R.string.location_no_recent_apps); + banner.setSelectable(false); + mCategoryAllRecentLocationRequests.addPreference(banner); + } else { + 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; + } + + public void setShowSystem(boolean showSystem) { + mShowSystem = showSystem; + if (mPreference != null) { + updateState(mPreference); + } + } +} |