summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--location/java/android/location/LocationManager.java11
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/Utils.java16
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java69
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java7
4 files changed, 100 insertions, 3 deletions
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 968f596e0cc5..d15ab33eed35 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -184,6 +184,17 @@ public class LocationManager {
public static final String MODE_CHANGED_ACTION = "android.location.MODE_CHANGED";
/**
+ * Broadcast intent action when {@link android.provider.Settings.Secure#LOCATION_MODE} is
+ * about to be changed through Settings app or Quick Settings.
+ * For use with the {@link android.provider.Settings.Secure#LOCATION_MODE} API.
+ * If you're interacting with {@link #isProviderEnabled(String)}, use
+ * {@link #PROVIDERS_CHANGED_ACTION} instead.
+ *
+ * @hide
+ */
+ public static final String MODE_CHANGING_ACTION = "com.android.settings.location.MODE_CHANGING";
+
+ /**
* Broadcast intent action indicating that the GPS has either started or
* stopped receiving GPS fixes. An intent extra provides this state as a
* boolean, where {@code true} means that the GPS is actively receiving fixes.
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index eb338427b225..3c46d99906c7 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -14,8 +14,10 @@ import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
+import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.os.BatteryManager;
+import android.os.UserHandle;
import android.os.UserManager;
import android.print.PrintManager;
import android.provider.Settings;
@@ -26,6 +28,10 @@ import com.android.settingslib.drawable.UserIconDrawable;
import java.text.NumberFormat;
public class Utils {
+
+ private static final String CURRENT_MODE_KEY = "CURRENT_MODE";
+ private static final String NEW_MODE_KEY = "NEW_MODE";
+
private static Signature[] sSystemSignature;
private static String sPermissionControllerPackageName;
private static String sServicesSystemSharedLibPackageName;
@@ -39,6 +45,16 @@ public class Utils {
com.android.internal.R.drawable.ic_wifi_signal_4
};
+ public static boolean updateLocationMode(Context context, int oldMode, int newMode, int userId) {
+ Intent intent = new Intent(LocationManager.MODE_CHANGING_ACTION);
+ intent.putExtra(CURRENT_MODE_KEY, oldMode);
+ intent.putExtra(NEW_MODE_KEY, newMode);
+ context.sendBroadcastAsUser(
+ intent, UserHandle.of(userId), android.Manifest.permission.WRITE_SECURE_SETTINGS);
+ return Settings.Secure.putIntForUser(
+ context.getContentResolver(), Settings.Secure.LOCATION_MODE, newMode, userId);
+ }
+
/**
* Return string resource that best describes combination of tethering
* options available on this device.
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
index c6cfdb80d851..976bbee64208 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
@@ -15,20 +15,45 @@
*/
package com.android.settingslib;
+import android.app.ActivityManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.location.LocationManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.text.TextUtils;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
+import org.mockito.ArgumentMatchers;
+import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Matchers.eq;
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.res.Resources;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowSettings;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(
+ manifest = TestConfig.MANIFEST_PATH,
+ sdk = TestConfig.SDK_VERSION,
+ shadows = {UtilsTest.ShadowSecure.class})
public class UtilsTest {
private static final double[] TEST_PERCENTAGES = {0, 0.4, 0.5, 0.6, 49, 49.3, 49.8, 50, 100};
private static final String PERCENTAGE_0 = "0%";
@@ -37,6 +62,29 @@ public class UtilsTest {
private static final String PERCENTAGE_50 = "50%";
private static final String PERCENTAGE_100 = "100%";
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = spy(RuntimeEnvironment.application);
+ ShadowSecure.reset();
+ }
+
+ @Test
+ public void testUpdateLocationMode_sendBroadcast() {
+ int currentUserId = ActivityManager.getCurrentUser();
+ Utils.updateLocationMode(
+ mContext,
+ Secure.LOCATION_MODE_OFF,
+ Secure.LOCATION_MODE_HIGH_ACCURACY,
+ currentUserId);
+
+ verify(mContext).sendBroadcastAsUser(
+ argThat(actionMatches(LocationManager.MODE_CHANGING_ACTION)),
+ ArgumentMatchers.eq(UserHandle.of(currentUserId)),
+ ArgumentMatchers.eq(WRITE_SECURE_SETTINGS));
+ }
+
@Test
public void testFormatPercentage_RoundTrue_RoundUpIfPossible() {
final String[] expectedPercentages = {PERCENTAGE_0, PERCENTAGE_0, PERCENTAGE_1,
@@ -74,4 +122,23 @@ public class UtilsTest {
.thenReturn(60);
assertThat(Utils.getDefaultStorageManagerDaysToRetain(resources)).isEqualTo(60);
}
+
+ private static ArgumentMatcher<Intent> actionMatches(String expected) {
+ return intent -> TextUtils.equals(expected, intent.getAction());
+ }
+
+ @Implements(value = Settings.Secure.class)
+ public static class ShadowSecure extends ShadowSettings.ShadowSecure {
+ private static Map<String, Integer> map = new HashMap<>();
+
+ @Implementation
+ public static boolean putIntForUser(ContentResolver cr, String name, int value, int userHandle) {
+ map.put(name, value);
+ return true;
+ }
+
+ public static void reset() {
+ map.clear();
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index 874f0d9d5b5f..4ee4ef492ec1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -39,6 +39,8 @@ import com.android.systemui.util.Utils;
import java.util.ArrayList;
import java.util.List;
+import static com.android.settingslib.Utils.updateLocationMode;
+
/**
* A controller to manage changes of location related states and update the views accordingly.
*/
@@ -106,12 +108,13 @@ public class LocationControllerImpl extends BroadcastReceiver implements Locatio
final ContentResolver cr = mContext.getContentResolver();
// When enabling location, a user consent dialog will pop up, and the
// setting won't be fully enabled until the user accepts the agreement.
+ int currentMode = Settings.Secure.getIntForUser(cr, Settings.Secure.LOCATION_MODE,
+ Settings.Secure.LOCATION_MODE_OFF, currentUserId);
int mode = enabled
? Settings.Secure.LOCATION_MODE_PREVIOUS : Settings.Secure.LOCATION_MODE_OFF;
// QuickSettings always runs as the owner, so specifically set the settings
// for the current foreground user.
- return Settings.Secure
- .putIntForUser(cr, Settings.Secure.LOCATION_MODE, mode, currentUserId);
+ return updateLocationMode(mContext, currentMode, mode, currentUserId);
}
/**