| /* |
| * 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); |
| } |