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

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

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

Powered by Google App Engine
This is Rietveld 408576698