Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4590)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationTracker.java

Issue 2872653002: Include GPS location as a fallback. Only read it passively. (Closed)
Patch Set: Include GPS location as a fallback. Only read it passively. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationTracker.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationTracker.java
index dfac566a7f743e3a4f2a0683c7d519b53f460db1..076fb175b6aec14e391a2c45f888e0f9f8e875f1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationTracker.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationTracker.java
@@ -4,13 +4,17 @@
package org.chromium.chrome.browser.omnibox.geo;
+import android.Manifest;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
+import android.os.Process;
+import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.ThreadUtils;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.SuppressFBWarnings;
@@ -24,7 +28,8 @@ import org.chromium.base.annotations.SuppressFBWarnings;
class GeolocationTracker {
private static SelfCancelingListener sListener;
- private static Location sLocationForTesting;
+ private static Location sNetworkLocationForTesting;
+ private static Location sGpsLocationForTesting;
private static boolean sUseLocationForTesting;
private static class SelfCancelingListener implements LocationListener {
@@ -78,13 +83,37 @@ class GeolocationTracker {
}
/**
- * Returns the last known location from the network provider or null if none is available.
+ * Returns the last known location or null if none is available.
+ *
+ * @param includeGpsFallback Whether the gps provider should also be used as a fallback.
+ * Otherwise only the network provider will be used.
*/
- static Location getLastKnownLocation(Context context) {
- if (sUseLocationForTesting) return sLocationForTesting;
+ static Location getLastKnownLocation(Context context, boolean includeGpsFallback) {
+ if (sUseLocationForTesting) {
+ return chooseLocation(
+ sNetworkLocationForTesting, sGpsLocationForTesting, includeGpsFallback);
+ }
+
+ if (!hasPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)) {
+ // Do not call location manager without permissions
+ return null;
+ }
+
LocationManager locationManager =
(LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
- return locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
+ Location networkLocation =
+ locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
+ // If no GPS location has been request, just return the network location. For efficiency,
+ // don't even get the GPS location.
+ if (!includeGpsFallback) {
+ return networkLocation;
+ }
+ Location gpsLocation = null;
+ if (hasPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)) {
+ // Only try to get GPS location when ACCESS_FINE_LOCATION is granted.
+ gpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
+ }
+ return chooseLocation(networkLocation, gpsLocation, includeGpsFallback);
}
/**
@@ -96,6 +125,10 @@ class GeolocationTracker {
static void refreshLastKnownLocation(Context context, long maxAge) {
ThreadUtils.assertOnUiThread();
+ if (!hasPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)) {
+ return;
+ }
+
// We're still waiting for a location update.
if (sListener != null) return;
@@ -112,8 +145,30 @@ class GeolocationTracker {
}
@VisibleForTesting
- static void setLocationForTesting(Location location) {
- sLocationForTesting = location;
+ static void setLocationForTesting(
+ Location networkLocationForTesting, Location gpsLocationForTesting) {
+ sNetworkLocationForTesting = networkLocationForTesting;
+ sGpsLocationForTesting = gpsLocationForTesting;
sUseLocationForTesting = true;
}
+
+ private static boolean hasPermission(Context context, String permission) {
+ return ApiCompatibilityUtils.checkPermission(
+ context, permission, Process.myPid(), Process.myUid())
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
+ private static Location chooseLocation(
+ Location networkLocation, Location gpsLocation, boolean includeGpsFallback) {
+ if (!includeGpsFallback || gpsLocation == null) {
+ return networkLocation;
+ }
+
+ if (networkLocation == null) {
+ return gpsLocation;
+ }
+
+ // Both are not null, take the younger one.
+ return networkLocation.getTime() > gpsLocation.getTime() ? networkLocation : gpsLocation;
+ }
}

Powered by Google App Engine
This is Rietveld 408576698