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

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

Issue 2797903002: Geolocation Android: split LocationProviderAndroid out of LocationProviderFactory (Closed)
Patch Set: 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
« no previous file with comments | « device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderAndroid.java ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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;
9 import android.location.Location;
10 import android.location.LocationListener;
11 import android.location.LocationManager;
12 import android.os.Bundle;
13 8
14 import org.chromium.base.Log;
15 import org.chromium.base.ThreadUtils;
16 import org.chromium.base.VisibleForTesting; 9 import org.chromium.base.VisibleForTesting;
17 10
18 import java.util.List;
19
20 /** 11 /**
21 * Factory to create a LocationProvider to allow us to inject 12 * Factory to create a LocationProvider to allow us to inject
22 * a mock for tests. 13 * a mock for tests.
23 */ 14 */
24 public class LocationProviderFactory { 15 public class LocationProviderFactory {
25 private static LocationProviderFactory.LocationProvider sProviderImpl; 16 private static LocationProviderFactory.LocationProvider sProviderImpl;
26 17
27 /** 18 /**
28 * LocationProviderFactory.get() returns an instance of this interface. 19 * LocationProviderFactory.create() returns an instance of this interface.
29 */ 20 */
30 public interface LocationProvider { 21 public interface LocationProvider {
22 /**
23 * Start listening for location updates.
24 * @param enableHighAccuracy Whether or not to enable high accuracy loca tion providers.
25 */
31 public void start(boolean enableHighAccuracy); 26 public void start(boolean enableHighAccuracy);
27
28 /**
29 * Stop listening for location updates.
30 */
32 public void stop(); 31 public void stop();
32
33 /**
34 * Returns true if we are currently listening for location updates, fals e if not.
35 */
33 public boolean isRunning(); 36 public boolean isRunning();
34 } 37 }
35 38
36 private LocationProviderFactory() {} 39 private LocationProviderFactory() {}
37 40
38 @VisibleForTesting 41 @VisibleForTesting
39 public static void setLocationProviderImpl(LocationProviderFactory.LocationP rovider provider) { 42 public static void setLocationProviderImpl(LocationProviderFactory.LocationP rovider provider) {
40 assert sProviderImpl == null; 43 assert sProviderImpl == null;
41 sProviderImpl = provider; 44 sProviderImpl = provider;
42 } 45 }
43 46
44 public static LocationProvider get(Context context) { 47 public static LocationProvider create(Context context) {
45 if (sProviderImpl == null) { 48 if (sProviderImpl == null) {
46 sProviderImpl = new LocationProviderImpl(context); 49 sProviderImpl = new LocationProviderAndroid(context);
47 } 50 }
48 return sProviderImpl; 51 return sProviderImpl;
49 } 52 }
50
51 /**
52 * This is the core of android location provider. It is a separate class for clarity
53 * so that it can manage all processing completely in the UI thread. The con tainer class
54 * ensures that the start/stop calls into this class are done in the UI thre ad.
55 */
56 private static class LocationProviderImpl
57 implements LocationListener, LocationProviderFactory.LocationProvide r {
58 // Log tag
59 private static final String TAG = "cr_LocationProvider";
60
61 private Context mContext;
62 private LocationManager mLocationManager;
63 private boolean mIsRunning;
64
65 LocationProviderImpl(Context context) {
66 mContext = context;
67 }
68
69 /**
70 * Start listening for location updates.
71 * @param enableHighAccuracy Whether or not to enable high accuracy loca tion providers.
72 */
73 @Override
74 public void start(boolean enableHighAccuracy) {
75 unregisterFromLocationUpdates();
76 registerForLocationUpdates(enableHighAccuracy);
77 }
78
79 /**
80 * Stop listening for location updates.
81 */
82 @Override
83 public void stop() {
84 unregisterFromLocationUpdates();
85 }
86
87 /**
88 * Returns true if we are currently listening for location updates, fals e if not.
89 */
90 @Override
91 public boolean isRunning() {
92 return mIsRunning;
93 }
94
95 @Override
96 public void onLocationChanged(Location location) {
97 // Callbacks from the system location service are queued to this thr ead, so it's
98 // possible that we receive callbacks after unregistering. At this p oint, the
99 // native object will no longer exist.
100 if (mIsRunning) {
101 updateNewLocation(location);
102 }
103 }
104
105 private void updateNewLocation(Location location) {
106 LocationProviderAdapter.newLocationAvailable(location.getLatitude(),
107 location.getLongitude(), location.getTime() / 1000.0, locati on.hasAltitude(),
108 location.getAltitude(), location.hasAccuracy(), location.get Accuracy(),
109 location.hasBearing(), location.getBearing(), location.hasSp eed(),
110 location.getSpeed());
111 }
112
113 @Override
114 public void onStatusChanged(String provider, int status, Bundle extras) {}
115
116 @Override
117 public void onProviderEnabled(String provider) {}
118
119 @Override
120 public void onProviderDisabled(String provider) {}
121
122 private void ensureLocationManagerCreated() {
123 if (mLocationManager != null) return;
124 mLocationManager =
125 (LocationManager) mContext.getSystemService(Context.LOCATION _SERVICE);
126 if (mLocationManager == null) {
127 Log.e(TAG, "Could not get location manager.");
128 }
129 }
130
131 /**
132 * Registers this object with the location service.
133 */
134 private void registerForLocationUpdates(boolean enableHighAccuracy) {
135 ensureLocationManagerCreated();
136 if (usePassiveOneShotLocation()) return;
137
138 assert !mIsRunning;
139 mIsRunning = true;
140
141 // We're running on the main thread. The C++ side is responsible to
142 // bounce notifications to the Geolocation thread as they arrive in the mainLooper.
143 try {
144 Criteria criteria = new Criteria();
145 if (enableHighAccuracy) criteria.setAccuracy(Criteria.ACCURACY_F INE);
146 mLocationManager.requestLocationUpdates(
147 0, 0, criteria, this, ThreadUtils.getUiThreadLooper());
148 } catch (SecurityException e) {
149 Log.e(TAG, "Caught security exception while registering for loca tion updates "
150 + "from the system. The application does not hav e sufficient "
151 + "geolocation permissions.");
152 unregisterFromLocationUpdates();
153 // Propagate an error to JavaScript, this can happen in case of WebView
154 // when the embedding app does not have sufficient permissions.
155 LocationProviderAdapter.newErrorAvailable("application does not have sufficient "
156 + "geolocation permissions.");
157 } catch (IllegalArgumentException e) {
158 Log.e(TAG, "Caught IllegalArgumentException registering for loca tion updates.");
159 unregisterFromLocationUpdates();
160 assert false;
161 }
162 }
163
164 /**
165 * Unregisters this object from the location service.
166 */
167 private void unregisterFromLocationUpdates() {
168 if (mIsRunning) {
169 mIsRunning = false;
170 mLocationManager.removeUpdates(this);
171 }
172 }
173
174 private boolean usePassiveOneShotLocation() {
175 if (!isOnlyPassiveLocationProviderEnabled()) return false;
176
177 // Do not request a location update if the only available location p rovider is
178 // the passive one. Make use of the last known location and call
179 // onLocationChanged directly.
180 final Location location =
181 mLocationManager.getLastKnownLocation(LocationManager.PASSIV E_PROVIDER);
182 if (location != null) {
183 ThreadUtils.runOnUiThread(new Runnable() {
184 @Override
185 public void run() {
186 updateNewLocation(location);
187 }
188 });
189 }
190 return true;
191 }
192
193 /*
194 * Checks if the passive location provider is the only provider availabl e
195 * in the system.
196 */
197 private boolean isOnlyPassiveLocationProviderEnabled() {
198 List<String> providers = mLocationManager.getProviders(true);
199 return providers != null && providers.size() == 1
200 && providers.get(0).equals(LocationManager.PASSIVE_PROVIDER) ;
201 }
202 }
203 } 53 }
OLDNEW
« no previous file with comments | « device/geolocation/android/java/src/org/chromium/device/geolocation/LocationProviderAndroid.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698