From 2491d63996dd7f32791d6f2364a8d83cfd75ed35 Mon Sep 17 00:00:00 2001 From: Soonil Nagarkar Date: Mon, 8 Mar 2021 15:47:28 -0800 Subject: [PATCH] Remove dynamic location settings footer Replace with static location settings footer. Bug: 182210346 Test: manual Change-Id: If3ab492418e5f3461f7b0123fc771ecdd56db6c9 --- res/values/strings.xml | 5 + res/xml/location_settings.xml | 7 +- res/xml/location_settings_personal.xml | 7 +- res/xml/location_settings_workprofile.xml | 7 +- .../LocationFooterPreferenceController.java | 162 ------------------ .../location/LocationPersonalSettings.java | 1 - .../settings/location/LocationSettings.java | 1 - .../location/LocationWorkProfileSettings.java | 1 - ...ocationFooterPreferenceControllerTest.java | 159 ----------------- 9 files changed, 14 insertions(+), 336 deletions(-) delete mode 100644 src/com/android/settings/location/LocationFooterPreferenceController.java delete mode 100644 tests/robotests/src/com/android/settings/location/LocationFooterPreferenceControllerTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 869f7c3fe85..1acd110d32a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -684,6 +684,11 @@ Loading\u2026 + + + Location may use sources like GPS, Wi\u2011Fi, mobile networks, and sensors to help estimate + your device\u2019s location. + Accounts diff --git a/res/xml/location_settings.xml b/res/xml/location_settings.xml index 93f30e58d56..3b87ae4583f 100644 --- a/res/xml/location_settings.xml +++ b/res/xml/location_settings.xml @@ -76,9 +76,8 @@ - + android:selectable="false"/> diff --git a/res/xml/location_settings_personal.xml b/res/xml/location_settings_personal.xml index 0e971d660c9..0307a85641a 100644 --- a/res/xml/location_settings_personal.xml +++ b/res/xml/location_settings_personal.xml @@ -53,9 +53,8 @@ android:fragment="com.android.settings.location.LocationServices" settings:controller="com.android.settings.location.LocationServicesPreferenceController"/> - + android:selectable="false"/> diff --git a/res/xml/location_settings_workprofile.xml b/res/xml/location_settings_workprofile.xml index c3efcbe2af5..5ec3e1b0c6e 100644 --- a/res/xml/location_settings_workprofile.xml +++ b/res/xml/location_settings_workprofile.xml @@ -61,9 +61,8 @@ android:fragment="com.android.settings.location.LocationServicesForWork" settings:controller="com.android.settings.location.LocationServicesForWorkPreferenceController"/> - + android:selectable="false"/> diff --git a/src/com/android/settings/location/LocationFooterPreferenceController.java b/src/com/android/settings/location/LocationFooterPreferenceController.java deleted file mode 100644 index 3b9324df31c..00000000000 --- a/src/com/android/settings/location/LocationFooterPreferenceController.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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. - */ -package com.android.settings.location; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.ResolveInfo; -import android.location.LocationManager; -import android.util.Log; - -import androidx.preference.Preference; -import androidx.preference.PreferenceCategory; - -import com.android.settingslib.widget.FooterPreference; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -/** - * Preference controller for location footer preference category - */ -public class LocationFooterPreferenceController extends LocationBasePreferenceController { - - private static final String TAG = "LocationFooter"; - private static final Intent INJECT_INTENT = - new Intent(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION); - - private final PackageManager mPackageManager; - - public LocationFooterPreferenceController(Context context, String key) { - super(context, key); - mPackageManager = context.getPackageManager(); - } - - /** - * Insert footer preferences. - */ - @Override - public void updateState(Preference preference) { - PreferenceCategory category = (PreferenceCategory) preference; - category.removeAll(); - Collection footerData = getFooterData(); - for (FooterData data : footerData) { - try { - String footerString = - mPackageManager - .getResourcesForApplication(data.applicationInfo) - .getString(data.footerStringRes); - - // Generate a footer preference with the given text - FooterPreference footerPreference = new FooterPreference(preference.getContext()); - footerPreference.setTitle(footerString); - category.addPreference(footerPreference); - } catch (NameNotFoundException exception) { - Log.w( - TAG, - "Resources not found for application " - + data.applicationInfo.packageName); - } - } - } - - /** - * Do nothing on location mode changes. - */ - @Override - public void onLocationModeChanged(int mode, boolean restricted) {} - - /** - * Location footer preference group should be displayed if there is at least one footer to - * inject. - */ - @Override - public int getAvailabilityStatus() { - return !getFooterData().isEmpty() ? AVAILABLE : UNSUPPORTED_ON_DEVICE; - } - - /** - * Return a list of strings with text provided by ACTION_INJECT_FOOTER broadcast receivers. - */ - private List getFooterData() { - // Fetch footer text from system apps - List resolveInfos = - mPackageManager.queryBroadcastReceivers( - INJECT_INTENT, PackageManager.GET_META_DATA); - if (resolveInfos == null) { - Log.e(TAG, "Unable to resolve intent " + INJECT_INTENT); - return Collections.emptyList(); - } - - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "Found broadcast receivers: " + resolveInfos); - } - - List footerDataList = new ArrayList<>(resolveInfos.size()); - for (ResolveInfo resolveInfo : resolveInfos) { - ActivityInfo activityInfo = resolveInfo.activityInfo; - ApplicationInfo appInfo = activityInfo.applicationInfo; - - // If a non-system app tries to inject footer, ignore it - if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { - Log.w(TAG, "Ignoring attempt to inject footer from app not in system image: " - + resolveInfo); - continue; - } - - // Get the footer text resource id from broadcast receiver's metadata - if (activityInfo.metaData == null) { - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "No METADATA in broadcast receiver " + activityInfo.name); - } - continue; - } - - final int footerTextRes = - activityInfo.metaData.getInt(LocationManager.METADATA_SETTINGS_FOOTER_STRING); - if (footerTextRes == 0) { - Log.w( - TAG, - "No mapping of integer exists for " - + LocationManager.METADATA_SETTINGS_FOOTER_STRING); - continue; - } - footerDataList.add(new FooterData(footerTextRes, appInfo)); - } - return footerDataList; - } - - /** - * Contains information related to a footer. - */ - private static class FooterData { - - // The string resource of the footer - final int footerStringRes; - - // Application info of receiver injecting this footer - final ApplicationInfo applicationInfo; - - FooterData(int footerRes, ApplicationInfo appInfo) { - this.footerStringRes = footerRes; - this.applicationInfo = appInfo; - } - } -} diff --git a/src/com/android/settings/location/LocationPersonalSettings.java b/src/com/android/settings/location/LocationPersonalSettings.java index bdf2d2b8e89..ef5465c75e7 100644 --- a/src/com/android/settings/location/LocationPersonalSettings.java +++ b/src/com/android/settings/location/LocationPersonalSettings.java @@ -52,7 +52,6 @@ public class LocationPersonalSettings extends DashboardFragment { use(AppLocationPermissionPreferenceController.class).init(this); // STOPSHIP(b/180533061): resolve the personal/work location services issue before we can // ship. - use(LocationFooterPreferenceController.class).init(this); use(RecentLocationAccessSeeAllButtonPreferenceController.class).init(this); final int profileType = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE); diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java index bb971bff057..7b7ca1662be 100644 --- a/src/com/android/settings/location/LocationSettings.java +++ b/src/com/android/settings/location/LocationSettings.java @@ -84,7 +84,6 @@ public class LocationSettings extends DashboardFragment { use(AppLocationPermissionPreferenceController.class).init(this); use(RecentLocationAccessPreferenceController.class).init(this); use(RecentLocationAccessSeeAllButtonPreferenceController.class).init(this); - use(LocationFooterPreferenceController.class).init(this); use(LocationForWorkPreferenceController.class).init(this); use(LocationInjectedServicesForWorkPreferenceController.class).init(this); } diff --git a/src/com/android/settings/location/LocationWorkProfileSettings.java b/src/com/android/settings/location/LocationWorkProfileSettings.java index 67830758007..4cafcbff384 100644 --- a/src/com/android/settings/location/LocationWorkProfileSettings.java +++ b/src/com/android/settings/location/LocationWorkProfileSettings.java @@ -50,7 +50,6 @@ public class LocationWorkProfileSettings extends DashboardFragment { super.onAttach(context); use(AppLocationPermissionPreferenceController.class).init(this); - use(LocationFooterPreferenceController.class).init(this); use(LocationForWorkPreferenceController.class).init(this); use(RecentLocationAccessSeeAllButtonPreferenceController.class).init(this); diff --git a/tests/robotests/src/com/android/settings/location/LocationFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationFooterPreferenceControllerTest.java deleted file mode 100644 index 180f3e2494b..00000000000 --- a/tests/robotests/src/com/android/settings/location/LocationFooterPreferenceControllerTest.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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. - */ -package com.android.settings.location; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.doNothing; -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.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.ResolveInfo; -import android.content.res.Resources; -import android.location.LocationManager; -import android.os.Bundle; - -import androidx.preference.Preference; -import androidx.preference.PreferenceCategory; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -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 LocationFooterPreferenceControllerTest { - - @Mock - private PreferenceCategory mPreferenceCategory; - @Mock - private PackageManager mPackageManager; - @Mock - private Resources mResources; - private LocationFooterPreferenceController mController; - private static final int TEST_RES_ID = 1234; - private static final String TEST_TEXT = "text"; - - @Before - public void setUp() throws NameNotFoundException { - MockitoAnnotations.initMocks(this); - Context context = spy(RuntimeEnvironment.application); - when(context.getPackageManager()).thenReturn(mPackageManager); - when(mPreferenceCategory.getContext()).thenReturn(context); - mController = spy(new LocationFooterPreferenceController(context, "key")); - when(mPackageManager.getResourcesForApplication(any(ApplicationInfo.class))) - .thenReturn(mResources); - when(mResources.getString(TEST_RES_ID)).thenReturn(TEST_TEXT); - doNothing().when(mPreferenceCategory).removeAll(); - } - - @Test - public void isAvailable_hasValidFooter_returnsTrue() { - final List testResolveInfos = new ArrayList<>(); - testResolveInfos.add( - getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true)); - when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt())) - .thenReturn(testResolveInfos); - - assertThat(mController.isAvailable()).isTrue(); - } - - @Test - public void isAvailable_noSystemApp_returnsFalse() { - final List testResolveInfos = new ArrayList<>(); - testResolveInfos.add( - getTestResolveInfo(/*isSystemApp*/ false, /*hasRequiredMetadata*/ true)); - when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt())) - .thenReturn(testResolveInfos); - assertThat(mController.isAvailable()).isFalse(); - } - - @Test - public void isAvailable_noRequiredMetadata_returnsFalse() { - final List testResolveInfos = new ArrayList<>(); - testResolveInfos.add( - getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ false)); - when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt())) - .thenReturn(testResolveInfos); - assertThat(mController.isAvailable()).isFalse(); - } - - @Test - public void updateState_addPreferences() { - final List testResolveInfos = new ArrayList<>(); - testResolveInfos.add( - getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true)); - when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt())) - .thenReturn(testResolveInfos); - mController.updateState(mPreferenceCategory); - ArgumentCaptor pref = ArgumentCaptor.forClass(Preference.class); - verify(mPreferenceCategory).addPreference(pref.capture()); - assertThat(pref.getValue().getTitle()).isEqualTo(TEST_TEXT); - } - - @Test - public void updateState_notSystemApp_ignore() { - final List testResolveInfos = new ArrayList<>(); - testResolveInfos.add( - getTestResolveInfo(/*isSystemApp*/ false, /*hasRequiredMetadata*/ true)); - when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt())) - .thenReturn(testResolveInfos); - mController.updateState(mPreferenceCategory); - verify(mPreferenceCategory, never()).addPreference(any(Preference.class)); - } - - /** - * Returns a ResolveInfo object for testing - * @param isSystemApp If true, the application is a system app. - * @param hasRequiredMetaData If true, the broadcast receiver has a valid value for - * {@link LocationManager#METADATA_SETTINGS_FOOTER_STRING} - */ - private ResolveInfo getTestResolveInfo(boolean isSystemApp, boolean hasRequiredMetaData) { - ResolveInfo testResolveInfo = new ResolveInfo(); - ApplicationInfo testAppInfo = new ApplicationInfo(); - if (isSystemApp) { - testAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM; - } - ActivityInfo testActivityInfo = new ActivityInfo(); - testActivityInfo.name = "TestActivityName"; - testActivityInfo.packageName = "TestPackageName"; - testActivityInfo.applicationInfo = testAppInfo; - if (hasRequiredMetaData) { - testActivityInfo.metaData = new Bundle(); - testActivityInfo.metaData.putInt( - LocationManager.METADATA_SETTINGS_FOOTER_STRING, TEST_RES_ID); - } - testResolveInfo.activityInfo = testActivityInfo; - return testResolveInfo; - } -}