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

Side by Side Diff: device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderAndroid.java

Issue 2809813002: GeoLocation: add support for GmsCore location provider (Closed)
Patch Set: reillyg@ nit Created 3 years, 8 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 unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.device.geolocation; 5 package org.chromium.device.geolocation;
6 6
7 import android.content.Context; 7 import android.content.Context;
8 import android.location.Criteria; 8 import android.location.Criteria;
9 import android.location.Location; 9 import android.location.Location;
10 import android.location.LocationListener; 10 import android.location.LocationListener;
11 import android.location.LocationManager; 11 import android.location.LocationManager;
12 import android.os.Bundle; 12 import android.os.Bundle;
13 13
14 import org.chromium.base.Log; 14 import org.chromium.base.Log;
15 import org.chromium.base.ThreadUtils; 15 import org.chromium.base.ThreadUtils;
16 import org.chromium.base.VisibleForTesting;
16 17
17 import java.util.List; 18 import java.util.List;
18 19
19 /** 20 /**
20 * This is a LocationProvider using Android APIs [1]. It is a separate class for clarity 21 * This is a LocationProvider using Android APIs [1]. It is a separate class for clarity
21 * so that it can manage all processing completely on the UI thread. The contain er class 22 * so that it can manage all processing completely on the UI thread. The contain er class
22 * ensures that the start/stop calls into this class are done on the UI thread. 23 * ensures that the start/stop calls into this class are done on the UI thread.
23 * 24 *
24 * [1] https://developer.android.com/reference/android/location/package-summary. html 25 * [1] https://developer.android.com/reference/android/location/package-summary. html
25 */ 26 */
26 public class LocationProviderAndroid 27 public class LocationProviderAndroid
27 implements LocationListener, LocationProviderFactory.LocationProvider { 28 implements LocationListener, LocationProviderFactory.LocationProvider {
28 private static final String TAG = "cr_LocationProvider"; 29 private static final String TAG = "cr_LocationProvider";
29 30
30 private Context mContext; 31 private Context mContext;
31 private LocationManager mLocationManager; 32 private LocationManager mLocationManager;
32 private boolean mIsRunning; 33 private boolean mIsRunning;
33 34
34 LocationProviderAndroid(Context context) { 35 LocationProviderAndroid(Context context) {
35 mContext = context; 36 mContext = context;
36 } 37 }
37 38
38 @Override 39 @Override
39 public void start(boolean enableHighAccuracy) { 40 public void start(boolean enableHighAccuracy) {
41 ThreadUtils.assertOnUiThread();
40 unregisterFromLocationUpdates(); 42 unregisterFromLocationUpdates();
41 registerForLocationUpdates(enableHighAccuracy); 43 registerForLocationUpdates(enableHighAccuracy);
42 } 44 }
43 45
44 @Override 46 @Override
45 public void stop() { 47 public void stop() {
48 ThreadUtils.assertOnUiThread();
46 unregisterFromLocationUpdates(); 49 unregisterFromLocationUpdates();
47 } 50 }
48 51
49 @Override 52 @Override
50 public boolean isRunning() { 53 public boolean isRunning() {
54 ThreadUtils.assertOnUiThread();
51 return mIsRunning; 55 return mIsRunning;
52 } 56 }
53 57
54 @Override 58 @Override
55 public void onLocationChanged(Location location) { 59 public void onLocationChanged(Location location) {
56 // Callbacks from the system location service are queued to this thread, so it's 60 // Callbacks from the system location service are queued to this thread, so it's
57 // possible that we receive callbacks after unregistering. At this point , the 61 // possible that we receive callbacks after unregistering. At this point , the
58 // native object will no longer exist. 62 // native object will no longer exist.
59 if (mIsRunning) { 63 if (mIsRunning) {
60 updateNewLocation(location); 64 LocationProviderAdapter.onNewLocationAvailable(location);
61 } 65 }
62 } 66 }
63 67
64 @Override 68 @Override
65 public void onStatusChanged(String provider, int status, Bundle extras) {} 69 public void onStatusChanged(String provider, int status, Bundle extras) {}
66 70
67 @Override 71 @Override
68 public void onProviderEnabled(String provider) {} 72 public void onProviderEnabled(String provider) {}
69 73
70 @Override 74 @Override
71 public void onProviderDisabled(String provider) {} 75 public void onProviderDisabled(String provider) {}
72 76
73 private void ensureLocationManagerCreated() { 77 @VisibleForTesting
78 public void setLocationManagerForTesting(LocationManager manager) {
79 mLocationManager = manager;
80 }
81
82 private void createLocationManagerIfNeeded() {
74 if (mLocationManager != null) return; 83 if (mLocationManager != null) return;
75 mLocationManager = (LocationManager) mContext.getSystemService(Context.L OCATION_SERVICE); 84 mLocationManager = (LocationManager) mContext.getSystemService(Context.L OCATION_SERVICE);
76 if (mLocationManager == null) { 85 if (mLocationManager == null) {
77 Log.e(TAG, "Could not get location manager."); 86 Log.e(TAG, "Could not get location manager.");
78 } 87 }
79 } 88 }
80 89
81 /** 90 /**
82 * Registers this object with the location service. 91 * Registers this object with the location service.
83 */ 92 */
84 private void registerForLocationUpdates(boolean enableHighAccuracy) { 93 private void registerForLocationUpdates(boolean enableHighAccuracy) {
85 ensureLocationManagerCreated(); 94 createLocationManagerIfNeeded();
86 if (usePassiveOneShotLocation()) return; 95 if (usePassiveOneShotLocation()) return;
87 96
88 assert !mIsRunning; 97 assert !mIsRunning;
89 mIsRunning = true; 98 mIsRunning = true;
90 99
91 // We're running on the main thread. The C++ side is responsible to 100 // We're running on the main thread. The C++ side is responsible to
92 // bounce notifications to the Geolocation thread as they arrive in the mainLooper. 101 // bounce notifications to the Geolocation thread as they arrive in the mainLooper.
93 try { 102 try {
94 Criteria criteria = new Criteria(); 103 Criteria criteria = new Criteria();
95 if (enableHighAccuracy) criteria.setAccuracy(Criteria.ACCURACY_FINE) ; 104 if (enableHighAccuracy) criteria.setAccuracy(Criteria.ACCURACY_FINE) ;
96 mLocationManager.requestLocationUpdates( 105 mLocationManager.requestLocationUpdates(
97 0, 0, criteria, this, ThreadUtils.getUiThreadLooper()); 106 0, 0, criteria, this, ThreadUtils.getUiThreadLooper());
98 } catch (SecurityException e) { 107 } catch (SecurityException e) {
99 Log.e(TAG, 108 Log.e(TAG,
100 "Caught security exception while registering for location up dates " 109 "Caught security exception while registering for location up dates "
101 + "from the system. The application does not have su fficient " 110 + "from the system. The application does not have su fficient "
102 + "geolocation permissions."); 111 + "geolocation permissions.");
103 unregisterFromLocationUpdates(); 112 unregisterFromLocationUpdates();
104 // Propagate an error to JavaScript, this can happen in case of WebV iew 113 // Propagate an error to JavaScript, this can happen in case of WebV iew
105 // when the embedding app does not have sufficient permissions. 114 // when the embedding app does not have sufficient permissions.
106 LocationProviderAdapter.newErrorAvailable("application does not have sufficient " 115 LocationProviderAdapter.newErrorAvailable(
107 + "geolocation permissions."); 116 "application does not have sufficient geolocation permission s.");
108 } catch (IllegalArgumentException e) { 117 } catch (IllegalArgumentException e) {
109 Log.e(TAG, "Caught IllegalArgumentException registering for location updates."); 118 Log.e(TAG, "Caught IllegalArgumentException registering for location updates.");
110 unregisterFromLocationUpdates(); 119 unregisterFromLocationUpdates();
111 assert false; 120 assert false;
112 } 121 }
113 } 122 }
114 123
115 /** 124 /**
116 * Unregisters this object from the location service. 125 * Unregisters this object from the location service.
117 */ 126 */
118 private void unregisterFromLocationUpdates() { 127 private void unregisterFromLocationUpdates() {
119 if (mIsRunning) { 128 if (!mIsRunning) return;
120 mIsRunning = false; 129 mIsRunning = false;
121 mLocationManager.removeUpdates(this); 130 mLocationManager.removeUpdates(this);
122 }
123 }
124
125 private void updateNewLocation(Location location) {
126 LocationProviderAdapter.newLocationAvailable(location.getLatitude(),
127 location.getLongitude(), location.getTime() / 1000.0, location.h asAltitude(),
128 location.getAltitude(), location.hasAccuracy(), location.getAccu racy(),
129 location.hasBearing(), location.getBearing(), location.hasSpeed( ),
130 location.getSpeed());
131 } 131 }
132 132
133 private boolean usePassiveOneShotLocation() { 133 private boolean usePassiveOneShotLocation() {
134 if (!isOnlyPassiveLocationProviderEnabled()) return false; 134 if (!isOnlyPassiveLocationProviderEnabled()) {
135 return false;
136 }
135 137
136 // Do not request a location update if the only available location provi der is 138 // Do not request a location update if the only available location provi der is
137 // the passive one. Make use of the last known location and call 139 // the passive one. Make use of the last known location and call
138 // onLocationChanged directly. 140 // onNewLocationAvailable directly.
139 final Location location = 141 final Location location =
140 mLocationManager.getLastKnownLocation(LocationManager.PASSIVE_PR OVIDER); 142 mLocationManager.getLastKnownLocation(LocationManager.PASSIVE_PR OVIDER);
141 if (location != null) { 143 if (location != null) {
142 ThreadUtils.runOnUiThread(new Runnable() { 144 ThreadUtils.runOnUiThread(new Runnable() {
143 @Override 145 @Override
144 public void run() { 146 public void run() {
145 updateNewLocation(location); 147 LocationProviderAdapter.onNewLocationAvailable(location);
146 } 148 }
147 }); 149 });
148 } 150 }
149 return true; 151 return true;
150 } 152 }
151 153
152 /* 154 /*
153 * Checks if the passive location provider is the only provider available 155 * Checks if the passive location provider is the only provider available
154 * in the system. 156 * in the system.
155 */ 157 */
156 private boolean isOnlyPassiveLocationProviderEnabled() { 158 private boolean isOnlyPassiveLocationProviderEnabled() {
157 List<String> providers = mLocationManager.getProviders(true); 159 final List<String> providers = mLocationManager.getProviders(true);
158 return providers != null && providers.size() == 1 160 return providers != null && providers.size() == 1
159 && providers.get(0).equals(LocationManager.PASSIVE_PROVIDER); 161 && providers.get(0).equals(LocationManager.PASSIVE_PROVIDER);
160 } 162 }
161 } 163 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698