201 lines
7.2 KiB
Java
201 lines
7.2 KiB
Java
|
/*
|
||
|
* Copyright (C) 2009 The Android Open Source Project
|
||
|
* Copyright (c) 2011, The Linux Foundation. All rights reserved.
|
||
|
*
|
||
|
* 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.");
|
||
|
} catch(IllegalArgumentException e) {
|
||
|
Log.e(TAG, "Caught IllegalArugument Exception: Either provider or listener is null");
|
||
|
e.printStackTrace();
|
||
|
} catch (RuntimeException e) {
|
||
|
Log.e(TAG, "Caught RuntimeException");
|
||
|
e.printStackTrace();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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);
|
||
|
}
|