From b9cf917f403e7ee31f81d3b8dfd54c50123fa2c5 Mon Sep 17 00:00:00 2001 From: songchenxi Date: Wed, 18 Jan 2017 20:16:57 -0800 Subject: [PATCH] Location Setting change for O This is a change that adds a link from location settings to location permissions Test: Manual Bug: 34400189 Change-Id: If873fbb6e53c1fd86a3cfe38e06465cdec56bef8 --- res/values/strings.xml | 2 + res/xml/location_settings.xml | 5 ++ ...ocationPermissionPreferenceController.java | 39 +++++++++++ .../settings/location/LocationSettings.java | 36 +++++++++- ...ionPermissionPreferenceControllerTest.java | 69 +++++++++++++++++++ 5 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 src/com/android/settings/location/AppLocationPermissionPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/location/AppLocationPermissionPreferenceControllerTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 36790575d3c..099a29039ef 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3039,6 +3039,8 @@ Device only Location off + + App-level permissions Recent location requests diff --git a/res/xml/location_settings.xml b/res/xml/location_settings.xml index 1abf9be7043..ecce221790e 100644 --- a/res/xml/location_settings.xml +++ b/res/xml/location_settings.xml @@ -34,6 +34,11 @@ android:enabled="false" android:selectable="true" /> + + + diff --git a/src/com/android/settings/location/AppLocationPermissionPreferenceController.java b/src/com/android/settings/location/AppLocationPermissionPreferenceController.java new file mode 100644 index 00000000000..d91b47b9cb6 --- /dev/null +++ b/src/com/android/settings/location/AppLocationPermissionPreferenceController.java @@ -0,0 +1,39 @@ +package com.android.settings.location; + +import android.content.Context; +import android.content.Intent; +import android.provider.Settings; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; + +import com.android.settings.core.PreferenceController; + +public class AppLocationPermissionPreferenceController extends PreferenceController { + + private static final String KEY_APP_LEVEL_PERMISSIONS = "app_level_permissions"; + private Preference mPreference; + + public AppLocationPermissionPreferenceController(Context context) { + super(context); + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + if (isAvailable()) { + mPreference = screen.findPreference(KEY_APP_LEVEL_PERMISSIONS); + } + } + + @Override + public String getPreferenceKey() { + return KEY_APP_LEVEL_PERMISSIONS; + } + + @Override + public boolean isAvailable() { + return Settings.Global.getInt(mContext.getContentResolver(), + android.provider.Settings.Global.LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED, 1) + == 1; + } +} diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java index 03aa155992e..d6ff4dcaaea 100644 --- a/src/com/android/settings/location/LocationSettings.java +++ b/src/com/android/settings/location/LocationSettings.java @@ -18,6 +18,7 @@ package com.android.settings.location; import android.app.Activity; import android.app.admin.DevicePolicyManager; +import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -95,11 +96,14 @@ public class LocationSettings extends LocationSettingsBase private static final String KEY_LOCATION_MODE = "location_mode"; /** Key for preference category "Recent location requests" */ private static final String KEY_RECENT_LOCATION_REQUESTS = "recent_location_requests"; + /** Key for preference "App-level permissions" */ + private static final String KEY_APP_LEVEL_PERMISSIONS = "app_level_permissions"; /** Key for preference category "Location services" */ private static final String KEY_LOCATION_SERVICES = "location_services"; private static final int MENU_SCANNING = Menu.FIRST; + private static final String KEY_LOCATION_PERMISSION = "android.permission-group.LOCATION"; private SwitchBar mSwitchBar; private Switch mSwitch; private boolean mValidListener = false; @@ -201,10 +205,21 @@ public class LocationSettings extends LocationSettingsBase } }); - mCategoryRecentLocationRequests = - (PreferenceCategory) root.findPreference(KEY_RECENT_LOCATION_REQUESTS); RecentLocationApps recentApps = new RecentLocationApps(activity); List recentLocationRequests = recentApps.getAppList(); + + final AppLocationPermissionPreferenceController preferenceController = + new AppLocationPermissionPreferenceController(activity); + preferenceController.displayPreference(root); + if (preferenceController.isAvailable()) { + Preference preferenceAppLevelPermissions = + root.findPreference(KEY_APP_LEVEL_PERMISSIONS); + setupAppLevelPermissionsPreference(preferenceAppLevelPermissions); + } + + mCategoryRecentLocationRequests = + (PreferenceCategory) root.findPreference(KEY_RECENT_LOCATION_REQUESTS); + List recentLocationPrefs = new ArrayList<>(recentLocationRequests.size()); for (final RecentLocationApps.Request request : recentLocationRequests) { DimmableIconPreference pref = new DimmableIconPreference(getPrefContext(), @@ -261,6 +276,23 @@ public class LocationSettings extends LocationSettingsBase } } + private void setupAppLevelPermissionsPreference(Preference preference) { + preference.setOnPreferenceClickListener( + new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + Intent intent = new Intent(Intent.ACTION_MANAGE_PERMISSION_APPS) + .putExtra(Intent.EXTRA_PERMISSION_NAME, KEY_LOCATION_PERMISSION); + try { + getActivity().startActivity(intent); + } catch (ActivityNotFoundException e) { + Log.w("Permission", "No app to handle " + intent); + } + return true; + } + }); + } + private void changeManagedProfileLocationAccessStatus(boolean mainSwitchOn) { if (mManagedProfileSwitch == null) { return; diff --git a/tests/robotests/src/com/android/settings/location/AppLocationPermissionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/AppLocationPermissionPreferenceControllerTest.java new file mode 100644 index 00000000000..8a035e5140e --- /dev/null +++ b/tests/robotests/src/com/android/settings/location/AppLocationPermissionPreferenceControllerTest.java @@ -0,0 +1,69 @@ +package com.android.settings.location; + +import android.content.Context; +import android.os.UserManager; +import android.provider.Settings; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; + +import com.android.settings.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowApplication; + +import static org.mockito.Answers.RETURNS_DEEP_STUBS; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class AppLocationPermissionPreferenceControllerTest { + @Mock + private Preference mPreference; + @Mock(answer = RETURNS_DEEP_STUBS) + private PreferenceScreen mScreen; + + private AppLocationPermissionPreferenceController mController; + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Context mContext; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(mScreen.findPreference(anyString())).thenReturn(mPreference); + mController = new AppLocationPermissionPreferenceController(mContext); + } + + @Test + public void displayPreference_shouldRemovePreference() { + Settings.System.putInt(mContext.getContentResolver(), + android.provider.Settings.Global.LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED, + 0); + + mController.displayPreference(mScreen); + + verify(mScreen).removePreference(any(Preference.class)); + } + + @Test + public void displayPreference_shouldNotRemovePreference() { + Settings.System.putInt(mContext.getContentResolver(), + android.provider.Settings.Global.LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED, + 1); + mController.displayPreference(mScreen); + + verify(mScreen, never()).removePreference(any(Preference.class)); + } + +}