Index: device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderGmsCore.java |
diff --git a/device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderGmsCore.java b/device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderGmsCore.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..aed6822628075ad7b58ae0f5a21f8b40d6e8299d |
--- /dev/null |
+++ b/device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderGmsCore.java |
@@ -0,0 +1,136 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.device.geolocation; |
+ |
+import android.content.Context; |
+import android.location.Location; |
+import android.os.Bundle; |
+ |
+import com.google.android.gms.common.ConnectionResult; |
+import com.google.android.gms.common.GoogleApiAvailability; |
+import com.google.android.gms.common.api.GoogleApiClient; |
+import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; |
+import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener; |
+import com.google.android.gms.location.FusedLocationProviderApi; |
+import com.google.android.gms.location.LocationListener; |
+import com.google.android.gms.location.LocationRequest; |
+import com.google.android.gms.location.LocationServices; |
+ |
+import org.chromium.base.Log; |
+import org.chromium.base.ThreadUtils; |
+ |
+/** |
+ * This is a LocationProvider using Google Play Services. |
+ * |
+ * https://developers.google.com/android/reference/com/google/android/gms/location/package-summary |
+ */ |
+public class LocationProviderGmsCore implements ConnectionCallbacks, OnConnectionFailedListener, |
+ LocationListener, |
+ LocationProviderFactory.LocationProvider { |
+ private static final String TAG = "cr_LocationProvider"; |
+ |
+ // Values for the LocationRequest's setInterval for normal and high accuracy, respectively. |
+ private static final long UPDATE_INTERVAL_MS = 1000; |
+ private static final long UPDATE_INTERVAL_FAST_MS = 500; |
+ |
+ private final GoogleApiClient mGoogleApiClient; |
+ private FusedLocationProviderApi mLocationProviderApi = LocationServices.FusedLocationApi; |
+ |
+ private boolean mEnablehighAccuracy; |
+ private LocationRequest mLocationRequest; |
+ |
+ public static boolean isGooglePlayServicesAvailable(Context context) { |
+ return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) |
+ == ConnectionResult.SUCCESS; |
+ } |
+ |
+ LocationProviderGmsCore(Context context) { |
+ Log.i(TAG, "Google Play Services"); |
+ mGoogleApiClient = new GoogleApiClient.Builder(context) |
+ .addApi(LocationServices.API) |
+ .addConnectionCallbacks(this) |
+ .addOnConnectionFailedListener(this) |
+ .build(); |
+ assert mGoogleApiClient != null; |
+ } |
+ |
+ LocationProviderGmsCore(GoogleApiClient client, FusedLocationProviderApi locationApi) { |
+ mGoogleApiClient = client; |
+ mLocationProviderApi = locationApi; |
+ } |
+ |
+ // ConnectionCallbacks implementation |
+ @Override |
+ public void onConnected(Bundle connectionHint) { |
+ ThreadUtils.assertOnUiThread(); |
+ |
+ mLocationRequest = LocationRequest.create(); |
+ if (mEnablehighAccuracy) { |
+ mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) |
+ .setInterval(UPDATE_INTERVAL_FAST_MS); |
+ } else { |
+ mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY) |
+ .setInterval(UPDATE_INTERVAL_MS); |
+ } |
+ |
+ final Location location = mLocationProviderApi.getLastLocation(mGoogleApiClient); |
+ if (location != null) { |
+ LocationProviderAdapter.onNewLocationAvailable(location); |
+ } |
+ |
+ try { |
+ // Request updates on UI Thread replicating LocationProviderAndroid's behaviour. |
+ mLocationProviderApi.requestLocationUpdates( |
+ mGoogleApiClient, mLocationRequest, this, ThreadUtils.getUiThreadLooper()); |
+ } catch (IllegalStateException e) { |
+ // Happens "If this method is executed in a thread that has not called Looper.prepare()" |
+ Log.e(TAG, "Unexpected exception " + e); |
+ assert false; |
+ } |
+ } |
+ |
+ @Override |
+ public void onConnectionSuspended(int cause) {} |
+ |
+ // OnConnectionFailedListener implementation |
+ @Override |
+ public void onConnectionFailed(ConnectionResult result) { |
+ LocationProviderAdapter.newErrorAvailable( |
+ "Failed to connect to Google Play Services: " + result.toString()); |
+ } |
+ |
+ // LocationProviderFactory.LocationProvider implementation |
+ @Override |
+ public void start(boolean enableHighAccuracy) { |
+ ThreadUtils.assertOnUiThread(); |
+ if (mGoogleApiClient.isConnected()) mGoogleApiClient.disconnect(); |
+ |
+ mEnablehighAccuracy = enableHighAccuracy; |
+ mGoogleApiClient.connect(); // Should return via onConnected(). |
+ } |
+ |
+ @Override |
+ public void stop() { |
+ ThreadUtils.assertOnUiThread(); |
+ if (!mGoogleApiClient.isConnected()) return; |
+ |
+ mLocationProviderApi.removeLocationUpdates(mGoogleApiClient, this); |
+ |
+ mGoogleApiClient.disconnect(); |
+ } |
+ |
+ @Override |
+ public boolean isRunning() { |
+ assert ThreadUtils.runningOnUiThread(); |
+ if (mGoogleApiClient == null) return false; |
+ return mGoogleApiClient.isConnecting() || mGoogleApiClient.isConnected(); |
+ } |
+ |
+ // LocationListener implementation |
+ @Override |
+ public void onLocationChanged(Location location) { |
+ LocationProviderAdapter.onNewLocationAvailable(location); |
+ } |
+} |