| Index: device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderFactory.java
|
| diff --git a/device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderFactory.java b/device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderFactory.java
|
| index 817ca49f86106cea7a09d9f1f619f5ff2f2af4d2..3ffc36af9dbcdfa4e6d41a423772a568009bad44 100644
|
| --- a/device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderFactory.java
|
| +++ b/device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderFactory.java
|
| @@ -5,18 +5,9 @@
|
| package org.chromium.device.geolocation;
|
|
|
| import android.content.Context;
|
| -import android.location.Criteria;
|
| -import android.location.Location;
|
| -import android.location.LocationListener;
|
| -import android.location.LocationManager;
|
| -import android.os.Bundle;
|
|
|
| -import org.chromium.base.Log;
|
| -import org.chromium.base.ThreadUtils;
|
| import org.chromium.base.VisibleForTesting;
|
|
|
| -import java.util.List;
|
| -
|
| /**
|
| * Factory to create a LocationProvider to allow us to inject
|
| * a mock for tests.
|
| @@ -25,179 +16,38 @@ public class LocationProviderFactory {
|
| private static LocationProviderFactory.LocationProvider sProviderImpl;
|
|
|
| /**
|
| - * LocationProviderFactory.get() returns an instance of this interface.
|
| + * LocationProviderFactory.create() returns an instance of this interface.
|
| */
|
| public interface LocationProvider {
|
| - public void start(boolean enableHighAccuracy);
|
| - public void stop();
|
| - public boolean isRunning();
|
| - }
|
| -
|
| - private LocationProviderFactory() {}
|
| -
|
| - @VisibleForTesting
|
| - public static void setLocationProviderImpl(LocationProviderFactory.LocationProvider provider) {
|
| - assert sProviderImpl == null;
|
| - sProviderImpl = provider;
|
| - }
|
| -
|
| - public static LocationProvider get(Context context) {
|
| - if (sProviderImpl == null) {
|
| - sProviderImpl = new LocationProviderImpl(context);
|
| - }
|
| - return sProviderImpl;
|
| - }
|
| -
|
| - /**
|
| - * This is the core of android location provider. It is a separate class for clarity
|
| - * so that it can manage all processing completely in the UI thread. The container class
|
| - * ensures that the start/stop calls into this class are done in the UI thread.
|
| - */
|
| - private static class LocationProviderImpl
|
| - implements LocationListener, LocationProviderFactory.LocationProvider {
|
| - // Log tag
|
| - private static final String TAG = "cr_LocationProvider";
|
| -
|
| - private Context mContext;
|
| - private LocationManager mLocationManager;
|
| - private boolean mIsRunning;
|
| -
|
| - LocationProviderImpl(Context context) {
|
| - mContext = context;
|
| - }
|
| -
|
| /**
|
| * Start listening for location updates.
|
| * @param enableHighAccuracy Whether or not to enable high accuracy location providers.
|
| */
|
| - @Override
|
| - public void start(boolean enableHighAccuracy) {
|
| - unregisterFromLocationUpdates();
|
| - registerForLocationUpdates(enableHighAccuracy);
|
| - }
|
| + public void start(boolean enableHighAccuracy);
|
|
|
| /**
|
| * Stop listening for location updates.
|
| */
|
| - @Override
|
| - public void stop() {
|
| - unregisterFromLocationUpdates();
|
| - }
|
| + public void stop();
|
|
|
| /**
|
| * Returns true if we are currently listening for location updates, false if not.
|
| */
|
| - @Override
|
| - public boolean isRunning() {
|
| - return mIsRunning;
|
| - }
|
| -
|
| - @Override
|
| - public void onLocationChanged(Location location) {
|
| - // Callbacks from the system location service are queued to this thread, so it's
|
| - // possible that we receive callbacks after unregistering. At this point, the
|
| - // native object will no longer exist.
|
| - if (mIsRunning) {
|
| - updateNewLocation(location);
|
| - }
|
| - }
|
| -
|
| - private void updateNewLocation(Location location) {
|
| - LocationProviderAdapter.newLocationAvailable(location.getLatitude(),
|
| - location.getLongitude(), location.getTime() / 1000.0, location.hasAltitude(),
|
| - location.getAltitude(), location.hasAccuracy(), location.getAccuracy(),
|
| - location.hasBearing(), location.getBearing(), location.hasSpeed(),
|
| - location.getSpeed());
|
| - }
|
| -
|
| - @Override
|
| - public void onStatusChanged(String provider, int status, Bundle extras) {}
|
| -
|
| - @Override
|
| - public void onProviderEnabled(String provider) {}
|
| -
|
| - @Override
|
| - public void onProviderDisabled(String provider) {}
|
| -
|
| - private void ensureLocationManagerCreated() {
|
| - if (mLocationManager != null) return;
|
| - mLocationManager =
|
| - (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
|
| - if (mLocationManager == null) {
|
| - Log.e(TAG, "Could not get location manager.");
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Registers this object with the location service.
|
| - */
|
| - private void registerForLocationUpdates(boolean enableHighAccuracy) {
|
| - ensureLocationManagerCreated();
|
| - if (usePassiveOneShotLocation()) return;
|
| -
|
| - assert !mIsRunning;
|
| - mIsRunning = true;
|
| -
|
| - // We're running on the main thread. The C++ side is responsible to
|
| - // bounce notifications to the Geolocation thread as they arrive in the mainLooper.
|
| - try {
|
| - Criteria criteria = new Criteria();
|
| - if (enableHighAccuracy) criteria.setAccuracy(Criteria.ACCURACY_FINE);
|
| - mLocationManager.requestLocationUpdates(
|
| - 0, 0, criteria, this, ThreadUtils.getUiThreadLooper());
|
| - } catch (SecurityException e) {
|
| - Log.e(TAG, "Caught security exception while registering for location updates "
|
| - + "from the system. The application does not have sufficient "
|
| - + "geolocation permissions.");
|
| - unregisterFromLocationUpdates();
|
| - // Propagate an error to JavaScript, this can happen in case of WebView
|
| - // when the embedding app does not have sufficient permissions.
|
| - LocationProviderAdapter.newErrorAvailable("application does not have sufficient "
|
| - + "geolocation permissions.");
|
| - } catch (IllegalArgumentException e) {
|
| - Log.e(TAG, "Caught IllegalArgumentException registering for location updates.");
|
| - unregisterFromLocationUpdates();
|
| - assert false;
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Unregisters this object from the location service.
|
| - */
|
| - private void unregisterFromLocationUpdates() {
|
| - if (mIsRunning) {
|
| - mIsRunning = false;
|
| - mLocationManager.removeUpdates(this);
|
| - }
|
| - }
|
| + public boolean isRunning();
|
| + }
|
|
|
| - private boolean usePassiveOneShotLocation() {
|
| - if (!isOnlyPassiveLocationProviderEnabled()) return false;
|
| + private LocationProviderFactory() {}
|
|
|
| - // Do not request a location update if the only available location provider is
|
| - // the passive one. Make use of the last known location and call
|
| - // onLocationChanged directly.
|
| - final Location location =
|
| - mLocationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
|
| - if (location != null) {
|
| - ThreadUtils.runOnUiThread(new Runnable() {
|
| - @Override
|
| - public void run() {
|
| - updateNewLocation(location);
|
| - }
|
| - });
|
| - }
|
| - return true;
|
| - }
|
| + @VisibleForTesting
|
| + public static void setLocationProviderImpl(LocationProviderFactory.LocationProvider provider) {
|
| + assert sProviderImpl == null;
|
| + sProviderImpl = provider;
|
| + }
|
|
|
| - /*
|
| - * Checks if the passive location provider is the only provider available
|
| - * in the system.
|
| - */
|
| - private boolean isOnlyPassiveLocationProviderEnabled() {
|
| - List<String> providers = mLocationManager.getProviders(true);
|
| - return providers != null && providers.size() == 1
|
| - && providers.get(0).equals(LocationManager.PASSIVE_PROVIDER);
|
| + public static LocationProvider create(Context context) {
|
| + if (sProviderImpl == null) {
|
| + sProviderImpl = new LocationProviderAndroid(context);
|
| }
|
| + return sProviderImpl;
|
| }
|
| }
|
|
|