| 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);
|
| + }
|
| +}
|
|
|