Merge branch 'readonly-p4-master'

This commit is contained in:
Mike Lockwood
2009-04-03 08:26:05 -07:00
committed by The Android Open Source Project
8 changed files with 179 additions and 220 deletions

View File

@@ -53,6 +53,9 @@ interface ILocationManager
boolean isProviderEnabled(String provider);
Location getLastKnownLocation(String provider);
/* used by location providers to tell the location manager when it has a new location */
void setLocation(in Location location);
String getFromLocation(double latitude, double longitude, int maxResults,
String language, String country, String variant, String appName, out List<Address> addrs);

View File

@@ -27,6 +27,7 @@ import java.util.HashMap;
import java.util.List;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Config;
import android.util.Log;
@@ -46,11 +47,13 @@ public abstract class LocationProviderImpl extends LocationProvider {
private static HashMap<String, LocationProviderImpl> sProvidersByName
= new HashMap<String, LocationProviderImpl>();
private final ILocationManager mLocationManager;
private boolean mLocationTracking = false;
private long mMinTime = 0;
protected LocationProviderImpl(String name) {
protected LocationProviderImpl(String name, ILocationManager locationManager) {
super(name);
mLocationManager = locationManager;
}
public static void addProvider(LocationProviderImpl provider) {
@@ -114,16 +117,24 @@ public abstract class LocationProviderImpl extends LocationProvider {
return null;
}
public void reportLocationChanged(Location location) {
try {
mLocationManager.setLocation(location);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException calling ILocationManager.onLocationChanged");
}
}
/**
* Enables this provider. When enabled, calls to {@link #getStatus()}
* and {@link #getLocation} must be handled. Hardware may be started up
* must be handled. Hardware may be started up
* when the provider is enabled.
*/
public abstract void enable();
/**
* Disables this provider. When disabled, calls to {@link #getStatus()}
* and {@link #getLocation} need not be handled. Hardware may be shut
* need not be handled. Hardware may be shut
* down while the provider is disabled.
*/
public abstract void disable();
@@ -174,15 +185,6 @@ public abstract class LocationProviderImpl extends LocationProvider {
return 0;
}
/**
* Sets a Location object with the information gathered
* during the most recent fix.
*
* @param l location object to set
* @return true if a location fix is available
*/
public abstract boolean getLocation(Location l);
/**
* Notifies the location provider that clients are listening for locations.
* Called with enable set to true when the first client is added and

View File

@@ -22,6 +22,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.location.Criteria;
import android.location.IGpsStatusListener;
import android.location.ILocationManager;
import android.location.Location;
import android.location.LocationManager;
import android.location.LocationProvider;
@@ -209,8 +210,8 @@ public class GpsLocationProvider extends LocationProviderImpl {
return native_is_supported();
}
public GpsLocationProvider(Context context) {
super(LocationManager.GPS_PROVIDER);
public GpsLocationProvider(Context context, ILocationManager locationManager) {
super(LocationManager.GPS_PROVIDER, locationManager);
mContext = context;
TelephonyBroadcastReceiver receiver = new TelephonyBroadcastReceiver();
@@ -355,7 +356,7 @@ public class GpsLocationProvider extends LocationProviderImpl {
/**
* Enables this provider. When enabled, calls to getStatus()
* and getLocation() must be handled. Hardware may be started up
* must be handled. Hardware may be started up
* when the provider is enabled.
*/
@Override
@@ -385,7 +386,7 @@ public class GpsLocationProvider extends LocationProviderImpl {
/**
* Disables this provider. When disabled, calls to getStatus()
* and getLocation() need not be handled. Hardware may be shut
* need not be handled. Hardware may be shut
* down while the provider is disabled.
*/
@Override
@@ -448,19 +449,6 @@ public class GpsLocationProvider extends LocationProviderImpl {
return mStatusUpdateTime;
}
@Override
public boolean getLocation(Location l) {
synchronized (mLocation) {
// don't report locations without latitude and longitude
if ((mLocationFlags & LOCATION_HAS_LAT_LONG) == 0) {
return false;
}
l.set(mLocation);
l.setExtras(mLocationExtras);
return true;
}
}
@Override
public void enableLocationTracking(boolean enable) {
if (mLocationTracking == enable) {
@@ -685,6 +673,8 @@ public class GpsLocationProvider extends LocationProviderImpl {
mLocation.removeAccuracy();
}
reportLocationChanged(mLocation);
// Send to collector
if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG
&& mCollector != null) {

View File

@@ -20,12 +20,7 @@ import android.location.Address;
import android.location.Location;
import android.net.wifi.ScanResult;
import com.google.common.io.protocol.ProtoBuf;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
/**
* Interface for network location provider

View File

@@ -16,6 +16,7 @@
package com.android.internal.location;
import android.location.ILocationManager;
import android.location.Location;
import android.location.LocationProviderImpl;
import android.os.Bundle;
@@ -46,10 +47,11 @@ public class MockProvider extends LocationProviderImpl {
private boolean mHasStatus;
private boolean mEnabled;
public MockProvider(String name, boolean requiresNetwork, boolean requiresSatellite,
public MockProvider(String name, ILocationManager locationManager,
boolean requiresNetwork, boolean requiresSatellite,
boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude,
boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
super(name);
super(name, locationManager);
mRequiresNetwork = requiresNetwork;
mRequiresSatellite = requiresSatellite;
@@ -73,15 +75,6 @@ public class MockProvider extends LocationProviderImpl {
mEnabled = true;
}
@Override
public boolean getLocation(Location l) {
if (mHasLocation) {
l.set(mLocation);
return true;
}
return false;
}
@Override
public int getStatus(Bundle extras) {
if (mHasStatus) {
@@ -93,6 +86,11 @@ public class MockProvider extends LocationProviderImpl {
}
}
@Override
public long getStatusUpdateTime() {
return mStatusUpdateTime;
}
@Override
public boolean isEnabled() {
return mEnabled;
@@ -146,6 +144,7 @@ public class MockProvider extends LocationProviderImpl {
public void setLocation(Location l) {
mLocation.set(l);
mHasLocation = true;
reportLocationChanged(mLocation);
}
public void clearLocation() {
@@ -164,29 +163,7 @@ public class MockProvider extends LocationProviderImpl {
public void clearStatus() {
mHasStatus = false;
}
public int overrideStatus(int status) {
if (mHasStatus) {
return mStatus;
} else {
return status;
}
}
public long overrideStatusUpdateTime(long statusUpdateTime) {
if (mHasStatus) {
return mStatusUpdateTime;
} else {
return statusUpdateTime;
}
}
public void overrideExtras(Bundle extras) {
if (mHasStatus) {
extras.clear();
extras.putAll(mExtras);
}
mStatusUpdateTime = 0;
}
public void dump(PrintWriter pw, String prefix) {

View File

@@ -16,6 +16,7 @@ import java.util.List;
import java.util.StringTokenizer;
import android.location.Criteria;
import android.location.ILocationManager;
import android.location.Location;
import android.location.LocationProviderImpl;
import android.os.Bundle;
@@ -50,6 +51,7 @@ public class TrackProvider extends LocationProviderImpl {
private static final long INTERVAL = 1000L;
private boolean mEnabled = true;
private TrackProviderThread mThread;
private double mLatitude;
private double mLongitude;
@@ -86,6 +88,36 @@ public class TrackProvider extends LocationProviderImpl {
private Location mInitialLocation;
private class TrackProviderThread extends Thread {
private boolean mDone = false;
public TrackProviderThread() {
super("TrackProviderThread");
}
public void run() {
// thread exits after disable() is called
synchronized (this) {
while (!mDone) {
try {
wait(INTERVAL);
} catch (InterruptedException e) {
}
if (!mDone) {
TrackProvider.this.update();
}
}
}
}
synchronized void setDone() {
mDone = true;
notify();
}
}
private void close(Reader rdr) {
try {
if (rdr != null) {
@@ -392,13 +424,13 @@ public class TrackProvider extends LocationProviderImpl {
}
}
public TrackProvider(String name) {
super(name);
public TrackProvider(String name, ILocationManager locationManager) {
super(name, locationManager);
setTimes();
}
public TrackProvider(String name, File file) {
this(name);
public TrackProvider(String name, ILocationManager locationManager, File file) {
this(name, locationManager);
String filename = file.getName();
if (filename.endsWith("kml")) {
@@ -429,12 +461,7 @@ public class TrackProvider extends LocationProviderImpl {
}
private void update() {
// Don't update the position at all unless INTERVAL milliseconds
// have passed since the last request
long time = System.currentTimeMillis() - mBaseTime;
if (time - mLastTime < INTERVAL) {
return;
}
List<Waypoint> waypoints = mWaypoints;
if (waypoints == null) {
@@ -594,12 +621,22 @@ public class TrackProvider extends LocationProviderImpl {
mTrackSpeed = trackSpeed;
}
@Override public void enable() {
mEnabled = true;
@Override public synchronized void enable() {
mEnabled = true;
mThread = new TrackProviderThread();
mThread.start();
}
@Override public void disable() {
@Override public synchronized void disable() {
mEnabled = false;
if (mThread != null) {
mThread.setDone();
try {
mThread.join();
} catch (InterruptedException e) {
}
mThread = null;
}
}
@Override public boolean isEnabled() {
@@ -610,31 +647,6 @@ public class TrackProvider extends LocationProviderImpl {
return AVAILABLE;
}
@Override public boolean getLocation(Location l) {
if (mEnabled) {
update();
l.setProvider(getName());
l.setTime(mTime + mBaseTime);
l.setLatitude(mLatitude);
l.setLongitude(mLongitude);
if (mSupportsAltitude && mHasAltitude) {
l.setAltitude(mAltitude);
}
if (mSupportsBearing && mHasBearing) {
l.setBearing(mBearing);
}
if (mSupportsSpeed && mHasSpeed) {
l.setSpeed(mSpeed);
}
if (mExtras != null) {
l.setExtras(mExtras);
}
return true;
} else {
return false;
}
}
public Location getInitialLocation() {
return mInitialLocation;
}

View File

@@ -136,7 +136,7 @@ public class LocationManagerService extends ILocationManager.Stub
private LocationWorkerHandler mLocationHandler;
// Handler messages
private static final int MESSAGE_HEARTBEAT = 1;
private static final int MESSAGE_LOCATION_CHANGED = 1;
private static final int MESSAGE_ACQUIRE_WAKE_LOCK = 2;
private static final int MESSAGE_RELEASE_WAKE_LOCK = 3;
private static final int MESSAGE_INSTALL_NETWORK_LOCATION_PROVIDER = 4;
@@ -191,13 +191,6 @@ public class LocationManagerService extends ILocationManager.Stub
private final HashMap<String,ArrayList<UpdateRecord>> mRecordsByProvider =
new HashMap<String,ArrayList<UpdateRecord>>();
/**
* Mappings from provider name to object to use for current location. Locations
* contained in this list may not always be valid.
*/
private final HashMap<String,Location> mLocationsByProvider =
new HashMap<String,Location>();
// Proximity listeners
private Receiver mProximityListener = null;
private HashMap<PendingIntent,ProximityAlert> mProximityAlerts =
@@ -484,7 +477,7 @@ public class LocationManagerService extends ILocationManager.Stub
// Attempt to load "real" providers first
if (GpsLocationProvider.isSupported()) {
// Create a gps location provider
mGpsLocationProvider = new GpsLocationProvider(mContext);
mGpsLocationProvider = new GpsLocationProvider(mContext, this);
LocationProviderImpl.addProvider(mGpsLocationProvider);
}
@@ -518,7 +511,7 @@ public class LocationManagerService extends ILocationManager.Stub
File propertiesFile = new File(subdirs[i], "properties");
if (propertiesFile.exists()) {
provider = new TrackProvider(name);
provider = new TrackProvider(name, this);
((TrackProvider)provider).readProperties(propertiesFile);
File kmlFile = new File(subdirs[i], "kml");
@@ -885,14 +878,6 @@ public class LocationManagerService extends ILocationManager.Stub
p.disable();
updateWakelockStatusLocked(mScreenOn);
}
if (enabled && listeners > 0) {
mLocationHandler.removeMessages(MESSAGE_HEARTBEAT, provider);
Message m = Message.obtain(mLocationHandler, MESSAGE_HEARTBEAT, provider);
mLocationHandler.sendMessageAtTime(m, SystemClock.uptimeMillis() + 1000);
} else {
mLocationHandler.removeMessages(MESSAGE_HEARTBEAT, provider);
}
}
private long getMinTimeLocked(String provider) {
@@ -1059,11 +1044,6 @@ public class LocationManagerService extends ILocationManager.Stub
updateReportedGpsLocked();
}
}
// Clear heartbeats if any before starting a new one
mLocationHandler.removeMessages(MESSAGE_HEARTBEAT, provider);
Message m = Message.obtain(mLocationHandler, MESSAGE_HEARTBEAT, provider);
mLocationHandler.sendMessageAtTime(m, SystemClock.uptimeMillis() + 1000);
} else {
try {
// Notify the listener that updates are currently disabled
@@ -1162,7 +1142,6 @@ public class LocationManagerService extends ILocationManager.Stub
if (hasOtherListener) {
p.setMinTime(getMinTimeLocked(provider));
} else {
mLocationHandler.removeMessages(MESSAGE_HEARTBEAT, provider);
p.enableLocationTracking(false);
}
@@ -1522,6 +1501,12 @@ public class LocationManagerService extends ILocationManager.Stub
}
}
public void setLocation(Location location) {
mLocationHandler.removeMessages(MESSAGE_LOCATION_CHANGED, location);
Message m = Message.obtain(mLocationHandler, MESSAGE_LOCATION_CHANGED, location);
mLocationHandler.sendMessageAtFrontOfQueue(m);
}
private boolean _isProviderEnabledLocked(String provider) {
checkPermissionsSafe(provider);
@@ -1592,7 +1577,8 @@ public class LocationManagerService extends ILocationManager.Stub
return true;
}
private void handleLocationChangedLocked(String provider) {
private void handleLocationChangedLocked(Location location) {
String provider = location.getProvider();
ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
if (records == null || records.size() == 0) {
return;
@@ -1603,40 +1589,19 @@ public class LocationManagerService extends ILocationManager.Stub
return;
}
// Get location object
Location loc = mLocationsByProvider.get(provider);
if (loc == null) {
loc = new Location(provider);
mLocationsByProvider.put(provider, loc);
} else {
loc.reset();
}
boolean locationValid;
// Use the mock location if available
MockProvider mockProvider = mMockProviders.get(provider);
if (mockProvider != null && mockProvider.getLocation(loc)) {
locationValid = true;
} else {
locationValid = p.getLocation(loc);
}
// Update last known location for provider
if (locationValid) {
Location location = mLastKnownLocation.get(provider);
if (location == null) {
mLastKnownLocation.put(provider, new Location(loc));
} else {
location.set(loc);
}
writeLastKnownLocationLocked(provider, loc);
Location lastLocation = mLastKnownLocation.get(provider);
if (lastLocation == null) {
mLastKnownLocation.put(provider, new Location(location));
} else {
lastLocation.set(location);
}
writeLastKnownLocationLocked(provider, location);
if (p instanceof INetworkLocationProvider) {
mWakeLockNetworkReceived = true;
} else if (p instanceof GpsLocationProvider) {
// Gps location received signal is in NetworkStateBroadcastReceiver
}
if (p instanceof INetworkLocationProvider) {
mWakeLockNetworkReceived = true;
} else if (p instanceof GpsLocationProvider) {
// Gps location received signal is in NetworkStateBroadcastReceiver
}
// Fetch latest status update time
@@ -1646,13 +1611,6 @@ public class LocationManagerService extends ILocationManager.Stub
Bundle extras = new Bundle();
int status = p.getStatus(extras);
// Override with mock values if mock provider is present
if (mockProvider != null) {
status = mockProvider.overrideStatus(status);
newStatusUpdateTime = mockProvider.overrideStatusUpdateTime(newStatusUpdateTime);
mockProvider.overrideExtras(extras);
}
ArrayList<Receiver> deadReceivers = null;
// Broadcast location or status to all listeners
@@ -1661,28 +1619,25 @@ public class LocationManagerService extends ILocationManager.Stub
UpdateRecord r = records.get(i);
Receiver receiver = r.mReceiver;
// Broadcast location only if it is valid
if (locationValid) {
HashMap<String,Location> map = mLastFixBroadcast.get(receiver);
if (map == null) {
map = new HashMap<String,Location>();
mLastFixBroadcast.put(receiver, map);
HashMap<String,Location> map = mLastFixBroadcast.get(receiver);
if (map == null) {
map = new HashMap<String,Location>();
mLastFixBroadcast.put(receiver, map);
}
Location lastLoc = map.get(provider);
if ((lastLoc == null) || shouldBroadcastSafe(location, lastLoc, r)) {
if (lastLoc == null) {
lastLoc = new Location(location);
map.put(provider, lastLoc);
} else {
lastLoc.set(location);
}
Location lastLoc = map.get(provider);
if ((lastLoc == null) || shouldBroadcastSafe(loc, lastLoc, r)) {
if (lastLoc == null) {
lastLoc = new Location(loc);
map.put(provider, lastLoc);
} else {
lastLoc.set(loc);
}
if (!receiver.callLocationChangedLocked(loc)) {
Log.w(TAG, "RemoteException calling onLocationChanged on " + receiver);
if (deadReceivers == null) {
deadReceivers = new ArrayList<Receiver>();
}
deadReceivers.add(receiver);
if (!receiver.callLocationChangedLocked(location)) {
Log.w(TAG, "RemoteException calling onLocationChanged on " + receiver);
if (deadReceivers == null) {
deadReceivers = new ArrayList<Receiver>();
}
deadReceivers.add(receiver);
}
}
@@ -1723,25 +1678,19 @@ public class LocationManagerService extends ILocationManager.Stub
@Override
public void handleMessage(Message msg) {
try {
if (msg.what == MESSAGE_HEARTBEAT) {
// log("LocationWorkerHandler: Heartbeat!");
if (msg.what == MESSAGE_LOCATION_CHANGED) {
// log("LocationWorkerHandler: MESSAGE_LOCATION_CHANGED!");
synchronized (mLocationListeners) {
String provider = (String) msg.obj;
Location location = (Location) msg.obj;
String provider = location.getProvider();
if (!isAllowedBySettingsLocked(provider)) {
return;
}
// Process the location fix if the screen is on or we're holding a wakelock
if (mScreenOn || (mWakeLockAcquireTime != 0)) {
handleLocationChangedLocked(provider);
}
// If it continues to have listeners
ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
if (records != null && records.size() > 0) {
Message m = Message.obtain(this, MESSAGE_HEARTBEAT, provider);
sendMessageAtTime(m, SystemClock.uptimeMillis() + 1000);
handleLocationChangedLocked(location);
}
if ((mWakeLockAcquireTime != 0) &&
@@ -2386,7 +2335,8 @@ public class LocationManagerService extends ILocationManager.Stub
checkMockPermissionsSafe();
synchronized (mLocationListeners) {
MockProvider provider = new MockProvider(name, requiresNetwork, requiresSatellite,
MockProvider provider = new MockProvider(name, this,
requiresNetwork, requiresSatellite,
requiresCell, hasMonetaryCost, supportsAltitude,
supportsSpeed, supportsBearing, powerRequirement, accuracy);
if (LocationProviderImpl.getProvider(name) != null) {
@@ -2563,12 +2513,6 @@ public class LocationManagerService extends ILocationManager.Stub
j.dump(pw, " ");
}
}
pw.println(" Locations by Provider:");
for (Map.Entry<String, Location> i
: mLocationsByProvider.entrySet()) {
pw.println(" " + i.getKey() + ":");
i.getValue().dump(new PrintWriterPrinter(pw), " ");
}
pw.println(" Last Known Locations:");
for (Map.Entry<String, Location> i
: mLastKnownLocation.entrySet()) {

View File

@@ -18,6 +18,7 @@ package android.test;
import android.location.Criteria;
import android.location.ILocationManager;
import android.location.Location;
import android.location.LocationProviderImpl;
import android.os.Bundle;
@@ -36,14 +37,45 @@ public class TestLocationProvider extends LocationProviderImpl {
public static final float SPEED = 10;
public static final float BEARING = 1;
public static final int STATUS = AVAILABLE;
private static final long LOCATION_INTERVAL = 1000;
private Location mLocation;
private boolean mEnabled;
private TestLocationProviderThread mThread;
public TestLocationProvider() {
super(PROVIDER_NAME);
private class TestLocationProviderThread extends Thread {
private boolean mDone = false;
public TestLocationProviderThread() {
super("TestLocationProviderThread");
}
public void run() {
// thread exits after disable() is called
synchronized (this) {
while (!mDone) {
try {
wait(LOCATION_INTERVAL);
} catch (InterruptedException e) {
}
if (!mDone) {
TestLocationProvider.this.updateLocation();
}
}
}
}
synchronized void setDone() {
mDone = true;
notify();
}
}
public TestLocationProvider(ILocationManager locationManager) {
super(PROVIDER_NAME, locationManager);
mLocation = new Location(PROVIDER_NAME);
updateLocation();
}
//LocationProvider methods
@@ -95,13 +127,23 @@ public class TestLocationProvider extends LocationProviderImpl {
//LocationProviderImpl methods
@Override
public void disable() {
public synchronized void disable() {
mEnabled = false;
if (mThread != null) {
mThread.setDone();
try {
mThread.join();
} catch (InterruptedException e) {
}
mThread = null;
}
}
@Override
public void enable() {
mEnabled = true;
public synchronized void enable() {
mEnabled = true;
mThread = new TestLocationProviderThread();
mThread.start();
}
@Override
@@ -109,13 +151,6 @@ public class TestLocationProvider extends LocationProviderImpl {
return mEnabled;
}
@Override
public boolean getLocation(Location l) {
updateLocation();
l.set(mLocation);
return true;
}
@Override
public int getStatus(Bundle extras) {
return STATUS;
@@ -134,6 +169,7 @@ public class TestLocationProvider extends LocationProviderImpl {
extras.putInt("extraTest", 24);
mLocation.setExtras(extras);
mLocation.setTime(time);
reportLocationChanged(mLocation);
}
}