diff options
Diffstat (limited to 'core/java/android/webkit/GeolocationService.java')
-rwxr-xr-x | core/java/android/webkit/GeolocationService.java | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/core/java/android/webkit/GeolocationService.java b/core/java/android/webkit/GeolocationService.java new file mode 100755 index 0000000..24306f4 --- /dev/null +++ b/core/java/android/webkit/GeolocationService.java @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.webkit; + +import android.app.ActivityThread; +import android.content.Context; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.location.LocationProvider; +import android.os.Bundle; +import android.util.Log; +import android.webkit.WebView; +import android.webkit.WebViewCore; + + +/** + * Implements the Java side of GeolocationServiceAndroid. + */ +final class GeolocationService implements LocationListener { + + // Log tag + private static final String TAG = "geolocationService"; + + private long mNativeObject; + private LocationManager mLocationManager; + private boolean mIsGpsEnabled; + private boolean mIsRunning; + private boolean mIsNetworkProviderAvailable; + private boolean mIsGpsProviderAvailable; + + /** + * Constructor + * @param nativeObject The native object to which this object will report position updates and + * errors. + */ + public GeolocationService(long nativeObject) { + mNativeObject = nativeObject; + // Register newLocationAvailable with platform service. + ActivityThread thread = ActivityThread.systemMain(); + Context context = thread.getApplication(); + mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + if (mLocationManager == null) { + Log.e(TAG, "Could not get location manager."); + } + } + + /** + * Start listening for location updates. + */ + public void start() { + registerForLocationUpdates(); + mIsRunning = true; + } + + /** + * Stop listening for location updates. + */ + public void stop() { + unregisterFromLocationUpdates(); + mIsRunning = false; + } + + /** + * Sets whether to use the GPS. + * @param enable Whether to use the GPS. + */ + public void setEnableGps(boolean enable) { + if (mIsGpsEnabled != enable) { + mIsGpsEnabled = enable; + if (mIsRunning) { + // There's no way to unregister from a single provider, so we can + // only unregister from all, then reregister with all but the GPS. + unregisterFromLocationUpdates(); + registerForLocationUpdates(); + } + } + } + + /** + * LocationListener implementation. + * Called when the location has changed. + * @param location The new location, as a Location object. + */ + public void onLocationChanged(Location location) { + // Callbacks from the system location sevice are queued to this thread, so it's possible + // that we receive callbacks after unregistering. At this point, the native object will no + // longer exist. + if (mIsRunning) { + nativeNewLocationAvailable(mNativeObject, location); + } + } + + /** + * LocationListener implementation. + * Called when the provider status changes. + * @param provider The name of the provider. + * @param status The new status of the provider. + * @param extras an optional Bundle with provider specific data. + */ + public void onStatusChanged(String providerName, int status, Bundle extras) { + boolean isAvailable = (status == LocationProvider.AVAILABLE); + if (LocationManager.NETWORK_PROVIDER.equals(providerName)) { + mIsNetworkProviderAvailable = isAvailable; + } else if (LocationManager.GPS_PROVIDER.equals(providerName)) { + mIsGpsProviderAvailable = isAvailable; + } + maybeReportError("The last location provider is no longer available"); + } + + /** + * LocationListener implementation. + * Called when the provider is enabled. + * @param provider The name of the location provider that is now enabled. + */ + public void onProviderEnabled(String providerName) { + // No need to notify the native side. It's enough to start sending + // valid position fixes again. + if (LocationManager.NETWORK_PROVIDER.equals(providerName)) { + mIsNetworkProviderAvailable = true; + } else if (LocationManager.GPS_PROVIDER.equals(providerName)) { + mIsGpsProviderAvailable = true; + } + } + + /** + * LocationListener implementation. + * Called when the provider is disabled. + * @param provider The name of the location provider that is now disabled. + */ + public void onProviderDisabled(String providerName) { + if (LocationManager.NETWORK_PROVIDER.equals(providerName)) { + mIsNetworkProviderAvailable = false; + } else if (LocationManager.GPS_PROVIDER.equals(providerName)) { + mIsGpsProviderAvailable = false; + } + maybeReportError("The last location provider was disabled"); + } + + /** + * Registers this object with the location service. + */ + private void registerForLocationUpdates() { + try { + mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); + mIsNetworkProviderAvailable = true; + if (mIsGpsEnabled) { + mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); + mIsGpsProviderAvailable = true; + } + } catch(SecurityException e) { + Log.e(TAG, "Caught security exception registering for location updates from system. " + + "This should only happen in DumpRenderTree."); + } + } + + /** + * Unregisters this object from the location service. + */ + private void unregisterFromLocationUpdates() { + mLocationManager.removeUpdates(this); + } + + /** + * Reports an error if neither the network nor the GPS provider is available. + */ + private void maybeReportError(String message) { + // Callbacks from the system location sevice are queued to this thread, so it's possible + // that we receive callbacks after unregistering. At this point, the native object will no + // longer exist. + if (mIsRunning && !mIsNetworkProviderAvailable && !mIsGpsProviderAvailable) { + nativeNewErrorAvailable(mNativeObject, message); + } + } + + // Native functions + private static native void nativeNewLocationAvailable(long nativeObject, Location location); + private static native void nativeNewErrorAvailable(long nativeObject, String message); +} |