Merge "Remembers previous location mode when location off"
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f560f8a..c92382a 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4420,8 +4420,19 @@
          * to receive changes in this value.
          */
         public static final String LOCATION_MODE = "location_mode";
+        /**
+         * Stores the previous location mode when {@link #LOCATION_MODE} is set to
+         * {@link #LOCATION_MODE_OFF}
+         * @hide
+         */
+        public static final String LOCATION_PREVIOUS_MODE = "location_previous_mode";
 
         /**
+         * Sets all location providers to the previous states before location was turned off.
+         * @hide
+         */
+        public static final int LOCATION_MODE_PREVIOUS = -1;
+        /**
          * Location access disabled.
          */
         public static final int LOCATION_MODE_OFF = 0;
@@ -5795,6 +5806,7 @@
             CLONE_TO_MANAGED_PROFILE.add(ENABLED_ACCESSIBILITY_SERVICES);
             CLONE_TO_MANAGED_PROFILE.add(ENABLED_INPUT_METHODS);
             CLONE_TO_MANAGED_PROFILE.add(LOCATION_MODE);
+            CLONE_TO_MANAGED_PROFILE.add(LOCATION_PREVIOUS_MODE);
             CLONE_TO_MANAGED_PROFILE.add(LOCATION_PROVIDERS_ALLOWED);
             CLONE_TO_MANAGED_PROFILE.add(LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
             CLONE_TO_MANAGED_PROFILE.add(SELECTED_INPUT_METHOD_SUBTYPE);
@@ -5882,6 +5894,28 @@
         }
 
         /**
+         * Saves the current location mode into {@link #LOCATION_PREVIOUS_MODE}.
+         */
+        private static final boolean saveLocationModeForUser(ContentResolver cr, int userId) {
+            final int mode = getLocationModeForUser(cr, userId);
+            return putIntForUser(cr, Settings.Secure.LOCATION_PREVIOUS_MODE, mode, userId);
+        }
+
+        /**
+         * Restores the current location mode from {@link #LOCATION_PREVIOUS_MODE}.
+         */
+        private static final boolean restoreLocationModeForUser(ContentResolver cr, int userId) {
+            int mode = getIntForUser(cr, Settings.Secure.LOCATION_PREVIOUS_MODE,
+                    LOCATION_MODE_HIGH_ACCURACY, userId);
+            // Make sure that the previous mode is never "off". Otherwise the user won't be able to
+            // turn on location any longer.
+            if (mode == LOCATION_MODE_OFF) {
+                mode = LOCATION_MODE_HIGH_ACCURACY;
+            }
+            return setLocationModeForUser(cr, mode, userId);
+        }
+
+        /**
          * Thread-safe method for setting the location mode to one of
          * {@link #LOCATION_MODE_HIGH_ACCURACY}, {@link #LOCATION_MODE_SENSORS_ONLY},
          * {@link #LOCATION_MODE_BATTERY_SAVING}, or {@link #LOCATION_MODE_OFF}.
@@ -5899,7 +5933,11 @@
                 boolean gps = false;
                 boolean network = false;
                 switch (mode) {
+                    case LOCATION_MODE_PREVIOUS:
+                        // Retrieve the actual mode and set to that mode.
+                        return restoreLocationModeForUser(cr, userId);
                     case LOCATION_MODE_OFF:
+                        saveLocationModeForUser(cr, userId);
                         break;
                     case LOCATION_MODE_SENSORS_ONLY:
                         gps = true;
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 93a8fd8..0917528 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -110,7 +110,7 @@
         // 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 mode = enabled
-                ? Settings.Secure.LOCATION_MODE_HIGH_ACCURACY : Settings.Secure.LOCATION_MODE_OFF;
+                ? 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