eclair snapshot

This commit is contained in:
Jean-Baptiste Queru
2009-11-12 18:45:53 -08:00
parent 6c63ee4fc4
commit 9db3d07b96
3587 changed files with 991748 additions and 69172 deletions

View File

@@ -16,12 +16,7 @@
package com.android.server;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
@@ -31,7 +26,6 @@ import java.util.Map;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;
import java.util.regex.Pattern;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -49,10 +43,12 @@ import android.location.IGpsStatusProvider;
import android.location.ILocationListener;
import android.location.ILocationManager;
import android.location.ILocationProvider;
import android.location.INetInitiatedListener;
import android.location.Location;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -63,7 +59,6 @@ import android.os.Message;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;
import android.util.PrintWriterPrinter;
@@ -71,6 +66,7 @@ import android.util.PrintWriterPrinter;
import com.android.internal.location.GpsLocationProvider;
import com.android.internal.location.LocationProviderProxy;
import com.android.internal.location.MockProvider;
import com.android.internal.location.GpsNetInitiatedHandler;
/**
* The service class that manages LocationProviders and issues location
@@ -82,17 +78,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
private static final String TAG = "LocationManagerService";
private static final boolean LOCAL_LOGV = false;
// Minimum time interval between last known location writes, in milliseconds.
private static final long MIN_LAST_KNOWN_LOCATION_TIME = 60L * 1000L;
// Max time to hold wake lock for, in milliseconds.
private static final long MAX_TIME_FOR_WAKE_LOCK = 60 * 1000L;
// The last time a location was written, by provider name.
private HashMap<String,Long> mLastWriteTime = new HashMap<String,Long>();
private static final Pattern PATTERN_COMMA = Pattern.compile(",");
private static final String ACCESS_FINE_LOCATION =
android.Manifest.permission.ACCESS_FINE_LOCATION;
private static final String ACCESS_COARSE_LOCATION =
@@ -118,6 +106,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
private final Context mContext;
private IGeocodeProvider mGeocodeProvider;
private IGpsStatusProvider mGpsStatusProvider;
private INetInitiatedListener mNetInitiatedListener;
private LocationWorkerHandler mLocationHandler;
// Cache the real providers for use in addTestProvider() and removeTestProvider()
@@ -394,7 +383,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
public void locationCallbackFinished(ILocationListener listener) {
Receiver receiver = getReceiver(listener);
//Do not use getReceiver here as that will add the ILocationListener to
//the receiver list if it is not found. If it is not found then the
//LocationListener was removed when it had a pending broadcast and should
//not be added back.
IBinder binder = listener.asBinder();
Receiver receiver = mReceivers.get(binder);
if (receiver != null) {
synchronized (receiver) {
// so wakelock calls will succeed
@@ -413,97 +407,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
}
private Location readLastKnownLocationLocked(String provider) {
Location location = null;
String s = null;
try {
File f = new File(LocationManager.SYSTEM_DIR + "/location."
+ provider);
if (!f.exists()) {
return null;
}
BufferedReader reader = new BufferedReader(new FileReader(f), 256);
s = reader.readLine();
} catch (IOException e) {
Log.w(TAG, "Unable to read last known location", e);
}
if (s == null) {
return null;
}
try {
String[] tokens = PATTERN_COMMA.split(s);
int idx = 0;
long time = Long.parseLong(tokens[idx++]);
double latitude = Double.parseDouble(tokens[idx++]);
double longitude = Double.parseDouble(tokens[idx++]);
double altitude = Double.parseDouble(tokens[idx++]);
float bearing = Float.parseFloat(tokens[idx++]);
float speed = Float.parseFloat(tokens[idx++]);
location = new Location(provider);
location.setTime(time);
location.setLatitude(latitude);
location.setLongitude(longitude);
location.setAltitude(altitude);
location.setBearing(bearing);
location.setSpeed(speed);
} catch (NumberFormatException nfe) {
Log.e(TAG, "NumberFormatException reading last known location", nfe);
return null;
}
return location;
}
private void writeLastKnownLocationLocked(String provider,
Location location) {
long now = SystemClock.elapsedRealtime();
Long last = mLastWriteTime.get(provider);
if ((last != null)
&& (now - last.longValue() < MIN_LAST_KNOWN_LOCATION_TIME)) {
return;
}
mLastWriteTime.put(provider, now);
StringBuilder sb = new StringBuilder(100);
sb.append(location.getTime());
sb.append(',');
sb.append(location.getLatitude());
sb.append(',');
sb.append(location.getLongitude());
sb.append(',');
sb.append(location.getAltitude());
sb.append(',');
sb.append(location.getBearing());
sb.append(',');
sb.append(location.getSpeed());
FileWriter writer = null;
try {
File d = new File(LocationManager.SYSTEM_DIR);
if (!d.exists()) {
if (!d.mkdirs()) {
Log.w(TAG, "Unable to create directory to write location");
return;
}
}
File f = new File(LocationManager.SYSTEM_DIR + "/location." + provider);
writer = new FileWriter(f);
writer.write(sb.toString());
} catch (IOException e) {
Log.w(TAG, "Unable to write location", e);
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
Log.w(TAG, "Exception closing file", e);
}
}
}
}
private void addProvider(LocationProviderProxy provider) {
mProviders.add(provider);
mProvidersByName.put(provider.getName(), provider);
@@ -541,6 +444,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
// Create a gps location provider
GpsLocationProvider provider = new GpsLocationProvider(mContext, this);
mGpsStatusProvider = provider.getGpsStatusProvider();
mNetInitiatedListener = provider.getNetInitiatedListener();
LocationProviderProxy proxy = new LocationProviderProxy(LocationManager.GPS_PROVIDER, provider);
addProvider(proxy);
mGpsLocationProvider = proxy;
@@ -626,7 +530,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
// notify provider of current network state
proxy.updateNetworkState(mNetworkState);
proxy.updateNetworkState(mNetworkState, null);
}
}
@@ -850,7 +754,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
*/
void disposeLocked() {
ArrayList<UpdateRecord> records = mRecordsByProvider.get(this.mProvider);
records.remove(this);
if (records != null) {
records.remove(this);
}
}
@Override
@@ -869,15 +775,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
mLastFixBroadcast.dump(new PrintWriterPrinter(pw), prefix + " ");
pw.println(prefix + "mLastStatusBroadcast=" + mLastStatusBroadcast);
}
/**
* Calls dispose().
*/
@Override protected void finalize() {
synchronized (mLock) {
disposeLocked();
}
}
}
private Receiver getReceiver(ILocationListener listener) {
@@ -1030,6 +927,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
try {
if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) {
receiver.getListener().asBinder().unlinkToDeath(receiver, 0);
synchronized(receiver) {
if(receiver.mPendingBroadcasts > 0) {
decrementPendingBroadcasts();
receiver.mPendingBroadcasts = 0;
}
}
}
// Record which providers were associated with this listener
@@ -1108,6 +1011,11 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
public boolean sendExtraCommand(String provider, String command, Bundle extras) {
if (provider == null) {
// throw NullPointerException to remain compatible with previous implementation
throw new NullPointerException();
}
// first check for permission to the provider
checkPermissionsSafe(provider);
// and check for ACCESS_LOCATION_EXTRA_COMMANDS
@@ -1118,7 +1026,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
synchronized (mLock) {
LocationProviderProxy proxy = mProvidersByName.get(provider);
if (provider == null) {
if (proxy == null) {
return false;
}
@@ -1126,6 +1034,22 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
}
public boolean sendNiResponse(int notifId, int userResponse)
{
if (Binder.getCallingUid() != Process.myUid()) {
throw new SecurityException(
"calling sendNiResponse from outside of the system is not allowed");
}
try {
return mNetInitiatedListener.sendNiResponse(notifId, userResponse);
}
catch (RemoteException e)
{
Log.e(TAG, "RemoteException in LocationManagerService.sendNiResponse");
return false;
}
}
class ProximityAlert {
final int mUid;
final double mLatitude;
@@ -1157,13 +1081,13 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
return mIntent;
}
boolean isInProximity(double latitude, double longitude) {
boolean isInProximity(double latitude, double longitude, float accuracy) {
Location loc = new Location("");
loc.setLatitude(latitude);
loc.setLongitude(longitude);
double radius = loc.distanceTo(mLocation);
return radius <= mRadius;
return radius <= Math.max(mRadius,accuracy);
}
@Override
@@ -1203,6 +1127,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
long now = System.currentTimeMillis();
double latitude = loc.getLatitude();
double longitude = loc.getLongitude();
float accuracy = loc.getAccuracy();
ArrayList<PendingIntent> intentsToRemove = null;
for (ProximityAlert alert : mProximityAlerts.values()) {
@@ -1212,7 +1137,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
if ((expiration == -1) || (now <= expiration)) {
boolean entered = mProximitiesEntered.contains(alert);
boolean inProximity =
alert.isInProximity(latitude, longitude);
alert.isInProximity(latitude, longitude, accuracy);
if (!entered && inProximity) {
if (LOCAL_LOGV) {
Log.v(TAG, "Entered alert");
@@ -1487,16 +1412,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
return null;
}
Location location = mLastKnownLocation.get(provider);
if (location == null) {
// Get the persistent last known location for the provider
location = readLastKnownLocationLocked(provider);
if (location != null) {
mLastKnownLocation.put(provider, location);
}
}
return location;
return mLastKnownLocation.get(provider);
}
private static boolean shouldBroadcastSafe(Location loc, Location lastLoc, UpdateRecord record) {
@@ -1541,7 +1457,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
} else {
lastLocation.set(location);
}
writeLastKnownLocationLocked(provider, location);
// Fetch latest status update time
long newStatusUpdateTime = p.getStatusUpdateTime();
@@ -1686,13 +1601,15 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
} else {
mNetworkState = LocationProvider.TEMPORARILY_UNAVAILABLE;
}
NetworkInfo info =
(NetworkInfo)intent.getExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
// Notify location providers of current network state
synchronized (mLock) {
for (int i = mProviders.size() - 1; i >= 0; i--) {
LocationProviderProxy provider = mProviders.get(i);
if (provider.requiresNetwork()) {
provider.updateNetworkState(mNetworkState);
provider.updateNetworkState(mNetworkState, info);
}
}
}
@@ -1792,6 +1709,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
checkMockPermissionsSafe();
long identity = Binder.clearCallingIdentity();
synchronized (mLock) {
MockProvider provider = new MockProvider(name, this,
requiresNetwork, requiresSatellite,
@@ -1814,6 +1732,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
mLastKnownLocation.put(name, null);
updateProvidersLocked();
}
Binder.restoreCallingIdentity(identity);
}
public void removeTestProvider(String provider) {
@@ -1823,6 +1742,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
if (mockProvider == null) {
throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
}
long identity = Binder.clearCallingIdentity();
removeProvider(mProvidersByName.get(provider));
mMockProviders.remove(mockProvider);
// reinstall real provider if we were mocking GPS or network provider
@@ -1835,6 +1755,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
mLastKnownLocation.put(provider, null);
updateProvidersLocked();
Binder.restoreCallingIdentity(identity);
}
}
@@ -1870,6 +1791,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
if (mockProvider == null) {
throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
}
long identity = Binder.clearCallingIdentity();
if (enabled) {
mockProvider.enable();
mEnabledProviders.add(provider);
@@ -1880,6 +1802,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
mDisabledProviders.add(provider);
}
updateProvidersLocked();
Binder.restoreCallingIdentity(identity);
}
}
@@ -1890,9 +1813,11 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
if (mockProvider == null) {
throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
}
long identity = Binder.clearCallingIdentity();
mEnabledProviders.remove(provider);
mDisabledProviders.remove(provider);
updateProvidersLocked();
Binder.restoreCallingIdentity(identity);
}
}