blob: 646f8c507d36a48f7c05aba8c2c59be00e33493a [file] [log] [blame]
Steve Block67e1eb62009-07-31 09:06:59 +01001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.webkit;
18
19import android.app.ActivityThread;
20import android.content.Context;
21import android.location.Location;
22import android.location.LocationListener;
23import android.location.LocationManager;
24import android.location.LocationProvider;
25import android.os.Bundle;
26import android.util.Log;
27import android.webkit.WebView;
28import android.webkit.WebViewCore;
29
30
31/**
32 * Implements the Java side of GeolocationServiceAndroid.
33 * @hide Pending API council review.
34 */
35public final class GeolocationService implements LocationListener {
36
37 // Log tag
38 private static final String TAG = "geolocationService";
39
40 private long mNativeObject;
41 private LocationManager mLocationManager;
42 private boolean mIsGpsEnabled;
43 private boolean mIsRunning;
44 private boolean mIsNetworkProviderAvailable;
45 private boolean mIsGpsProviderAvailable;
46
47 /**
48 * Constructor
49 * @param nativeObject The native object to which this object will report position updates and
50 * errors.
51 */
52 public GeolocationService(long nativeObject) {
53 mNativeObject = nativeObject;
54 // Register newLocationAvailable with platform service.
55 ActivityThread thread = ActivityThread.systemMain();
56 Context context = thread.getApplication();
57 mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
58 if (mLocationManager == null) {
59 Log.e(TAG, "Could not get location manager.");
60 }
61 }
62
63 /**
64 * Start listening for location updates.
65 */
66 public void start() {
67 registerForLocationUpdates();
68 mIsRunning = true;
69 }
70
71 /**
72 * Stop listening for location updates.
73 */
74 public void stop() {
75 unregisterFromLocationUpdates();
76 mIsRunning = false;
77 }
78
79 /**
80 * Sets whether to use the GPS.
81 * @param enable Whether to use the GPS.
82 */
83 public void setEnableGps(boolean enable) {
84 if (mIsGpsEnabled != enable) {
85 mIsGpsEnabled = enable;
86 if (mIsRunning) {
87 // There's no way to unregister from a single provider, so we can
88 // only unregister from all, then reregister with all but the GPS.
89 unregisterFromLocationUpdates();
90 registerForLocationUpdates();
91 }
92 }
93 }
94
95 /**
96 * LocationListener implementation.
97 * Called when the location has changed.
98 * @param location The new location, as a Location object.
99 */
100 public void onLocationChanged(Location location) {
101 // Callbacks from the system location sevice are queued to this thread, so it's possible
102 // that we receive callbacks after unregistering. At this point, the native object will no
103 // longer exist.
104 if (mIsRunning) {
105 nativeNewLocationAvailable(mNativeObject, location);
106 }
107 }
108
109 /**
110 * LocationListener implementation.
111 * Called when the provider status changes.
112 * @param provider The name of the provider.
113 * @param status The new status of the provider.
114 * @param extras an optional Bundle with provider specific data.
115 */
116 public void onStatusChanged(String providerName, int status, Bundle extras) {
117 boolean isAvailable = (status == LocationProvider.AVAILABLE);
118 if (LocationManager.NETWORK_PROVIDER.equals(providerName)) {
119 mIsNetworkProviderAvailable = isAvailable;
120 } else if (LocationManager.GPS_PROVIDER.equals(providerName)) {
121 mIsGpsProviderAvailable = isAvailable;
122 }
123 maybeReportError("The last location provider is no longer available");
124 }
125
126 /**
127 * LocationListener implementation.
128 * Called when the provider is enabled.
129 * @param provider The name of the location provider that is now enabled.
130 */
131 public void onProviderEnabled(String providerName) {
132 // No need to notify the native side. It's enough to start sending
133 // valid position fixes again.
134 if (LocationManager.NETWORK_PROVIDER.equals(providerName)) {
135 mIsNetworkProviderAvailable = true;
136 } else if (LocationManager.GPS_PROVIDER.equals(providerName)) {
137 mIsGpsProviderAvailable = true;
138 }
139 }
140
141 /**
142 * LocationListener implementation.
143 * Called when the provider is disabled.
144 * @param provider The name of the location provider that is now disabled.
145 */
146 public void onProviderDisabled(String providerName) {
147 if (LocationManager.NETWORK_PROVIDER.equals(providerName)) {
148 mIsNetworkProviderAvailable = false;
149 } else if (LocationManager.GPS_PROVIDER.equals(providerName)) {
150 mIsGpsProviderAvailable = false;
151 }
152 maybeReportError("The last location provider was disabled");
153 }
154
155 /**
156 * Registers this object with the location service.
157 */
158 private void registerForLocationUpdates() {
Steve Block4afcd2e2009-09-03 11:41:29 +0100159 try {
160 mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
161 mIsNetworkProviderAvailable = true;
162 if (mIsGpsEnabled) {
163 mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
164 mIsGpsProviderAvailable = true;
165 }
166 } catch(SecurityException e) {
167 Log.e(TAG, "Caught security exception registering for location updates from system. " +
168 "This should only happen in DumpRenderTree.");
Steve Block67e1eb62009-07-31 09:06:59 +0100169 }
170 }
171
172 /**
173 * Unregisters this object from the location service.
174 */
175 private void unregisterFromLocationUpdates() {
176 mLocationManager.removeUpdates(this);
177 }
178
179 /**
180 * Reports an error if neither the network nor the GPS provider is available.
181 */
182 private void maybeReportError(String message) {
183 // Callbacks from the system location sevice are queued to this thread, so it's possible
184 // that we receive callbacks after unregistering. At this point, the native object will no
185 // longer exist.
186 if (mIsRunning && !mIsNetworkProviderAvailable && !mIsGpsProviderAvailable) {
187 nativeNewErrorAvailable(mNativeObject, message);
188 }
189 }
190
191 // Native functions
192 private static native void nativeNewLocationAvailable(long nativeObject, Location location);
193 private static native void nativeNewErrorAvailable(long nativeObject, String message);
194}