summaryrefslogtreecommitdiffstats
path: root/location
diff options
context:
space:
mode:
Diffstat (limited to 'location')
-rw-r--r--location/Android.mk19
-rw-r--r--location/java/android/location/Criteria.java177
-rw-r--r--location/java/android/location/Geocoder.java21
-rw-r--r--location/java/android/location/GpsStatus.java20
-rw-r--r--location/java/android/location/ILocationManager.aidl16
-rw-r--r--location/java/android/location/ILocationProvider.aidl5
-rw-r--r--location/java/android/location/LocationManager.java570
-rw-r--r--location/java/android/location/LocationProvider.java35
-rw-r--r--location/java/android/location/LocationProviderInterface.java52
-rw-r--r--location/java/com/android/internal/location/DummyLocationProvider.java5
-rw-r--r--location/java/com/android/internal/location/GeocoderProxy.java105
-rwxr-xr-xlocation/java/com/android/internal/location/GpsLocationProvider.java1475
-rwxr-xr-xlocation/java/com/android/internal/location/GpsNetInitiatedHandler.java517
-rw-r--r--location/java/com/android/internal/location/GpsXtraDownloader.java173
-rw-r--r--location/java/com/android/internal/location/LocationProviderProxy.java384
-rw-r--r--location/java/com/android/internal/location/MockProvider.java207
-rw-r--r--location/java/com/android/internal/location/PassiveProvider.java143
-rw-r--r--location/lib/Android.mk45
-rw-r--r--location/lib/com.android.location.provider.xml20
-rw-r--r--location/lib/java/com/android/location/provider/GeocodeProvider.java (renamed from location/java/android/location/provider/GeocodeProvider.java)7
-rw-r--r--location/lib/java/com/android/location/provider/LocationProvider.java (renamed from location/java/android/location/provider/LocationProvider.java)44
21 files changed, 897 insertions, 3143 deletions
diff --git a/location/Android.mk b/location/Android.mk
new file mode 100644
index 0000000..12db2f7
--- /dev/null
+++ b/location/Android.mk
@@ -0,0 +1,19 @@
+# Copyright (C) 2010 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.
+
+LOCAL_PATH := $(call my-dir)
+
+ifeq ($(TARGET_BUILD_APPS),)
+include $(call all-makefiles-under, $(LOCAL_PATH))
+endif
diff --git a/location/java/android/location/Criteria.java b/location/java/android/location/Criteria.java
index 9d258d0..1f3fb7a 100644
--- a/location/java/android/location/Criteria.java
+++ b/location/java/android/location/Criteria.java
@@ -57,9 +57,35 @@ public class Criteria implements Parcelable {
*/
public static final int ACCURACY_COARSE = 2;
- private int mAccuracy = NO_REQUIREMENT;
+ /**
+ * A constant indicating a low location accuracy requirement
+ * - may be used for horizontal, altitude, speed or bearing accuracy.
+ * For horizontal and vertical position this corresponds roughly to
+ * an accuracy of greater than 500 meters.
+ */
+ public static final int ACCURACY_LOW = 1;
+
+ /**
+ * A constant indicating a medium accuracy requirement
+ * - currently used only for horizontal accuracy.
+ * For horizontal position this corresponds roughly to to an accuracy
+ * of between 100 and 500 meters.
+ */
+ public static final int ACCURACY_MEDIUM = 2;
+
+ /**
+ * a constant indicating a high accuracy requirement
+ * - may be used for horizontal, altitude, speed or bearing accuracy.
+ * For horizontal and vertical position this corresponds roughly to
+ * an accuracy of less than 100 meters.
+ */
+ public static final int ACCURACY_HIGH = 3;
+
+ private int mHorizontalAccuracy = NO_REQUIREMENT;
+ private int mVerticalAccuracy = NO_REQUIREMENT;
+ private int mSpeedAccuracy = NO_REQUIREMENT;
+ private int mBearingAccuracy = NO_REQUIREMENT;
private int mPowerRequirement = NO_REQUIREMENT;
-// private int mPreferredResponseTime = NO_REQUIREMENT;
private boolean mAltitudeRequired = false;
private boolean mBearingRequired = false;
private boolean mSpeedRequired = false;
@@ -77,9 +103,11 @@ public class Criteria implements Parcelable {
* Constructs a new Criteria object that is a copy of the given criteria.
*/
public Criteria(Criteria criteria) {
- mAccuracy = criteria.mAccuracy;
+ mHorizontalAccuracy = criteria.mHorizontalAccuracy;
+ mVerticalAccuracy = criteria.mVerticalAccuracy;
+ mSpeedAccuracy = criteria.mSpeedAccuracy;
+ mBearingAccuracy = criteria.mBearingAccuracy;
mPowerRequirement = criteria.mPowerRequirement;
-// mPreferredResponseTime = criteria.mPreferredResponseTime;
mAltitudeRequired = criteria.mAltitudeRequired;
mBearingRequired = criteria.mBearingRequired;
mSpeedRequired = criteria.mSpeedRequired;
@@ -87,19 +115,118 @@ public class Criteria implements Parcelable {
}
/**
+ * Indicates the desired horizontal accuracy (latitude and longitude).
+ * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
+ * {@link #ACCURACY_HIGH} or {@link #NO_REQUIREMENT}.
+ * More accurate location may consume more power and may take longer.
+ *
+ * @throws IllegalArgumentException if accuracy is not one of the supported constants
+ */
+ public void setHorizontalAccuracy(int accuracy) {
+ if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_HIGH) {
+ throw new IllegalArgumentException("accuracy=" + accuracy);
+ }
+ mHorizontalAccuracy = accuracy;
+ }
+
+ /**
+ * Returns a constant indicating the desired horizontal accuracy (latitude and longitude).
+ * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
+ * {@link #ACCURACY_HIGH} or {@link #NO_REQUIREMENT}.
+ */
+ public int getHorizontalAccuracy() {
+ return mHorizontalAccuracy;
+ }
+
+ /**
+ * Indicates the desired vertical accuracy (altitude).
+ * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
+ * {@link #ACCURACY_HIGH} or {@link #NO_REQUIREMENT}.
+ * More accurate location may consume more power and may take longer.
+ *
+ * @throws IllegalArgumentException if accuracy is not one of the supported constants
+ */
+ public void setVerticalAccuracy(int accuracy) {
+ if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_HIGH) {
+ throw new IllegalArgumentException("accuracy=" + accuracy);
+ }
+ mVerticalAccuracy = accuracy;
+ }
+
+ /**
+ * Returns a constant indicating the desired vertical accuracy (altitude).
+ * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
+ * or {@link #NO_REQUIREMENT}.
+ */
+ public int getVerticalAccuracy() {
+ return mVerticalAccuracy;
+ }
+
+ /**
+ * Indicates the desired speed accuracy.
+ * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
+ * or {@link #NO_REQUIREMENT}.
+ * More accurate location may consume more power and may take longer.
+ *
+ * @throws IllegalArgumentException if accuracy is not one of the supported constants
+ */
+ public void setSpeedAccuracy(int accuracy) {
+ if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_HIGH) {
+ throw new IllegalArgumentException("accuracy=" + accuracy);
+ }
+ mSpeedAccuracy = accuracy;
+ }
+
+ /**
+ * Returns a constant indicating the desired speed accuracy
+ * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
+ * or {@link #NO_REQUIREMENT}.
+ */
+ public int getSpeedAccuracy() {
+ return mSpeedAccuracy;
+ }
+
+ /**
+ * Indicates the desired bearing accuracy.
+ * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
+ * or {@link #NO_REQUIREMENT}.
+ * More accurate location may consume more power and may take longer.
+ *
+ * @throws IllegalArgumentException if accuracy is not one of the supported constants
+ */
+ public void setBearingAccuracy(int accuracy) {
+ if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_HIGH) {
+ throw new IllegalArgumentException("accuracy=" + accuracy);
+ }
+ mBearingAccuracy = accuracy;
+ }
+
+ /**
+ * Returns a constant indicating the desired bearing accuracy.
+ * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
+ * or {@link #NO_REQUIREMENT}.
+ */
+ public int getBearingAccuracy() {
+ return mBearingAccuracy;
+ }
+
+ /**
* Indicates the desired accuracy for latitude and longitude. Accuracy
* may be {@link #ACCURACY_FINE} if desired location
* is fine, else it can be {@link #ACCURACY_COARSE}.
- * More accurate location usually consumes more power and may take
- * longer.
+ * More accurate location may consume more power and may take longer.
*
- * @throws IllegalArgumentException if accuracy is negative
+ * @throws IllegalArgumentException if accuracy is not one of the supported constants
*/
public void setAccuracy(int accuracy) {
- if (accuracy < NO_REQUIREMENT && accuracy > ACCURACY_COARSE) {
+ if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_COARSE) {
throw new IllegalArgumentException("accuracy=" + accuracy);
}
- mAccuracy = accuracy;
+ if (accuracy == ACCURACY_FINE) {
+ mHorizontalAccuracy = ACCURACY_HIGH;
+ } else {
+ mHorizontalAccuracy = ACCURACY_LOW;
+ }
}
/**
@@ -108,7 +235,11 @@ public class Criteria implements Parcelable {
* is fine, else it can be {@link #ACCURACY_COARSE}.
*/
public int getAccuracy() {
- return mAccuracy;
+ if (mHorizontalAccuracy >= ACCURACY_HIGH) {
+ return ACCURACY_FINE;
+ } else {
+ return ACCURACY_COARSE;
+ }
}
/**
@@ -131,20 +262,6 @@ public class Criteria implements Parcelable {
return mPowerRequirement;
}
-// /**
-// * Indicates the preferred response time of the provider, in milliseconds.
-// */
-// public void setPreferredResponseTime(int time) {
-// mPreferredResponseTime = time;
-// }
-//
-// /**
-// * Returns the preferred response time of the provider, in milliseconds.
-// */
-// public int getPreferredResponseTime() {
-// return mPreferredResponseTime;
-// }
-
/**
* Indicates whether the provider is allowed to incur monetary cost.
*/
@@ -211,9 +328,11 @@ public class Criteria implements Parcelable {
new Parcelable.Creator<Criteria>() {
public Criteria createFromParcel(Parcel in) {
Criteria c = new Criteria();
- c.mAccuracy = in.readInt();
+ c.mHorizontalAccuracy = in.readInt();
+ c.mVerticalAccuracy = in.readInt();
+ c.mSpeedAccuracy = in.readInt();
+ c.mBearingAccuracy = in.readInt();
c.mPowerRequirement = in.readInt();
-// c.mPreferredResponseTime = in.readInt();
c.mAltitudeRequired = in.readInt() != 0;
c.mBearingRequired = in.readInt() != 0;
c.mSpeedRequired = in.readInt() != 0;
@@ -231,9 +350,11 @@ public class Criteria implements Parcelable {
}
public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeInt(mAccuracy);
+ parcel.writeInt(mHorizontalAccuracy);
+ parcel.writeInt(mVerticalAccuracy);
+ parcel.writeInt(mSpeedAccuracy);
+ parcel.writeInt(mBearingAccuracy);
parcel.writeInt(mPowerRequirement);
-// parcel.writeInt(mPreferredResponseTime);
parcel.writeInt(mAltitudeRequired ? 1 : 0);
parcel.writeInt(mBearingRequired ? 1 : 0);
parcel.writeInt(mSpeedRequired ? 1 : 0);
diff --git a/location/java/android/location/Geocoder.java b/location/java/android/location/Geocoder.java
index c325b1b..ac7eb8b 100644
--- a/location/java/android/location/Geocoder.java
+++ b/location/java/android/location/Geocoder.java
@@ -40,7 +40,9 @@ import java.util.List;
*
* The Geocoder class requires a backend service that is not included in
* the core android framework. The Geocoder query methods will return an
- * empty list if there no backend service in the platform.
+ * empty list if there no backend service in the platform. Use the
+ * isPresent() method to determine whether a Geocoder implementation
+ * exists.
*/
public final class Geocoder {
private static final String TAG = "Geocoder";
@@ -49,6 +51,23 @@ public final class Geocoder {
private ILocationManager mService;
/**
+ * Returns true if the Geocoder methods getFromLocation and
+ * getFromLocationName are implemented. Lack of network
+ * connectivity may still cause these methods to return null or
+ * empty lists.
+ */
+ public static boolean isPresent() {
+ IBinder b = ServiceManager.getService(Context.LOCATION_SERVICE);
+ ILocationManager lm = ILocationManager.Stub.asInterface(b);
+ try {
+ return lm.geocoderIsPresent();
+ } catch (RemoteException e) {
+ Log.e(TAG, "isPresent: got RemoteException", e);
+ return false;
+ }
+ }
+
+ /**
* Constructs a Geocoder whose responses will be localized for the
* given Locale.
*
diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java
index ce69ac1..4af55a6 100644
--- a/location/java/android/location/GpsStatus.java
+++ b/location/java/android/location/GpsStatus.java
@@ -150,15 +150,17 @@ public final class GpsStatus {
for (i = 0; i < svCount; i++) {
int prn = prns[i] - 1;
int prnShift = (1 << prn);
- GpsSatellite satellite = mSatellites[prn];
-
- satellite.mValid = true;
- satellite.mSnr = snrs[i];
- satellite.mElevation = elevations[i];
- satellite.mAzimuth = azimuths[i];
- satellite.mHasEphemeris = ((ephemerisMask & prnShift) != 0);
- satellite.mHasAlmanac = ((almanacMask & prnShift) != 0);
- satellite.mUsedInFix = ((usedInFixMask & prnShift) != 0);
+ if (prn >= 0 && prn < mSatellites.length) {
+ GpsSatellite satellite = mSatellites[prn];
+
+ satellite.mValid = true;
+ satellite.mSnr = snrs[i];
+ satellite.mElevation = elevations[i];
+ satellite.mAzimuth = azimuths[i];
+ satellite.mHasEphemeris = ((ephemerisMask & prnShift) != 0);
+ satellite.mHasAlmanac = ((almanacMask & prnShift) != 0);
+ satellite.mUsedInFix = ((usedInFixMask & prnShift) != 0);
+ }
}
}
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index 2c0399e..2255bf2 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -18,6 +18,7 @@ package android.location;
import android.app.PendingIntent;
import android.location.Address;
+import android.location.Criteria;
import android.location.GeocoderParams;
import android.location.IGeocodeProvider;
import android.location.IGpsStatusListener;
@@ -32,13 +33,15 @@ import android.os.Bundle;
*/
interface ILocationManager
{
- List getAllProviders();
- List getProviders(boolean enabledOnly);
+ List<String> getAllProviders();
+ List<String> getProviders(in Criteria criteria, boolean enabledOnly);
+ String getBestProvider(in Criteria criteria, boolean enabledOnly);
+ boolean providerMeetsCriteria(String provider, in Criteria criteria);
- void requestLocationUpdates(String provider, long minTime, float minDistance,
- in ILocationListener listener);
- void requestLocationUpdatesPI(String provider, long minTime, float minDistance,
- in PendingIntent intent);
+ void requestLocationUpdates(String provider, in Criteria criteria, long minTime, float minDistance,
+ boolean singleShot, in ILocationListener listener);
+ void requestLocationUpdatesPI(String provider, in Criteria criteria, long minTime, float minDistance,
+ boolean singleShot, in PendingIntent intent);
void removeUpdates(in ILocationListener listener);
void removeUpdatesPI(in PendingIntent intent);
@@ -64,6 +67,7 @@ interface ILocationManager
// it need not be shared with other providers.
void reportLocation(in Location location, boolean passive);
+ boolean geocoderIsPresent();
String getFromLocation(double latitude, double longitude, int maxResults,
in GeocoderParams params, out List<Address> addrs);
String getFromLocationName(String locationName,
diff --git a/location/java/android/location/ILocationProvider.aidl b/location/java/android/location/ILocationProvider.aidl
index 97b283c..ecf6789 100644
--- a/location/java/android/location/ILocationProvider.aidl
+++ b/location/java/android/location/ILocationProvider.aidl
@@ -16,9 +16,11 @@
package android.location;
+import android.location.Criteria;
import android.location.Location;
import android.net.NetworkInfo;
import android.os.Bundle;
+import android.os.WorkSource;
/**
* Binder interface for services that implement location providers.
@@ -34,6 +36,7 @@ interface ILocationProvider {
boolean supportsSpeed();
boolean supportsBearing();
int getPowerRequirement();
+ boolean meetsCriteria(in Criteria criteria);
int getAccuracy();
void enable();
void disable();
@@ -41,7 +44,7 @@ interface ILocationProvider {
long getStatusUpdateTime();
String getInternalState();
void enableLocationTracking(boolean enable);
- void setMinTime(long minTime);
+ void setMinTime(long minTime, in WorkSource ws);
void updateNetworkState(int state, in NetworkInfo info);
void updateLocation(in Location location);
boolean sendExtraCommand(String command, inout Bundle extras);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 9e4a16b..9aa84a03 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -28,8 +28,6 @@ import android.util.Log;
import com.android.internal.location.DummyLocationProvider;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
@@ -117,6 +115,44 @@ public class LocationManager {
*/
public static final String KEY_LOCATION_CHANGED = "location";
+ /**
+ * Broadcast intent action indicating that the GPS has either been
+ * enabled or disabled. An intent extra provides this state as a boolean,
+ * where {@code true} means enabled.
+ * @see #EXTRA_GPS_ENABLED
+ *
+ * {@hide}
+ */
+ public static final String GPS_ENABLED_CHANGE_ACTION =
+ "android.location.GPS_ENABLED_CHANGE";
+
+ /**
+ * Broadcast intent action when the configured location providers
+ * change.
+ */
+ public static final String PROVIDERS_CHANGED_ACTION =
+ "android.location.PROVIDERS_CHANGED";
+
+ /**
+ * Broadcast intent action indicating that the GPS has either started or
+ * stopped receiving GPS fixes. An intent extra provides this state as a
+ * boolean, where {@code true} means that the GPS is actively receiving fixes.
+ * @see #EXTRA_GPS_ENABLED
+ *
+ * {@hide}
+ */
+ public static final String GPS_FIX_CHANGE_ACTION =
+ "android.location.GPS_FIX_CHANGE";
+
+ /**
+ * The lookup key for a boolean that indicates whether GPS is enabled or
+ * disabled. {@code true} means GPS is enabled. Retrieve it with
+ * {@link android.content.Intent#getBooleanExtra(String,boolean)}.
+ *
+ * {@hide}
+ */
+ public static final String EXTRA_GPS_ENABLED = "enabled";
+
// Map from LocationListeners to their associated ListenerTransport objects
private HashMap<LocationListener,ListenerTransport> mListeners =
new HashMap<LocationListener,ListenerTransport>();
@@ -218,15 +254,12 @@ public class LocationManager {
* factory Context.getSystemService.
*/
public LocationManager(ILocationManager service) {
- if (false) {
- Log.d(TAG, "Constructor: service = " + service);
- }
mService = service;
}
private LocationProvider createProvider(String name, Bundle info) {
DummyLocationProvider provider =
- new DummyLocationProvider(name);
+ new DummyLocationProvider(name, mService);
provider.setRequiresNetwork(info.getBoolean("network"));
provider.setRequiresSatellite(info.getBoolean("satellite"));
provider.setRequiresCell(info.getBoolean("cell"));
@@ -268,7 +301,7 @@ public class LocationManager {
*/
public List<String> getProviders(boolean enabledOnly) {
try {
- return mService.getProviders(enabledOnly);
+ return mService.getProviders(null, enabledOnly);
} catch (RemoteException ex) {
Log.e(TAG, "getProviders: RemoteException", ex);
}
@@ -313,173 +346,15 @@ public class LocationManager {
* @return list of Strings containing names of the providers
*/
public List<String> getProviders(Criteria criteria, boolean enabledOnly) {
- List<String> goodProviders = Collections.emptyList();
- List<String> providers = getProviders(enabledOnly);
- for (String providerName : providers) {
- LocationProvider provider = getProvider(providerName);
- if (provider != null && provider.meetsCriteria(criteria)) {
- if (goodProviders.isEmpty()) {
- goodProviders = new ArrayList<String>();
- }
- goodProviders.add(providerName);
- }
- }
- return goodProviders;
- }
-
- /**
- * Returns the next looser power requirement, in the sequence:
- *
- * POWER_LOW -> POWER_MEDIUM -> POWER_HIGH -> NO_REQUIREMENT
- */
- private int nextPower(int power) {
- switch (power) {
- case Criteria.POWER_LOW:
- return Criteria.POWER_MEDIUM;
- case Criteria.POWER_MEDIUM:
- return Criteria.POWER_HIGH;
- case Criteria.POWER_HIGH:
- return Criteria.NO_REQUIREMENT;
- case Criteria.NO_REQUIREMENT:
- default:
- return Criteria.NO_REQUIREMENT;
+ if (criteria == null) {
+ throw new IllegalArgumentException("criteria==null");
}
- }
-
- /**
- * Returns the next looser accuracy requirement, in the sequence:
- *
- * ACCURACY_FINE -> ACCURACY_APPROXIMATE-> NO_REQUIREMENT
- */
- private int nextAccuracy(int accuracy) {
- if (accuracy == Criteria.ACCURACY_FINE) {
- return Criteria.ACCURACY_COARSE;
- } else {
- return Criteria.NO_REQUIREMENT;
- }
- }
-
- private abstract class LpComparator implements Comparator<LocationProvider> {
-
- public int compare(int a1, int a2) {
- if (a1 < a2) {
- return -1;
- } else if (a1 > a2) {
- return 1;
- } else {
- return 0;
- }
- }
-
- public int compare(float a1, float a2) {
- if (a1 < a2) {
- return -1;
- } else if (a1 > a2) {
- return 1;
- } else {
- return 0;
- }
- }
- }
-
- private class LpPowerComparator extends LpComparator {
- public int compare(LocationProvider l1, LocationProvider l2) {
- int a1 = l1.getPowerRequirement();
- int a2 = l2.getPowerRequirement();
- return compare(a1, a2); // Smaller is better
- }
-
- public boolean equals(LocationProvider l1, LocationProvider l2) {
- int a1 = l1.getPowerRequirement();
- int a2 = l2.getPowerRequirement();
- return a1 == a2;
- }
- }
-
- private class LpAccuracyComparator extends LpComparator {
- public int compare(LocationProvider l1, LocationProvider l2) {
- int a1 = l1.getAccuracy();
- int a2 = l2.getAccuracy();
- return compare(a1, a2); // Smaller is better
- }
-
- public boolean equals(LocationProvider l1, LocationProvider l2) {
- int a1 = l1.getAccuracy();
- int a2 = l2.getAccuracy();
- return a1 == a2;
- }
- }
-
- private class LpCapabilityComparator extends LpComparator {
-
- private static final int ALTITUDE_SCORE = 4;
- private static final int BEARING_SCORE = 4;
- private static final int SPEED_SCORE = 4;
-
- private int score(LocationProvider p) {
- return (p.supportsAltitude() ? ALTITUDE_SCORE : 0) +
- (p.supportsBearing() ? BEARING_SCORE : 0) +
- (p.supportsSpeed() ? SPEED_SCORE : 0);
- }
-
- public int compare(LocationProvider l1, LocationProvider l2) {
- int a1 = score(l1);
- int a2 = score(l2);
- return compare(-a1, -a2); // Bigger is better
- }
-
- public boolean equals(LocationProvider l1, LocationProvider l2) {
- int a1 = score(l1);
- int a2 = score(l2);
- return a1 == a2;
- }
- }
-
- private LocationProvider best(List<String> providerNames) {
- List<LocationProvider> providers = new ArrayList<LocationProvider>(providerNames.size());
- for (String name : providerNames) {
- providers.add(getProvider(name));
- }
-
- if (providers.size() < 2) {
- return providers.get(0);
- }
-
- // First, sort by power requirement
- Collections.sort(providers, new LpPowerComparator());
- int power = providers.get(0).getPowerRequirement();
- if (power < providers.get(1).getPowerRequirement()) {
- return providers.get(0);
- }
-
- int idx, size;
-
- List<LocationProvider> tmp = new ArrayList<LocationProvider>();
- idx = 0;
- size = providers.size();
- while ((idx < size) && (providers.get(idx).getPowerRequirement() == power)) {
- tmp.add(providers.get(idx));
- idx++;
- }
-
- // Next, sort by accuracy
- Collections.sort(tmp, new LpAccuracyComparator());
- int acc = tmp.get(0).getAccuracy();
- if (acc < tmp.get(1).getAccuracy()) {
- return tmp.get(0);
- }
-
- List<LocationProvider> tmp2 = new ArrayList<LocationProvider>();
- idx = 0;
- size = tmp.size();
- while ((idx < size) && (tmp.get(idx).getAccuracy() == acc)) {
- tmp2.add(tmp.get(idx));
- idx++;
+ try {
+ return mService.getProviders(criteria, enabledOnly);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "getProviders: RemoteException", ex);
}
-
- // Finally, sort by capability "score"
- Collections.sort(tmp2, new LpCapabilityComparator());
- return tmp2.get(0);
+ return null;
}
/**
@@ -505,72 +380,14 @@ public class LocationManager {
* @return name of the provider that best matches the requirements
*/
public String getBestProvider(Criteria criteria, boolean enabledOnly) {
- List<String> goodProviders = getProviders(criteria, enabledOnly);
- if (!goodProviders.isEmpty()) {
- return best(goodProviders).getName();
+ if (criteria == null) {
+ throw new IllegalArgumentException("criteria==null");
}
-
- // Make a copy of the criteria that we can modify
- criteria = new Criteria(criteria);
-
- // Loosen power requirement
- int power = criteria.getPowerRequirement();
- while (goodProviders.isEmpty() && (power != Criteria.NO_REQUIREMENT)) {
- power = nextPower(power);
- criteria.setPowerRequirement(power);
- goodProviders = getProviders(criteria, enabledOnly);
- }
- if (!goodProviders.isEmpty()) {
- return best(goodProviders).getName();
- }
-
-// // Loosen response time requirement
-// int responseTime = criteria.getPreferredResponseTime();
-// while (goodProviders.isEmpty() &&
-// (responseTime != Criteria.NO_REQUIREMENT)) {
-// responseTime += 1000;
-// if (responseTime > 60000) {
-// responseTime = Criteria.NO_REQUIREMENT;
-// }
-// criteria.setPreferredResponseTime(responseTime);
-// goodProviders = getProviders(criteria);
-// }
-// if (!goodProviders.isEmpty()) {
-// return best(goodProviders);
-// }
-
- // Loosen accuracy requirement
- int accuracy = criteria.getAccuracy();
- while (goodProviders.isEmpty() && (accuracy != Criteria.NO_REQUIREMENT)) {
- accuracy = nextAccuracy(accuracy);
- criteria.setAccuracy(accuracy);
- goodProviders = getProviders(criteria, enabledOnly);
- }
- if (!goodProviders.isEmpty()) {
- return best(goodProviders).getName();
- }
-
- // Remove bearing requirement
- criteria.setBearingRequired(false);
- goodProviders = getProviders(criteria, enabledOnly);
- if (!goodProviders.isEmpty()) {
- return best(goodProviders).getName();
- }
-
- // Remove speed requirement
- criteria.setSpeedRequired(false);
- goodProviders = getProviders(criteria, enabledOnly);
- if (!goodProviders.isEmpty()) {
- return best(goodProviders).getName();
- }
-
- // Remove altitude requirement
- criteria.setAltitudeRequired(false);
- goodProviders = getProviders(criteria, enabledOnly);
- if (!goodProviders.isEmpty()) {
- return best(goodProviders).getName();
+ try {
+ return mService.getBestProvider(criteria, enabledOnly);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "getBestProvider: RemoteException", ex);
}
-
return null;
}
@@ -614,8 +431,7 @@ public class LocationManager {
* {@link LocationListener#onLocationChanged} method will be called for
* each location update
*
- * @throws IllegalArgumentException if provider is null or doesn't exist
- * @throws IllegalArgumentException if listener is null
+ * @throws IllegalArgumentException if provider or listener is null
* @throws RuntimeException if the calling thread has no Looper
* @throws SecurityException if no suitable permission is present for the provider.
*/
@@ -627,7 +443,7 @@ public class LocationManager {
if (listener == null) {
throw new IllegalArgumentException("listener==null");
}
- _requestLocationUpdates(provider, minTime, minDistance, listener, null);
+ _requestLocationUpdates(provider, null, minTime, minDistance, false, listener, null);
}
/**
@@ -670,10 +486,10 @@ public class LocationManager {
* each location update
* @param looper a Looper object whose message queue will be used to
* implement the callback mechanism.
+ * If looper is null then the callbacks will be called on the main thread.
*
* @throws IllegalArgumentException if provider is null or doesn't exist
* @throws IllegalArgumentException if listener is null
- * @throws IllegalArgumentException if looper is null
* @throws SecurityException if no suitable permission is present for the provider.
*/
public void requestLocationUpdates(String provider,
@@ -685,15 +501,70 @@ public class LocationManager {
if (listener == null) {
throw new IllegalArgumentException("listener==null");
}
- if (looper == null) {
- throw new IllegalArgumentException("looper==null");
+ _requestLocationUpdates(provider, null, minTime, minDistance, false, listener, looper);
+ }
+
+ /**
+ * Registers the current activity to be notified periodically based on
+ * the specified criteria. Periodically, the supplied LocationListener will
+ * be called with the current Location or with status updates.
+ *
+ * <p> It may take a while to receive the most recent location. If
+ * an immediate location is required, applications may use the
+ * {@link #getLastKnownLocation(String)} method.
+ *
+ * <p> In case the provider is disabled by the user, updates will stop,
+ * and the {@link LocationListener#onProviderDisabled(String)}
+ * method will be called. As soon as the provider is enabled again,
+ * the {@link LocationListener#onProviderEnabled(String)} method will
+ * be called and location updates will start again.
+ *
+ * <p> The frequency of notification may be controlled using the
+ * minTime and minDistance parameters. If minTime is greater than 0,
+ * the LocationManager could potentially rest for minTime milliseconds
+ * between location updates to conserve power. If minDistance is greater than 0,
+ * a location will only be broadcasted if the device moves by minDistance meters.
+ * To obtain notifications as frequently as possible, set both parameters to 0.
+ *
+ * <p> Background services should be careful about setting a sufficiently high
+ * minTime so that the device doesn't consume too much power by keeping the
+ * GPS or wireless radios on all the time. In particular, values under 60000ms
+ * are not recommended.
+ *
+ * <p> The supplied Looper is used to implement the callback mechanism.
+ *
+ * @param minTime the minimum time interval for notifications, in
+ * milliseconds. This field is only used as a hint to conserve power, and actual
+ * time between location updates may be greater or lesser than this value.
+ * @param minDistance the minimum distance interval for notifications,
+ * in meters
+ * @param criteria contains parameters for the location manager to choose the
+ * appropriate provider and parameters to compute the location
+ * @param listener a {#link LocationListener} whose
+ * {@link LocationListener#onLocationChanged} method will be called for
+ * each location update
+ * @param looper a Looper object whose message queue will be used to
+ * implement the callback mechanism.
+ * If looper is null then the callbacks will be called on the main thread.
+ *
+ * @throws IllegalArgumentException if criteria is null
+ * @throws IllegalArgumentException if listener is null
+ * @throws SecurityException if no suitable permission is present to access
+ * the location services.
+ */
+ public void requestLocationUpdates(long minTime, float minDistance,
+ Criteria criteria, LocationListener listener, Looper looper) {
+ if (criteria == null) {
+ throw new IllegalArgumentException("criteria==null");
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("listener==null");
}
- _requestLocationUpdates(provider, minTime, minDistance, listener, looper);
+ _requestLocationUpdates(null, criteria, minTime, minDistance, false, listener, looper);
}
- private void _requestLocationUpdates(String provider,
- long minTime, float minDistance, LocationListener listener,
- Looper looper) {
+ private void _requestLocationUpdates(String provider, Criteria criteria, long minTime,
+ float minDistance, boolean singleShot, LocationListener listener, Looper looper) {
if (minTime < 0L) {
minTime = 0L;
}
@@ -708,7 +579,7 @@ public class LocationManager {
transport = new ListenerTransport(listener, looper);
}
mListeners.put(listener, transport);
- mService.requestLocationUpdates(provider, minTime, minDistance, transport);
+ mService.requestLocationUpdates(provider, criteria, minTime, minDistance, singleShot, transport);
}
} catch (RemoteException ex) {
Log.e(TAG, "requestLocationUpdates: DeadObjectException", ex);
@@ -754,7 +625,7 @@ public class LocationManager {
* time between location updates may be greater or lesser than this value.
* @param minDistance the minimum distance interval for notifications,
* in meters
- * @param intent a {#link PendingIntet} to be sent for each location update
+ * @param intent a {#link PendingIntent} to be sent for each location update
*
* @throws IllegalArgumentException if provider is null or doesn't exist
* @throws IllegalArgumentException if intent is null
@@ -768,11 +639,67 @@ public class LocationManager {
if (intent == null) {
throw new IllegalArgumentException("intent==null");
}
- _requestLocationUpdates(provider, minTime, minDistance, intent);
+ _requestLocationUpdates(provider, null, minTime, minDistance, false, intent);
}
- private void _requestLocationUpdates(String provider,
- long minTime, float minDistance, PendingIntent intent) {
+ /**
+ * Registers the current activity to be notified periodically based on
+ * the specified criteria. Periodically, the supplied PendingIntent will
+ * be broadcast with the current Location or with status updates.
+ *
+ * <p> Location updates are sent with a key of KEY_LOCATION_CHANGED and a Location value.
+ *
+ * <p> It may take a while to receive the most recent location. If
+ * an immediate location is required, applications may use the
+ * {@link #getLastKnownLocation(String)} method.
+ *
+ * <p> The frequency of notification or new locations may be controlled using the
+ * minTime and minDistance parameters. If minTime is greater than 0,
+ * the LocationManager could potentially rest for minTime milliseconds
+ * between location updates to conserve power. If minDistance is greater than 0,
+ * a location will only be broadcast if the device moves by minDistance meters.
+ * To obtain notifications as frequently as possible, set both parameters to 0.
+ *
+ * <p> Background services should be careful about setting a sufficiently high
+ * minTime so that the device doesn't consume too much power by keeping the
+ * GPS or wireless radios on all the time. In particular, values under 60000ms
+ * are not recommended.
+ *
+ * <p> In case the provider is disabled by the user, updates will stop,
+ * and an intent will be sent with an extra with key KEY_PROVIDER_ENABLED and a boolean value
+ * of false. If the provider is re-enabled, an intent will be sent with an
+ * extra with key KEY_PROVIDER_ENABLED and a boolean value of true and location updates will
+ * start again.
+ *
+ * <p> If the provider's status changes, an intent will be sent with an extra with key
+ * KEY_STATUS_CHANGED and an integer value indicating the new status. Any extras associated
+ * with the status update will be sent as well.
+ *
+ * @param minTime the minimum time interval for notifications, in
+ * milliseconds. This field is only used as a hint to conserve power, and actual
+ * time between location updates may be greater or lesser than this value.
+ * @param minDistance the minimum distance interval for notifications,
+ * in meters
+ * @param criteria contains parameters for the location manager to choose the
+ * appropriate provider and parameters to compute the location
+ * @param intent a {#link PendingIntent} to be sent for each location update
+ *
+ * @throws IllegalArgumentException if provider is null or doesn't exist
+ * @throws IllegalArgumentException if intent is null
+ * @throws SecurityException if no suitable permission is present for the provider.
+ */
+ public void requestLocationUpdates(long minTime, float minDistance, Criteria criteria, PendingIntent intent) {
+ if (criteria == null) {
+ throw new IllegalArgumentException("criteria==null");
+ }
+ if (intent == null) {
+ throw new IllegalArgumentException("intent==null");
+ }
+ _requestLocationUpdates(null, criteria, minTime, minDistance, false, intent);
+ }
+
+ private void _requestLocationUpdates(String provider, Criteria criteria,
+ long minTime, float minDistance, boolean singleShot, PendingIntent intent) {
if (minTime < 0L) {
minTime = 0L;
}
@@ -781,13 +708,150 @@ public class LocationManager {
}
try {
- mService.requestLocationUpdatesPI(provider, minTime, minDistance, intent);
+ mService.requestLocationUpdatesPI(provider, criteria, minTime, minDistance, singleShot, intent);
} catch (RemoteException ex) {
Log.e(TAG, "requestLocationUpdates: RemoteException", ex);
}
}
/**
+ * Registers the current activity to be notified periodically by
+ * the named provider. Periodically, the supplied LocationListener will
+ * be called with the current Location or with status updates.
+ *
+ * <p> It may take a while to receive the most recent location. If
+ * an immediate location is required, applications may use the
+ * {@link #getLastKnownLocation(String)} method.
+ *
+ * <p> In case the provider is disabled by the user, updates will stop,
+ * and the {@link LocationListener#onProviderDisabled(String)}
+ * method will be called. As soon as the provider is enabled again,
+ * the {@link LocationListener#onProviderEnabled(String)} method will
+ * be called and location updates will start again.
+ *
+ * <p> The supplied Looper is used to implement the callback mechanism.
+ *
+ * @param provider the name of the provider with which to register
+ * @param listener a {#link LocationListener} whose
+ * {@link LocationListener#onLocationChanged} method will be called for
+ * each location update
+ * @param looper a Looper object whose message queue will be used to
+ * implement the callback mechanism.
+ * If looper is null then the callbacks will be called on the main thread.
+ *
+ * @throws IllegalArgumentException if provider is null or doesn't exist
+ * @throws IllegalArgumentException if listener is null
+ * @throws SecurityException if no suitable permission is present for the provider.
+ */
+ public void requestSingleUpdate(String provider, LocationListener listener, Looper looper) {
+ if (provider == null) {
+ throw new IllegalArgumentException("provider==null");
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("listener==null");
+ }
+ _requestLocationUpdates(provider, null, 0L, 0.0f, true, listener, looper);
+ }
+
+ /**
+ * Registers the current activity to be notified periodically based on
+ * the specified criteria. Periodically, the supplied LocationListener will
+ * be called with the current Location or with status updates.
+ *
+ * <p> It may take a while to receive the most recent location. If
+ * an immediate location is required, applications may use the
+ * {@link #getLastKnownLocation(String)} method.
+ *
+ * <p> In case the provider is disabled by the user, updates will stop,
+ * and the {@link LocationListener#onProviderDisabled(String)}
+ * method will be called. As soon as the provider is enabled again,
+ * the {@link LocationListener#onProviderEnabled(String)} method will
+ * be called and location updates will start again.
+ *
+ * <p> The supplied Looper is used to implement the callback mechanism.
+ *
+ * @param criteria contains parameters for the location manager to choose the
+ * appropriate provider and parameters to compute the location
+ * @param listener a {#link LocationListener} whose
+ * {@link LocationListener#onLocationChanged} method will be called for
+ * each location update
+ * @param looper a Looper object whose message queue will be used to
+ * implement the callback mechanism.
+ * If looper is null then the callbacks will be called on the current thread.
+ *
+ * @throws IllegalArgumentException if criteria is null
+ * @throws IllegalArgumentException if listener is null
+ * @throws SecurityException if no suitable permission is present to access
+ * the location services.
+ */
+ public void requestSingleUpdate(Criteria criteria, LocationListener listener, Looper looper) {
+ if (criteria == null) {
+ throw new IllegalArgumentException("criteria==null");
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("listener==null");
+ }
+ _requestLocationUpdates(null, criteria, 0L, 0.0f, true, listener, looper);
+ }
+
+ /**
+ * Registers the current activity to be notified periodically by
+ * the named provider. Periodically, the supplied PendingIntent will
+ * be broadcast with the current Location or with status updates.
+ *
+ * <p> Location updates are sent with a key of KEY_LOCATION_CHANGED and a Location value.
+ *
+ * <p> It may take a while to receive the most recent location. If
+ * an immediate location is required, applications may use the
+ * {@link #getLastKnownLocation(String)} method.
+ *
+ * @param provider the name of the provider with which to register
+ * @param intent a {#link PendingIntent} to be sent for the location update
+ *
+ * @throws IllegalArgumentException if provider is null or doesn't exist
+ * @throws IllegalArgumentException if intent is null
+ * @throws SecurityException if no suitable permission is present for the provider.
+ */
+ public void requestSingleUpdate(String provider, PendingIntent intent) {
+ if (provider == null) {
+ throw new IllegalArgumentException("provider==null");
+ }
+ if (intent == null) {
+ throw new IllegalArgumentException("intent==null");
+ }
+ _requestLocationUpdates(provider, null, 0L, 0.0f, true, intent);
+ }
+
+ /**
+ * Registers the current activity to be notified periodically based on
+ * the specified criteria. Periodically, the supplied PendingIntent will
+ * be broadcast with the current Location or with status updates.
+ *
+ * <p> Location updates are sent with a key of KEY_LOCATION_CHANGED and a Location value.
+ *
+ * <p> It may take a while to receive the most recent location. If
+ * an immediate location is required, applications may use the
+ * {@link #getLastKnownLocation(String)} method.
+ *
+ * @param criteria contains parameters for the location manager to choose the
+ * appropriate provider and parameters to compute the location
+ * @param intent a {#link PendingIntent} to be sent for the location update
+ *
+ * @throws IllegalArgumentException if provider is null or doesn't exist
+ * @throws IllegalArgumentException if intent is null
+ * @throws SecurityException if no suitable permission is present for the provider.
+ */
+ public void requestSingleUpdate(Criteria criteria, PendingIntent intent) {
+ if (criteria == null) {
+ throw new IllegalArgumentException("criteria==null");
+ }
+ if (intent == null) {
+ throw new IllegalArgumentException("intent==null");
+ }
+ _requestLocationUpdates(null, criteria, 0L, 0.0f, true, intent);
+ }
+
+ /**
* Removes any current registration for location updates of the current activity
* with the given LocationListener. Following this call, updates will no longer
* occur for this listener.
@@ -919,7 +983,7 @@ public class LocationManager {
* @return true if the provider is enabled
*
* @throws SecurityException if no suitable permission is present for the provider.
- * @throws IllegalArgumentException if provider is null or doesn't exist
+ * @throws IllegalArgumentException if provider is null
*/
public boolean isProviderEnabled(String provider) {
if (provider == null) {
diff --git a/location/java/android/location/LocationProvider.java b/location/java/android/location/LocationProvider.java
index bb3e2a5..8c16580 100644
--- a/location/java/android/location/LocationProvider.java
+++ b/location/java/android/location/LocationProvider.java
@@ -16,6 +16,9 @@
package android.location;
+import android.os.RemoteException;
+import android.util.Log;
+
/**
* An abstract superclass for location providers. A location provider
* provides periodic reports on the geographical location of the
@@ -36,7 +39,8 @@ public abstract class LocationProvider {
// in the name of a LocationProvider.
static final String BAD_CHARS_REGEX = "[^a-zA-Z0-9]";
- private String mName;
+ private final String mName;
+ private final ILocationManager mService;
public static final int OUT_OF_SERVICE = 0;
public static final int TEMPORARILY_UNAVAILABLE = 1;
@@ -50,13 +54,13 @@ public abstract class LocationProvider {
*
* {@hide}
*/
- public LocationProvider(String name) {
+ public LocationProvider(String name, ILocationManager service) {
if (name.matches(BAD_CHARS_REGEX)) {
throw new IllegalArgumentException("name " + name +
" contains an illegal character");
}
- // Log.d(TAG, "Constructor: name = " + name);
mName = name;
+ mService = service;
}
/**
@@ -71,29 +75,12 @@ public abstract class LocationProvider {
* false otherwise.
*/
public boolean meetsCriteria(Criteria criteria) {
- // We do not want to match the special passive provider based on criteria.
- if (LocationManager.PASSIVE_PROVIDER.equals(mName)) {
- return false;
- }
- if ((criteria.getAccuracy() != Criteria.NO_REQUIREMENT) &&
- (criteria.getAccuracy() < getAccuracy())) {
- return false;
- }
- int criteriaPower = criteria.getPowerRequirement();
- if ((criteriaPower != Criteria.NO_REQUIREMENT) &&
- (criteriaPower < getPowerRequirement())) {
- return false;
- }
- if (criteria.isAltitudeRequired() && !supportsAltitude()) {
- return false;
- }
- if (criteria.isSpeedRequired() && !supportsSpeed()) {
- return false;
- }
- if (criteria.isBearingRequired() && !supportsBearing()) {
+ try {
+ return mService.providerMeetsCriteria(mName, criteria);
+ } catch (RemoteException e) {
+ Log.e(TAG, "meetsCriteria: RemoteException", e);
return false;
}
- return true;
}
/**
diff --git a/location/java/android/location/LocationProviderInterface.java b/location/java/android/location/LocationProviderInterface.java
deleted file mode 100644
index 5ffe15c..0000000
--- a/location/java/android/location/LocationProviderInterface.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2010 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.location;
-
-import android.location.Location;
-import android.net.NetworkInfo;
-import android.os.Bundle;
-
-/**
- * Location Manager's interface for location providers.
- *
- * {@hide}
- */
-public interface LocationProviderInterface {
- String getName();
- boolean requiresNetwork();
- boolean requiresSatellite();
- boolean requiresCell();
- boolean hasMonetaryCost();
- boolean supportsAltitude();
- boolean supportsSpeed();
- boolean supportsBearing();
- int getPowerRequirement();
- int getAccuracy();
- boolean isEnabled();
- void enable();
- void disable();
- int getStatus(Bundle extras);
- long getStatusUpdateTime();
- void enableLocationTracking(boolean enable);
- String getInternalState();
- void setMinTime(long minTime);
- void updateNetworkState(int state, NetworkInfo info);
- void updateLocation(Location location);
- boolean sendExtraCommand(String command, Bundle extras);
- void addListener(int uid);
- void removeListener(int uid);
-}
diff --git a/location/java/com/android/internal/location/DummyLocationProvider.java b/location/java/com/android/internal/location/DummyLocationProvider.java
index ff5e27b..e7b5143 100644
--- a/location/java/com/android/internal/location/DummyLocationProvider.java
+++ b/location/java/com/android/internal/location/DummyLocationProvider.java
@@ -16,6 +16,7 @@
package com.android.internal.location;
+import android.location.ILocationManager;
import android.location.LocationProvider;
/**
@@ -41,8 +42,8 @@ public class DummyLocationProvider extends LocationProvider {
int mPowerRequirement;
int mAccuracy;
- public DummyLocationProvider(String name) {
- super(name);
+ public DummyLocationProvider(String name, ILocationManager service) {
+ super(name, service);
}
public void setRequiresNetwork(boolean requiresNetwork) {
diff --git a/location/java/com/android/internal/location/GeocoderProxy.java b/location/java/com/android/internal/location/GeocoderProxy.java
deleted file mode 100644
index b06297b..0000000
--- a/location/java/com/android/internal/location/GeocoderProxy.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2010 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 com.android.internal.location;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.location.Address;
-import android.location.GeocoderParams;
-import android.location.IGeocodeProvider;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.util.Log;
-
-import java.util.List;
-
-/**
- * A class for proxying IGeocodeProvider implementations.
- *
- * {@hide}
- */
-public class GeocoderProxy {
-
- private static final String TAG = "GeocoderProxy";
-
- private final Context mContext;
- private final Intent mIntent;
- private final Connection mServiceConnection = new Connection();
- private IGeocodeProvider mProvider;
-
- public GeocoderProxy(Context context, String serviceName) {
- mContext = context;
- mIntent = new Intent(serviceName);
- mContext.bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
- }
-
- private class Connection implements ServiceConnection {
- public void onServiceConnected(ComponentName className, IBinder service) {
- Log.d(TAG, "onServiceConnected " + className);
- synchronized (this) {
- mProvider = IGeocodeProvider.Stub.asInterface(service);
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- Log.d(TAG, "onServiceDisconnected " + className);
- synchronized (this) {
- mProvider = null;
- }
- }
- }
-
- public String getFromLocation(double latitude, double longitude, int maxResults,
- GeocoderParams params, List<Address> addrs) {
- IGeocodeProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- return provider.getFromLocation(latitude, longitude, maxResults,
- params, addrs);
- } catch (RemoteException e) {
- Log.e(TAG, "getFromLocation failed", e);
- }
- }
- return "Service not Available";
- }
-
- public String getFromLocationName(String locationName,
- double lowerLeftLatitude, double lowerLeftLongitude,
- double upperRightLatitude, double upperRightLongitude, int maxResults,
- GeocoderParams params, List<Address> addrs) {
- IGeocodeProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- return provider.getFromLocationName(locationName, lowerLeftLatitude,
- lowerLeftLongitude, upperRightLatitude, upperRightLongitude,
- maxResults, params, addrs);
- } catch (RemoteException e) {
- Log.e(TAG, "getFromLocationName failed", e);
- }
- }
- return "Service not Available";
- }
-}
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
deleted file mode 100755
index ab79147..0000000
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ /dev/null
@@ -1,1475 +0,0 @@
-/*
- * Copyright (C) 2008 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 com.android.internal.location;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.location.Criteria;
-import android.location.IGpsStatusListener;
-import android.location.IGpsStatusProvider;
-import android.location.ILocationManager;
-import android.location.INetInitiatedListener;
-import android.location.Location;
-import android.location.LocationManager;
-import android.location.LocationProvider;
-import android.location.LocationProviderInterface;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.SntpClient;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.util.Log;
-import android.util.SparseIntArray;
-
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.telephony.Phone;
-import com.android.internal.location.GpsNetInitiatedHandler;
-import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.StringBufferInputStream;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.Properties;
-import java.util.Map.Entry;
-import java.util.concurrent.CountDownLatch;
-
-/**
- * A GPS implementation of LocationProvider used by LocationManager.
- *
- * {@hide}
- */
-public class GpsLocationProvider implements LocationProviderInterface {
-
- private static final String TAG = "GpsLocationProvider";
-
- private static final boolean DEBUG = false;
- private static final boolean VERBOSE = false;
-
- /**
- * Broadcast intent action indicating that the GPS has either been
- * enabled or disabled. An intent extra provides this state as a boolean,
- * where {@code true} means enabled.
- * @see #EXTRA_ENABLED
- *
- * {@hide}
- */
- public static final String GPS_ENABLED_CHANGE_ACTION =
- "android.location.GPS_ENABLED_CHANGE";
-
- /**
- * Broadcast intent action indicating that the GPS has either started or
- * stopped receiving GPS fixes. An intent extra provides this state as a
- * boolean, where {@code true} means that the GPS is actively receiving fixes.
- * @see #EXTRA_ENABLED
- *
- * {@hide}
- */
- public static final String GPS_FIX_CHANGE_ACTION =
- "android.location.GPS_FIX_CHANGE";
-
- /**
- * The lookup key for a boolean that indicates whether GPS is enabled or
- * disabled. {@code true} means GPS is enabled. Retrieve it with
- * {@link android.content.Intent#getBooleanExtra(String,boolean)}.
- *
- * {@hide}
- */
- public static final String EXTRA_ENABLED = "enabled";
-
- // these need to match GpsPositionMode enum in gps.h
- private static final int GPS_POSITION_MODE_STANDALONE = 0;
- private static final int GPS_POSITION_MODE_MS_BASED = 1;
- private static final int GPS_POSITION_MODE_MS_ASSISTED = 2;
-
- // these need to match GpsStatusValue defines in gps.h
- private static final int GPS_STATUS_NONE = 0;
- private static final int GPS_STATUS_SESSION_BEGIN = 1;
- private static final int GPS_STATUS_SESSION_END = 2;
- private static final int GPS_STATUS_ENGINE_ON = 3;
- private static final int GPS_STATUS_ENGINE_OFF = 4;
-
- // these need to match GpsApgsStatusValue defines in gps.h
- /** AGPS status event values. */
- private static final int GPS_REQUEST_AGPS_DATA_CONN = 1;
- private static final int GPS_RELEASE_AGPS_DATA_CONN = 2;
- private static final int GPS_AGPS_DATA_CONNECTED = 3;
- private static final int GPS_AGPS_DATA_CONN_DONE = 4;
- private static final int GPS_AGPS_DATA_CONN_FAILED = 5;
-
- // these need to match GpsLocationFlags enum in gps.h
- private static final int LOCATION_INVALID = 0;
- private static final int LOCATION_HAS_LAT_LONG = 1;
- private static final int LOCATION_HAS_ALTITUDE = 2;
- private static final int LOCATION_HAS_SPEED = 4;
- private static final int LOCATION_HAS_BEARING = 8;
- private static final int LOCATION_HAS_ACCURACY = 16;
-
-// IMPORTANT - the GPS_DELETE_* symbols here must match constants in gps.h
- private static final int GPS_DELETE_EPHEMERIS = 0x0001;
- private static final int GPS_DELETE_ALMANAC = 0x0002;
- private static final int GPS_DELETE_POSITION = 0x0004;
- private static final int GPS_DELETE_TIME = 0x0008;
- private static final int GPS_DELETE_IONO = 0x0010;
- private static final int GPS_DELETE_UTC = 0x0020;
- private static final int GPS_DELETE_HEALTH = 0x0040;
- private static final int GPS_DELETE_SVDIR = 0x0080;
- private static final int GPS_DELETE_SVSTEER = 0x0100;
- private static final int GPS_DELETE_SADATA = 0x0200;
- private static final int GPS_DELETE_RTI = 0x0400;
- private static final int GPS_DELETE_CELLDB_INFO = 0x8000;
- private static final int GPS_DELETE_ALL = 0xFFFF;
-
- // these need to match AGpsType enum in gps.h
- private static final int AGPS_TYPE_SUPL = 1;
- private static final int AGPS_TYPE_C2K = 2;
-
- // for mAGpsDataConnectionState
- private static final int AGPS_DATA_CONNECTION_CLOSED = 0;
- private static final int AGPS_DATA_CONNECTION_OPENING = 1;
- private static final int AGPS_DATA_CONNECTION_OPEN = 2;
-
- // Handler messages
- private static final int CHECK_LOCATION = 1;
- private static final int ENABLE = 2;
- private static final int ENABLE_TRACKING = 3;
- private static final int UPDATE_NETWORK_STATE = 4;
- private static final int INJECT_NTP_TIME = 5;
- private static final int DOWNLOAD_XTRA_DATA = 6;
- private static final int UPDATE_LOCATION = 7;
- private static final int ADD_LISTENER = 8;
- private static final int REMOVE_LISTENER = 9;
-
- private static final String PROPERTIES_FILE = "/etc/gps.conf";
-
- private int mLocationFlags = LOCATION_INVALID;
-
- // current status
- private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE;
-
- // time for last status update
- private long mStatusUpdateTime = SystemClock.elapsedRealtime();
-
- // turn off GPS fix icon if we haven't received a fix in 10 seconds
- private static final long RECENT_FIX_TIMEOUT = 10;
-
- // number of fixes to receive before disabling GPS
- private static final int MIN_FIX_COUNT = 10;
-
- // stop trying if we do not receive a fix within 60 seconds
- private static final int NO_FIX_TIMEOUT = 60;
-
- // true if we are enabled
- private volatile boolean mEnabled;
-
- // true if we have network connectivity
- private boolean mNetworkAvailable;
-
- // flags to trigger NTP or XTRA data download when network becomes available
- // initialized to true so we do NTP and XTRA when the network comes up after booting
- private boolean mInjectNtpTimePending = true;
- private boolean mDownloadXtraDataPending = false;
-
- // true if GPS is navigating
- private boolean mNavigating;
-
- // true if GPS engine is on
- private boolean mEngineOn;
-
- // requested frequency of fixes, in seconds
- private int mFixInterval = 1;
-
- // number of fixes we have received since we started navigating
- private int mFixCount;
-
- // true if we started navigation
- private boolean mStarted;
-
- // true if XTRA is supported
- private boolean mSupportsXtra;
-
- // for calculating time to first fix
- private long mFixRequestTime = 0;
- // time to first fix for most recent session
- private int mTTFF = 0;
- // time we received our last fix
- private long mLastFixTime;
-
- // properties loaded from PROPERTIES_FILE
- private Properties mProperties;
- private String mNtpServer;
- private String mSuplServerHost;
- private int mSuplServerPort;
- private String mC2KServerHost;
- private int mC2KServerPort;
-
- private final Context mContext;
- private final ILocationManager mLocationManager;
- private Location mLocation = new Location(LocationManager.GPS_PROVIDER);
- private Bundle mLocationExtras = new Bundle();
- private ArrayList<Listener> mListeners = new ArrayList<Listener>();
-
- // GpsLocationProvider's handler thread
- private final Thread mThread;
- // Handler for processing events in mThread.
- private Handler mHandler;
- // Used to signal when our main thread has initialized everything
- private final CountDownLatch mInitializedLatch = new CountDownLatch(1);
- // Thread for receiving events from the native code
- private Thread mEventThread;
-
- private String mAGpsApn;
- private int mAGpsDataConnectionState;
- private final ConnectivityManager mConnMgr;
- private final GpsNetInitiatedHandler mNIHandler;
-
- // Wakelocks
- private final static String WAKELOCK_KEY = "GpsLocationProvider";
- private final PowerManager.WakeLock mWakeLock;
-
- // Alarms
- private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
- private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT";
- private final AlarmManager mAlarmManager;
- private final PendingIntent mWakeupIntent;
- private final PendingIntent mTimeoutIntent;
-
- private final IBatteryStats mBatteryStats;
- private final SparseIntArray mClientUids = new SparseIntArray();
-
- // how often to request NTP time, in milliseconds
- // current setting 4 hours
- private static final long NTP_INTERVAL = 4*60*60*1000;
- // how long to wait if we have a network error in NTP or XTRA downloading
- // current setting - 5 minutes
- private static final long RETRY_INTERVAL = 5*60*1000;
-
- // to avoid injecting bad NTP time, we reject any time fixes that differ from system time
- // by more than 5 minutes.
- private static final long MAX_NTP_SYSTEM_TIME_OFFSET = 5*60*1000;
-
- private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() {
- public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException {
- if (listener == null) {
- throw new NullPointerException("listener is null in addGpsStatusListener");
- }
-
- synchronized(mListeners) {
- IBinder binder = listener.asBinder();
- int size = mListeners.size();
- for (int i = 0; i < size; i++) {
- Listener test = mListeners.get(i);
- if (binder.equals(test.mListener.asBinder())) {
- // listener already added
- return;
- }
- }
-
- Listener l = new Listener(listener);
- binder.linkToDeath(l, 0);
- mListeners.add(l);
- }
- }
-
- public void removeGpsStatusListener(IGpsStatusListener listener) {
- if (listener == null) {
- throw new NullPointerException("listener is null in addGpsStatusListener");
- }
-
- synchronized(mListeners) {
- IBinder binder = listener.asBinder();
- Listener l = null;
- int size = mListeners.size();
- for (int i = 0; i < size && l == null; i++) {
- Listener test = mListeners.get(i);
- if (binder.equals(test.mListener.asBinder())) {
- l = test;
- }
- }
-
- if (l != null) {
- mListeners.remove(l);
- binder.unlinkToDeath(l, 0);
- }
- }
- }
- };
-
- public IGpsStatusProvider getGpsStatusProvider() {
- return mGpsStatusProvider;
- }
-
- private final BroadcastReceiver mBroadcastReciever = new BroadcastReceiver() {
- @Override public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
-
- if (action.equals(ALARM_WAKEUP)) {
- if (DEBUG) Log.d(TAG, "ALARM_WAKEUP");
- startNavigating();
- } else if (action.equals(ALARM_TIMEOUT)) {
- if (DEBUG) Log.d(TAG, "ALARM_TIMEOUT");
- hibernate();
- }
- }
- };
-
- public static boolean isSupported() {
- return native_is_supported();
- }
-
- public GpsLocationProvider(Context context, ILocationManager locationManager) {
- mContext = context;
- mLocationManager = locationManager;
- mNIHandler = new GpsNetInitiatedHandler(context, this);
-
- mLocation.setExtras(mLocationExtras);
-
- // Create a wake lock
- PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
-
- mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
- mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
- mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
-
- mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
-
- // Battery statistics service to be notified when GPS turns on or off
- mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo"));
-
- mProperties = new Properties();
- try {
- File file = new File(PROPERTIES_FILE);
- FileInputStream stream = new FileInputStream(file);
- mProperties.load(stream);
- stream.close();
- mNtpServer = mProperties.getProperty("NTP_SERVER", null);
-
- mSuplServerHost = mProperties.getProperty("SUPL_HOST");
- String portString = mProperties.getProperty("SUPL_PORT");
- if (mSuplServerHost != null && portString != null) {
- try {
- mSuplServerPort = Integer.parseInt(portString);
- } catch (NumberFormatException e) {
- Log.e(TAG, "unable to parse SUPL_PORT: " + portString);
- }
- }
-
- mC2KServerHost = mProperties.getProperty("C2K_HOST");
- portString = mProperties.getProperty("C2K_PORT");
- if (mC2KServerHost != null && portString != null) {
- try {
- mC2KServerPort = Integer.parseInt(portString);
- } catch (NumberFormatException e) {
- Log.e(TAG, "unable to parse C2K_PORT: " + portString);
- }
- }
- } catch (IOException e) {
- Log.w(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE);
- }
-
- // wait until we are fully initialized before returning
- mThread = new GpsLocationProviderThread();
- mThread.start();
- while (true) {
- try {
- mInitializedLatch.await();
- break;
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- }
- }
- }
-
- private void initialize() {
- // register our receiver on our thread rather than the main thread
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(ALARM_WAKEUP);
- intentFilter.addAction(ALARM_TIMEOUT);
- mContext.registerReceiver(mBroadcastReciever, intentFilter);
- }
-
- /**
- * Returns the name of this provider.
- */
- public String getName() {
- return LocationManager.GPS_PROVIDER;
- }
-
- /**
- * Returns true if the provider requires access to a
- * data network (e.g., the Internet), false otherwise.
- */
- public boolean requiresNetwork() {
- return true;
- }
-
- public void updateNetworkState(int state, NetworkInfo info) {
- mHandler.removeMessages(UPDATE_NETWORK_STATE);
- Message m = Message.obtain(mHandler, UPDATE_NETWORK_STATE);
- m.arg1 = state;
- m.obj = info;
- mHandler.sendMessage(m);
- }
-
- private void handleUpdateNetworkState(int state, NetworkInfo info) {
- mNetworkAvailable = (state == LocationProvider.AVAILABLE);
-
- if (DEBUG) {
- Log.d(TAG, "updateNetworkState " + (mNetworkAvailable ? "available" : "unavailable")
- + " info: " + info);
- }
-
- if (info != null && info.getType() == ConnectivityManager.TYPE_MOBILE_SUPL
- && mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) {
- String apnName = info.getExtraInfo();
- if (mNetworkAvailable && apnName != null && apnName.length() > 0) {
- mAGpsApn = apnName;
- if (DEBUG) Log.d(TAG, "call native_agps_data_conn_open");
- native_agps_data_conn_open(apnName);
- mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN;
- } else {
- if (DEBUG) Log.d(TAG, "call native_agps_data_conn_failed");
- mAGpsApn = null;
- mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED;
- native_agps_data_conn_failed();
- }
- }
-
- if (mNetworkAvailable) {
- if (mInjectNtpTimePending) {
- mHandler.removeMessages(INJECT_NTP_TIME);
- mHandler.sendMessage(Message.obtain(mHandler, INJECT_NTP_TIME));
- }
- if (mDownloadXtraDataPending) {
- mHandler.removeMessages(DOWNLOAD_XTRA_DATA);
- mHandler.sendMessage(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA));
- }
- }
- }
-
- private void handleInjectNtpTime() {
- if (!mNetworkAvailable) {
- // try again when network is up
- mInjectNtpTimePending = true;
- return;
- }
- mInjectNtpTimePending = false;
-
- SntpClient client = new SntpClient();
- long delay;
-
- if (client.requestTime(mNtpServer, 10000)) {
- long time = client.getNtpTime();
- long timeReference = client.getNtpTimeReference();
- int certainty = (int)(client.getRoundTripTime()/2);
- long now = System.currentTimeMillis();
- long systemTimeOffset = time - now;
-
- Log.d(TAG, "NTP server returned: "
- + time + " (" + new Date(time)
- + ") reference: " + timeReference
- + " certainty: " + certainty
- + " system time offset: " + systemTimeOffset);
-
- // sanity check NTP time and do not use if it is too far from system time
- if (systemTimeOffset < 0) {
- systemTimeOffset = -systemTimeOffset;
- }
- if (systemTimeOffset < MAX_NTP_SYSTEM_TIME_OFFSET) {
- native_inject_time(time, timeReference, certainty);
- } else {
- Log.e(TAG, "NTP time differs from system time by " + systemTimeOffset
- + "ms. Ignoring.");
- }
- delay = NTP_INTERVAL;
- } else {
- if (DEBUG) Log.d(TAG, "requestTime failed");
- delay = RETRY_INTERVAL;
- }
-
- // send delayed message for next NTP injection
- mHandler.removeMessages(INJECT_NTP_TIME);
- mHandler.sendMessageDelayed(Message.obtain(mHandler, INJECT_NTP_TIME), delay);
- }
-
- private void handleDownloadXtraData() {
- if (!mNetworkAvailable) {
- // try again when network is up
- mDownloadXtraDataPending = true;
- return;
- }
- mDownloadXtraDataPending = false;
-
-
- GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mContext, mProperties);
- byte[] data = xtraDownloader.downloadXtraData();
- if (data != null) {
- if (DEBUG) {
- Log.d(TAG, "calling native_inject_xtra_data");
- }
- native_inject_xtra_data(data, data.length);
- } else {
- // try again later
- mHandler.removeMessages(DOWNLOAD_XTRA_DATA);
- mHandler.sendMessageDelayed(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA), RETRY_INTERVAL);
- }
- }
-
- /**
- * This is called to inform us when another location provider returns a location.
- * Someday we might use this for network location injection to aid the GPS
- */
- public void updateLocation(Location location) {
- mHandler.removeMessages(UPDATE_LOCATION);
- Message m = Message.obtain(mHandler, UPDATE_LOCATION);
- m.obj = location;
- mHandler.sendMessage(m);
- }
-
- private void handleUpdateLocation(Location location) {
- if (location.hasAccuracy()) {
- native_inject_location(location.getLatitude(), location.getLongitude(),
- location.getAccuracy());
- }
- }
-
- /**
- * Returns true if the provider requires access to a
- * satellite-based positioning system (e.g., GPS), false
- * otherwise.
- */
- public boolean requiresSatellite() {
- return true;
- }
-
- /**
- * Returns true if the provider requires access to an appropriate
- * cellular network (e.g., to make use of cell tower IDs), false
- * otherwise.
- */
- public boolean requiresCell() {
- return false;
- }
-
- /**
- * Returns true if the use of this provider may result in a
- * monetary charge to the user, false if use is free. It is up to
- * each provider to give accurate information.
- */
- public boolean hasMonetaryCost() {
- return false;
- }
-
- /**
- * Returns true if the provider is able to provide altitude
- * information, false otherwise. A provider that reports altitude
- * under most circumstances but may occassionally not report it
- * should return true.
- */
- public boolean supportsAltitude() {
- return true;
- }
-
- /**
- * Returns true if the provider is able to provide speed
- * information, false otherwise. A provider that reports speed
- * under most circumstances but may occassionally not report it
- * should return true.
- */
- public boolean supportsSpeed() {
- return true;
- }
-
- /**
- * Returns true if the provider is able to provide bearing
- * information, false otherwise. A provider that reports bearing
- * under most circumstances but may occassionally not report it
- * should return true.
- */
- public boolean supportsBearing() {
- return true;
- }
-
- /**
- * Returns the power requirement for this provider.
- *
- * @return the power requirement for this provider, as one of the
- * constants Criteria.POWER_REQUIREMENT_*.
- */
- public int getPowerRequirement() {
- return Criteria.POWER_HIGH;
- }
-
- /**
- * Returns the horizontal accuracy of this provider
- *
- * @return the accuracy of location from this provider, as one
- * of the constants Criteria.ACCURACY_*.
- */
- public int getAccuracy() {
- return Criteria.ACCURACY_FINE;
- }
-
- /**
- * Enables this provider. When enabled, calls to getStatus()
- * must be handled. Hardware may be started up
- * when the provider is enabled.
- */
- public void enable() {
- synchronized (mHandler) {
- mHandler.removeMessages(ENABLE);
- Message m = Message.obtain(mHandler, ENABLE);
- m.arg1 = 1;
- mHandler.sendMessage(m);
- }
- }
-
- private void handleEnable() {
- if (DEBUG) Log.d(TAG, "handleEnable");
- if (mEnabled) return;
- mEnabled = native_init();
-
- if (mEnabled) {
- mSupportsXtra = native_supports_xtra();
- if (mSuplServerHost != null) {
- native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort);
- }
- if (mC2KServerHost != null) {
- native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort);
- }
-
- // run event listener thread while we are enabled
- mEventThread = new GpsEventThread();
- mEventThread.start();
- } else {
- Log.w(TAG, "Failed to enable location provider");
- }
- }
-
- /**
- * Disables this provider. When disabled, calls to getStatus()
- * need not be handled. Hardware may be shut
- * down while the provider is disabled.
- */
- public void disable() {
- synchronized (mHandler) {
- mHandler.removeMessages(ENABLE);
- Message m = Message.obtain(mHandler, ENABLE);
- m.arg1 = 0;
- mHandler.sendMessage(m);
- }
- }
-
- private void handleDisable() {
- if (DEBUG) Log.d(TAG, "handleDisable");
- if (!mEnabled) return;
-
- mEnabled = false;
- stopNavigating();
- native_disable();
-
- // make sure our event thread exits
- if (mEventThread != null) {
- try {
- mEventThread.join();
- } catch (InterruptedException e) {
- Log.w(TAG, "InterruptedException when joining mEventThread");
- }
- mEventThread = null;
- }
-
- // do this before releasing wakelock
- native_cleanup();
-
- // The GpsEventThread does not wait for the GPS to shutdown
- // so we need to report the GPS_STATUS_ENGINE_OFF event here
- if (mNavigating) {
- reportStatus(GPS_STATUS_SESSION_END);
- }
- if (mEngineOn) {
- reportStatus(GPS_STATUS_ENGINE_OFF);
- }
- }
-
- public boolean isEnabled() {
- return mEnabled;
- }
-
- public int getStatus(Bundle extras) {
- if (extras != null) {
- extras.putInt("satellites", mSvCount);
- }
- return mStatus;
- }
-
- private void updateStatus(int status, int svCount) {
- if (status != mStatus || svCount != mSvCount) {
- mStatus = status;
- mSvCount = svCount;
- mLocationExtras.putInt("satellites", svCount);
- mStatusUpdateTime = SystemClock.elapsedRealtime();
- }
- }
-
- public long getStatusUpdateTime() {
- return mStatusUpdateTime;
- }
-
- public void enableLocationTracking(boolean enable) {
- synchronized (mHandler) {
- mHandler.removeMessages(ENABLE_TRACKING);
- Message m = Message.obtain(mHandler, ENABLE_TRACKING);
- m.arg1 = (enable ? 1 : 0);
- mHandler.sendMessage(m);
- }
- }
-
- private void handleEnableLocationTracking(boolean enable) {
- if (enable) {
- mTTFF = 0;
- mLastFixTime = 0;
- startNavigating();
- } else {
- mAlarmManager.cancel(mWakeupIntent);
- mAlarmManager.cancel(mTimeoutIntent);
- stopNavigating();
- }
- }
-
- public void setMinTime(long minTime) {
- if (DEBUG) Log.d(TAG, "setMinTime " + minTime);
-
- if (minTime >= 0) {
- int interval = (int)(minTime/1000);
- if (interval < 1) {
- interval = 1;
- }
- mFixInterval = interval;
- }
- }
-
- public String getInternalState() {
- return native_get_internal_state();
- }
-
- private final class Listener implements IBinder.DeathRecipient {
- final IGpsStatusListener mListener;
-
- int mSensors = 0;
-
- Listener(IGpsStatusListener listener) {
- mListener = listener;
- }
-
- public void binderDied() {
- if (DEBUG) Log.d(TAG, "GPS status listener died");
-
- synchronized(mListeners) {
- mListeners.remove(this);
- }
- if (mListener != null) {
- mListener.asBinder().unlinkToDeath(this, 0);
- }
- }
- }
-
- public void addListener(int uid) {
- Message m = Message.obtain(mHandler, ADD_LISTENER);
- m.arg1 = uid;
- mHandler.sendMessage(m);
- }
-
- private void handleAddListener(int uid) {
- synchronized(mListeners) {
- if (mClientUids.indexOfKey(uid) >= 0) {
- // Shouldn't be here -- already have this uid.
- Log.w(TAG, "Duplicate add listener for uid " + uid);
- return;
- }
- mClientUids.put(uid, 0);
- if (mNavigating) {
- try {
- mBatteryStats.noteStartGps(uid);
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException in addListener");
- }
- }
- }
- }
-
- public void removeListener(int uid) {
- Message m = Message.obtain(mHandler, REMOVE_LISTENER);
- m.arg1 = uid;
- mHandler.sendMessage(m);
- }
-
- private void handleRemoveListener(int uid) {
- synchronized(mListeners) {
- if (mClientUids.indexOfKey(uid) < 0) {
- // Shouldn't be here -- don't have this uid.
- Log.w(TAG, "Unneeded remove listener for uid " + uid);
- return;
- }
- mClientUids.delete(uid);
- if (mNavigating) {
- try {
- mBatteryStats.noteStopGps(uid);
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException in removeListener");
- }
- }
- }
- }
-
- public boolean sendExtraCommand(String command, Bundle extras) {
-
- if ("delete_aiding_data".equals(command)) {
- return deleteAidingData(extras);
- }
- if ("force_time_injection".equals(command)) {
- mHandler.removeMessages(INJECT_NTP_TIME);
- mHandler.sendMessage(Message.obtain(mHandler, INJECT_NTP_TIME));
- return true;
- }
- if ("force_xtra_injection".equals(command)) {
- if (mSupportsXtra) {
- xtraDownloadRequest();
- return true;
- }
- return false;
- }
-
- Log.w(TAG, "sendExtraCommand: unknown command " + command);
- return false;
- }
-
- private boolean deleteAidingData(Bundle extras) {
- int flags;
-
- if (extras == null) {
- flags = GPS_DELETE_ALL;
- } else {
- flags = 0;
- if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS;
- if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC;
- if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION;
- if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME;
- if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO;
- if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC;
- if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH;
- if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR;
- if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER;
- if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA;
- if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI;
- if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO;
- if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL;
- }
-
- if (flags != 0) {
- native_delete_aiding_data(flags);
- return true;
- }
-
- return false;
- }
-
- private void startNavigating() {
- if (!mStarted) {
- if (DEBUG) Log.d(TAG, "startNavigating");
- mStarted = true;
- int positionMode;
- if (Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.ASSISTED_GPS_ENABLED, 1) != 0) {
- positionMode = GPS_POSITION_MODE_MS_BASED;
- } else {
- positionMode = GPS_POSITION_MODE_STANDALONE;
- }
-
- if (!native_start(positionMode, false, 1)) {
- mStarted = false;
- Log.e(TAG, "native_start failed in startNavigating()");
- return;
- }
-
- // reset SV count to zero
- updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0);
- mFixCount = 0;
- mFixRequestTime = System.currentTimeMillis();
- // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
- // and our fix interval is not short
- if (mFixInterval >= NO_FIX_TIMEOUT) {
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT * 1000, mTimeoutIntent);
- }
- }
- }
-
- private void stopNavigating() {
- if (DEBUG) Log.d(TAG, "stopNavigating");
- if (mStarted) {
- mStarted = false;
- native_stop();
- mTTFF = 0;
- mLastFixTime = 0;
- mLocationFlags = LOCATION_INVALID;
-
- // reset SV count to zero
- updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0);
- }
- }
-
- private void hibernate() {
- // stop GPS until our next fix interval arrives
- stopNavigating();
- mFixCount = 0;
- mAlarmManager.cancel(mTimeoutIntent);
- mAlarmManager.cancel(mWakeupIntent);
- long now = SystemClock.elapsedRealtime();
- mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- SystemClock.elapsedRealtime() + mFixInterval * 1000, mWakeupIntent);
- }
-
- /**
- * called from native code to update our position.
- */
- private void reportLocation(int flags, double latitude, double longitude, double altitude,
- float speed, float bearing, float accuracy, long timestamp) {
- if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude +
- " timestamp: " + timestamp);
-
- synchronized (mLocation) {
- mLocationFlags = flags;
- if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) {
- mLocation.setLatitude(latitude);
- mLocation.setLongitude(longitude);
- mLocation.setTime(timestamp);
- }
- if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) {
- mLocation.setAltitude(altitude);
- } else {
- mLocation.removeAltitude();
- }
- if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) {
- mLocation.setSpeed(speed);
- } else {
- mLocation.removeSpeed();
- }
- if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) {
- mLocation.setBearing(bearing);
- } else {
- mLocation.removeBearing();
- }
- if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) {
- mLocation.setAccuracy(accuracy);
- } else {
- mLocation.removeAccuracy();
- }
-
- try {
- mLocationManager.reportLocation(mLocation, false);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException calling reportLocation");
- }
- }
-
- mLastFixTime = System.currentTimeMillis();
- // report time to first fix
- if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) {
- mTTFF = (int)(mLastFixTime - mFixRequestTime);
- if (DEBUG) Log.d(TAG, "TTFF: " + mTTFF);
-
- // notify status listeners
- synchronized(mListeners) {
- int size = mListeners.size();
- for (int i = 0; i < size; i++) {
- Listener listener = mListeners.get(i);
- try {
- listener.mListener.onFirstFix(mTTFF);
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException in stopNavigating");
- mListeners.remove(listener);
- // adjust for size of list changing
- size--;
- }
- }
- }
- }
-
- if (mStarted && mStatus != LocationProvider.AVAILABLE) {
- // we still want to time out if we do not receive MIN_FIX_COUNT
- // within the time out and we are requesting infrequent fixes
- if (mFixInterval < NO_FIX_TIMEOUT) {
- mAlarmManager.cancel(mTimeoutIntent);
- }
-
- // send an intent to notify that the GPS is receiving fixes.
- Intent intent = new Intent(GPS_FIX_CHANGE_ACTION);
- intent.putExtra(EXTRA_ENABLED, true);
- mContext.sendBroadcast(intent);
- updateStatus(LocationProvider.AVAILABLE, mSvCount);
- }
-
- if (mFixCount++ >= MIN_FIX_COUNT && mFixInterval > 1) {
- if (DEBUG) Log.d(TAG, "exceeded MIN_FIX_COUNT");
- hibernate();
- }
- }
-
- /**
- * called from native code to update our status
- */
- private void reportStatus(int status) {
- if (VERBOSE) Log.v(TAG, "reportStatus status: " + status);
-
- synchronized(mListeners) {
- boolean wasNavigating = mNavigating;
-
- switch (status) {
- case GPS_STATUS_SESSION_BEGIN:
- mNavigating = true;
- mEngineOn = true;
- break;
- case GPS_STATUS_SESSION_END:
- mNavigating = false;
- break;
- case GPS_STATUS_ENGINE_ON:
- mEngineOn = true;
- break;
- case GPS_STATUS_ENGINE_OFF:
- mEngineOn = false;
- mNavigating = false;
- break;
- }
-
- // beware, the events can come out of order
- if ((mNavigating || mEngineOn) && !mWakeLock.isHeld()) {
- if (DEBUG) Log.d(TAG, "Acquiring wakelock");
- mWakeLock.acquire();
- }
-
- if (wasNavigating != mNavigating) {
- int size = mListeners.size();
- for (int i = 0; i < size; i++) {
- Listener listener = mListeners.get(i);
- try {
- if (mNavigating) {
- listener.mListener.onGpsStarted();
- } else {
- listener.mListener.onGpsStopped();
- }
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException in reportStatus");
- mListeners.remove(listener);
- // adjust for size of list changing
- size--;
- }
- }
-
- try {
- // update battery stats
- for (int i=mClientUids.size() - 1; i >= 0; i--) {
- int uid = mClientUids.keyAt(i);
- if (mNavigating) {
- mBatteryStats.noteStartGps(uid);
- } else {
- mBatteryStats.noteStopGps(uid);
- }
- }
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException in reportStatus");
- }
-
- // send an intent to notify that the GPS has been enabled or disabled.
- Intent intent = new Intent(GPS_ENABLED_CHANGE_ACTION);
- intent.putExtra(EXTRA_ENABLED, mNavigating);
- mContext.sendBroadcast(intent);
- }
-
- // beware, the events can come out of order
- if (!mNavigating && !mEngineOn && mWakeLock.isHeld()) {
- if (DEBUG) Log.d(TAG, "Releasing wakelock");
- mWakeLock.release();
- }
- }
- }
-
- /**
- * called from native code to update SV info
- */
- private void reportSvStatus() {
-
- int svCount = native_read_sv_status(mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks);
-
- synchronized(mListeners) {
- int size = mListeners.size();
- for (int i = 0; i < size; i++) {
- Listener listener = mListeners.get(i);
- try {
- listener.mListener.onSvStatusChanged(svCount, mSvs, mSnrs,
- mSvElevations, mSvAzimuths, mSvMasks[EPHEMERIS_MASK],
- mSvMasks[ALMANAC_MASK], mSvMasks[USED_FOR_FIX_MASK]);
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException in reportSvInfo");
- mListeners.remove(listener);
- // adjust for size of list changing
- size--;
- }
- }
- }
-
- if (VERBOSE) {
- Log.v(TAG, "SV count: " + svCount +
- " ephemerisMask: " + Integer.toHexString(mSvMasks[EPHEMERIS_MASK]) +
- " almanacMask: " + Integer.toHexString(mSvMasks[ALMANAC_MASK]));
- for (int i = 0; i < svCount; i++) {
- Log.v(TAG, "sv: " + mSvs[i] +
- " snr: " + (float)mSnrs[i]/10 +
- " elev: " + mSvElevations[i] +
- " azimuth: " + mSvAzimuths[i] +
- ((mSvMasks[EPHEMERIS_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " E") +
- ((mSvMasks[ALMANAC_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " A") +
- ((mSvMasks[USED_FOR_FIX_MASK] & (1 << (mSvs[i] - 1))) == 0 ? "" : "U"));
- }
- }
-
- updateStatus(mStatus, svCount);
-
- if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
- System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT * 1000) {
- // send an intent to notify that the GPS is no longer receiving fixes.
- Intent intent = new Intent(GPS_FIX_CHANGE_ACTION);
- intent.putExtra(EXTRA_ENABLED, false);
- mContext.sendBroadcast(intent);
- updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount);
- }
- }
-
- /**
- * called from native code to update AGPS status
- */
- private void reportAGpsStatus(int type, int status) {
- switch (status) {
- case GPS_REQUEST_AGPS_DATA_CONN:
- int result = mConnMgr.startUsingNetworkFeature(
- ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL);
- if (result == Phone.APN_ALREADY_ACTIVE) {
- if (mAGpsApn != null) {
- native_agps_data_conn_open(mAGpsApn);
- mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN;
- } else {
- Log.e(TAG, "mAGpsApn not set when receiving Phone.APN_ALREADY_ACTIVE");
- native_agps_data_conn_failed();
- }
- } else if (result == Phone.APN_REQUEST_STARTED) {
- mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING;
- } else {
- native_agps_data_conn_failed();
- }
- break;
- case GPS_RELEASE_AGPS_DATA_CONN:
- if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) {
- mConnMgr.stopUsingNetworkFeature(
- ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL);
- native_agps_data_conn_closed();
- mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED;
- }
- break;
- case GPS_AGPS_DATA_CONNECTED:
- // Log.d(TAG, "GPS_AGPS_DATA_CONNECTED");
- break;
- case GPS_AGPS_DATA_CONN_DONE:
- // Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE");
- break;
- case GPS_AGPS_DATA_CONN_FAILED:
- // Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED");
- break;
- }
- }
-
- /**
- * called from native code to report NMEA data received
- */
- private void reportNmea(int index, long timestamp) {
- synchronized(mListeners) {
- int size = mListeners.size();
- if (size > 0) {
- // don't bother creating the String if we have no listeners
- int length = native_read_nmea(index, mNmeaBuffer, mNmeaBuffer.length);
- String nmea = new String(mNmeaBuffer, 0, length);
-
- for (int i = 0; i < size; i++) {
- Listener listener = mListeners.get(i);
- try {
- listener.mListener.onNmeaReceived(timestamp, nmea);
- } catch (RemoteException e) {
- Log.w(TAG, "RemoteException in reportNmea");
- mListeners.remove(listener);
- // adjust for size of list changing
- size--;
- }
- }
- }
- }
- }
-
- /**
- * called from native code to request XTRA data
- */
- private void xtraDownloadRequest() {
- if (DEBUG) Log.d(TAG, "xtraDownloadRequest");
- mHandler.removeMessages(DOWNLOAD_XTRA_DATA);
- mHandler.sendMessage(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA));
- }
-
- //=============================================================
- // NI Client support
- //=============================================================
- private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() {
- // Sends a response for an NI reqeust to HAL.
- public boolean sendNiResponse(int notificationId, int userResponse)
- {
- // TODO Add Permission check
-
- StringBuilder extrasBuf = new StringBuilder();
-
- if (DEBUG) Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
- ", response: " + userResponse);
-
- native_send_ni_response(notificationId, userResponse);
-
- return true;
- }
- };
-
- public INetInitiatedListener getNetInitiatedListener() {
- return mNetInitiatedListener;
- }
-
- // Called by JNI function to report an NI request.
- @SuppressWarnings("deprecation")
- public void reportNiNotification(
- int notificationId,
- int niType,
- int notifyFlags,
- int timeout,
- int defaultResponse,
- String requestorId,
- String text,
- int requestorIdEncoding,
- int textEncoding,
- String extras // Encoded extra data
- )
- {
- Log.i(TAG, "reportNiNotification: entered");
- Log.i(TAG, "notificationId: " + notificationId +
- ", niType: " + niType +
- ", notifyFlags: " + notifyFlags +
- ", timeout: " + timeout +
- ", defaultResponse: " + defaultResponse);
-
- Log.i(TAG, "requestorId: " + requestorId +
- ", text: " + text +
- ", requestorIdEncoding: " + requestorIdEncoding +
- ", textEncoding: " + textEncoding);
-
- GpsNiNotification notification = new GpsNiNotification();
-
- notification.notificationId = notificationId;
- notification.niType = niType;
- notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
- notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
- notification.privacyOverride = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
- notification.timeout = timeout;
- notification.defaultResponse = defaultResponse;
- notification.requestorId = requestorId;
- notification.text = text;
- notification.requestorIdEncoding = requestorIdEncoding;
- notification.textEncoding = textEncoding;
-
- // Process extras, assuming the format is
- // one of more lines of "key = value"
- Bundle bundle = new Bundle();
-
- if (extras == null) extras = "";
- Properties extraProp = new Properties();
-
- try {
- extraProp.load(new StringBufferInputStream(extras));
- }
- catch (IOException e)
- {
- Log.e(TAG, "reportNiNotification cannot parse extras data: " + extras);
- }
-
- for (Entry<Object, Object> ent : extraProp.entrySet())
- {
- bundle.putString((String) ent.getKey(), (String) ent.getValue());
- }
-
- notification.extras = bundle;
-
- mNIHandler.handleNiNotification(notification);
- }
-
- // this thread is used to receive events from the native code.
- // native_wait_for_event() will callback to us via reportLocation(), reportStatus(), etc.
- // this is necessary because native code cannot call Java on a thread that the JVM does
- // not know about.
- private final class GpsEventThread extends Thread {
-
- public GpsEventThread() {
- super("GpsEventThread");
- }
-
- public void run() {
- if (DEBUG) Log.d(TAG, "GpsEventThread starting");
- // Exit as soon as disable() is called instead of waiting for the GPS to stop.
- while (mEnabled) {
- // this will wait for an event from the GPS,
- // which will be reported via reportLocation or reportStatus
- native_wait_for_event();
- }
- if (DEBUG) Log.d(TAG, "GpsEventThread exiting");
- }
- }
-
- private final class ProviderHandler extends Handler {
- @Override
- public void handleMessage(Message msg)
- {
- switch (msg.what) {
- case ENABLE:
- if (msg.arg1 == 1) {
- handleEnable();
- } else {
- handleDisable();
- }
- break;
- case ENABLE_TRACKING:
- handleEnableLocationTracking(msg.arg1 == 1);
- break;
- case UPDATE_NETWORK_STATE:
- handleUpdateNetworkState(msg.arg1, (NetworkInfo)msg.obj);
- break;
- case INJECT_NTP_TIME:
- handleInjectNtpTime();
- break;
- case DOWNLOAD_XTRA_DATA:
- if (mSupportsXtra) {
- handleDownloadXtraData();
- }
- break;
- case UPDATE_LOCATION:
- handleUpdateLocation((Location)msg.obj);
- break;
- case ADD_LISTENER:
- handleAddListener(msg.arg1);
- break;
- case REMOVE_LISTENER:
- handleRemoveListener(msg.arg1);
- break;
- }
- }
- };
-
- private final class GpsLocationProviderThread extends Thread {
-
- public GpsLocationProviderThread() {
- super("GpsLocationProvider");
- }
-
- public void run() {
- Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
- initialize();
- Looper.prepare();
- mHandler = new ProviderHandler();
- // signal when we are initialized and ready to go
- mInitializedLatch.countDown();
- Looper.loop();
- }
- }
-
- // for GPS SV statistics
- private static final int MAX_SVS = 32;
- private static final int EPHEMERIS_MASK = 0;
- private static final int ALMANAC_MASK = 1;
- private static final int USED_FOR_FIX_MASK = 2;
-
- // preallocated arrays, to avoid memory allocation in reportStatus()
- private int mSvs[] = new int[MAX_SVS];
- private float mSnrs[] = new float[MAX_SVS];
- private float mSvElevations[] = new float[MAX_SVS];
- private float mSvAzimuths[] = new float[MAX_SVS];
- private int mSvMasks[] = new int[3];
- private int mSvCount;
- // preallocated to avoid memory allocation in reportNmea()
- private byte[] mNmeaBuffer = new byte[120];
-
- static { class_init_native(); }
- private static native void class_init_native();
- private static native boolean native_is_supported();
-
- private native boolean native_init();
- private native void native_disable();
- private native void native_cleanup();
- private native boolean native_start(int positionMode, boolean singleFix, int fixInterval);
- private native boolean native_stop();
- private native void native_set_fix_frequency(int fixFrequency);
- private native void native_delete_aiding_data(int flags);
- private native void native_wait_for_event();
- // returns number of SVs
- // mask[0] is ephemeris mask and mask[1] is almanac mask
- private native int native_read_sv_status(int[] svs, float[] snrs,
- float[] elevations, float[] azimuths, int[] masks);
- private native int native_read_nmea(int index, byte[] buffer, int bufferSize);
- private native void native_inject_location(double latitude, double longitude, float accuracy);
-
- // XTRA Support
- private native void native_inject_time(long time, long timeReference, int uncertainty);
- private native boolean native_supports_xtra();
- private native void native_inject_xtra_data(byte[] data, int length);
-
- // DEBUG Support
- private native String native_get_internal_state();
-
- // AGPS Support
- private native void native_agps_data_conn_open(String apn);
- private native void native_agps_data_conn_closed();
- private native void native_agps_data_conn_failed();
- private native void native_set_agps_server(int type, String hostname, int port);
-
- // Network-initiated (NI) Support
- private native void native_send_ni_response(int notificationId, int userResponse);
-}
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index fc98e06..d539833 100755
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -23,6 +23,7 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
+import android.location.LocationManager;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
@@ -83,7 +84,7 @@ public class GpsNetInitiatedHandler {
private final Context mContext;
// parent gps location provider
- private final GpsLocationProvider mGpsLocationProvider;
+ private final LocationManager mLocationManager;
// configuration of notificaiton behavior
private boolean mPlaySounds = false;
@@ -95,25 +96,25 @@ public class GpsNetInitiatedHandler {
public static class GpsNiNotification
{
- int notificationId;
- int niType;
- boolean needNotify;
- boolean needVerify;
- boolean privacyOverride;
- int timeout;
- int defaultResponse;
- String requestorId;
- String text;
- int requestorIdEncoding;
- int textEncoding;
- Bundle extras;
+ public int notificationId;
+ public int niType;
+ public boolean needNotify;
+ public boolean needVerify;
+ public boolean privacyOverride;
+ public int timeout;
+ public int defaultResponse;
+ public String requestorId;
+ public String text;
+ public int requestorIdEncoding;
+ public int textEncoding;
+ public Bundle extras;
};
public static class GpsNiResponse {
- /* User reponse, one of the values in GpsUserResponseType */
- int userResponse;
- /* Optional extra data to pass with the user response */
- Bundle extras;
+ /* User reponse, one of the values in GpsUserResponseType */
+ int userResponse;
+ /* Optional extra data to pass with the user response */
+ Bundle extras;
};
/**
@@ -124,63 +125,57 @@ public class GpsNetInitiatedHandler {
*/
private Notification mNiNotification;
- public GpsNetInitiatedHandler(Context context, GpsLocationProvider gpsLocationProvider) {
- mContext = context;
- mGpsLocationProvider = gpsLocationProvider;
+ public GpsNetInitiatedHandler(Context context) {
+ mContext = context;
+ mLocationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
}
// Handles NI events from HAL
public void handleNiNotification(GpsNiNotification notif)
{
- if (DEBUG) Log.d(TAG, "handleNiNotification" + " notificationId: " + notif.notificationId
- + " requestorId: " + notif.requestorId + " text: " + notif.text);
-
- // Notify and verify with immediate pop-up
- if (notif.needNotify && notif.needVerify && mPopupImmediately)
- {
- // Popup the dialog box now
- openNiDialog(notif);
- }
-
- // Notify only, or delayed pop-up (change mPopupImmediately to FALSE)
- if (notif.needNotify && !notif.needVerify ||
- notif.needNotify && notif.needVerify && !mPopupImmediately)
- {
- // Show the notification
-
- // if mPopupImmediately == FALSE and needVerify == TRUE, a dialog will be opened
- // when the user opens the notification message
-
- setNiNotification(notif);
- }
-
- // ACCEPT cases: 1. Notify, no verify; 2. no notify, no verify; 3. privacy override.
- if ( notif.needNotify && !notif.needVerify ||
- !notif.needNotify && !notif.needVerify ||
- notif.privacyOverride)
- {
- try {
- mGpsLocationProvider.getNetInitiatedListener().sendNiResponse(notif.notificationId, GPS_NI_RESPONSE_ACCEPT);
- }
- catch (RemoteException e)
- {
- Log.e(TAG, e.getMessage());
- }
- }
-
- //////////////////////////////////////////////////////////////////////////
- // A note about timeout
- // According to the protocol, in the need_notify and need_verify case,
- // a default response should be sent when time out.
- //
- // In some GPS hardware, the GPS driver (under HAL) can handle the timeout case
- // and this class GpsNetInitiatedHandler does not need to do anything.
- //
- // However, the UI should at least close the dialog when timeout. Further,
- // for more general handling, timeout response should be added to the Handler here.
- //
+ if (DEBUG) Log.d(TAG, "handleNiNotification" + " notificationId: " + notif.notificationId
+ + " requestorId: " + notif.requestorId + " text: " + notif.text);
+
+ // Notify and verify with immediate pop-up
+ if (notif.needNotify && notif.needVerify && mPopupImmediately)
+ {
+ // Popup the dialog box now
+ openNiDialog(notif);
+ }
+
+ // Notify only, or delayed pop-up (change mPopupImmediately to FALSE)
+ if (notif.needNotify && !notif.needVerify ||
+ notif.needNotify && notif.needVerify && !mPopupImmediately)
+ {
+ // Show the notification
+
+ // if mPopupImmediately == FALSE and needVerify == TRUE, a dialog will be opened
+ // when the user opens the notification message
+
+ setNiNotification(notif);
+ }
+
+ // ACCEPT cases: 1. Notify, no verify; 2. no notify, no verify; 3. privacy override.
+ if ( notif.needNotify && !notif.needVerify ||
+ !notif.needNotify && !notif.needVerify ||
+ notif.privacyOverride)
+ {
+ mLocationManager.sendNiResponse(notif.notificationId, GPS_NI_RESPONSE_ACCEPT);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // A note about timeout
+ // According to the protocol, in the need_notify and need_verify case,
+ // a default response should be sent when time out.
+ //
+ // In some GPS hardware, the GPS driver (under HAL) can handle the timeout case
+ // and this class GpsNetInitiatedHandler does not need to do anything.
+ //
+ // However, the UI should at least close the dialog when timeout. Further,
+ // for more general handling, timeout response should be added to the Handler here.
+ //
}
-
+
// Sets the NI notification.
private synchronized void setNiNotification(GpsNiNotification notif) {
NotificationManager notificationManager = (NotificationManager) mContext
@@ -188,271 +183,271 @@ public class GpsNetInitiatedHandler {
if (notificationManager == null) {
return;
}
-
- String title = getNotifTitle(notif, mContext);
- String message = getNotifMessage(notif, mContext);
-
+
+ String title = getNotifTitle(notif, mContext);
+ String message = getNotifMessage(notif, mContext);
+
if (DEBUG) Log.d(TAG, "setNiNotification, notifyId: " + notif.notificationId +
- ", title: " + title +
- ", message: " + message);
-
- // Construct Notification
- if (mNiNotification == null) {
- mNiNotification = new Notification();
- mNiNotification.icon = com.android.internal.R.drawable.stat_sys_gps_on; /* Change notification icon here */
- mNiNotification.when = 0;
+ ", title: " + title +
+ ", message: " + message);
+
+ // Construct Notification
+ if (mNiNotification == null) {
+ mNiNotification = new Notification();
+ mNiNotification.icon = com.android.internal.R.drawable.stat_sys_gps_on; /* Change notification icon here */
+ mNiNotification.when = 0;
}
-
+
if (mPlaySounds) {
- mNiNotification.defaults |= Notification.DEFAULT_SOUND;
+ mNiNotification.defaults |= Notification.DEFAULT_SOUND;
} else {
- mNiNotification.defaults &= ~Notification.DEFAULT_SOUND;
+ mNiNotification.defaults &= ~Notification.DEFAULT_SOUND;
}
-
+
mNiNotification.flags = Notification.FLAG_ONGOING_EVENT;
mNiNotification.tickerText = getNotifTicker(notif, mContext);
-
+
// if not to popup dialog immediately, pending intent will open the dialog
- Intent intent = !mPopupImmediately ? getDlgIntent(notif) : new Intent();
+ Intent intent = !mPopupImmediately ? getDlgIntent(notif) : new Intent();
PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
mNiNotification.setLatestEventInfo(mContext, title, message, pi);
-
+
if (visible) {
notificationManager.notify(notif.notificationId, mNiNotification);
} else {
notificationManager.cancel(notif.notificationId);
}
}
-
+
// Opens the notification dialog and waits for user input
- private void openNiDialog(GpsNiNotification notif)
+ private void openNiDialog(GpsNiNotification notif)
{
- Intent intent = getDlgIntent(notif);
-
- if (DEBUG) Log.d(TAG, "openNiDialog, notifyId: " + notif.notificationId +
- ", requestorId: " + notif.requestorId +
- ", text: " + notif.text);
+ Intent intent = getDlgIntent(notif);
- mContext.startActivity(intent);
+ if (DEBUG) Log.d(TAG, "openNiDialog, notifyId: " + notif.notificationId +
+ ", requestorId: " + notif.requestorId +
+ ", text: " + notif.text);
+
+ mContext.startActivity(intent);
}
-
+
// Construct the intent for bringing up the dialog activity, which shows the
// notification and takes user input
private Intent getDlgIntent(GpsNiNotification notif)
{
- Intent intent = new Intent();
- String title = getDialogTitle(notif, mContext);
- String message = getDialogMessage(notif, mContext);
-
- // directly bring up the NI activity
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- intent.setClass(mContext, com.android.internal.app.NetInitiatedActivity.class);
-
- // put data in the intent
- intent.putExtra(NI_INTENT_KEY_NOTIF_ID, notif.notificationId);
- intent.putExtra(NI_INTENT_KEY_TITLE, title);
- intent.putExtra(NI_INTENT_KEY_MESSAGE, message);
- intent.putExtra(NI_INTENT_KEY_TIMEOUT, notif.timeout);
- intent.putExtra(NI_INTENT_KEY_DEFAULT_RESPONSE, notif.defaultResponse);
-
- if (DEBUG) Log.d(TAG, "generateIntent, title: " + title + ", message: " + message +
- ", timeout: " + notif.timeout);
-
- return intent;
+ Intent intent = new Intent();
+ String title = getDialogTitle(notif, mContext);
+ String message = getDialogMessage(notif, mContext);
+
+ // directly bring up the NI activity
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setClass(mContext, com.android.internal.app.NetInitiatedActivity.class);
+
+ // put data in the intent
+ intent.putExtra(NI_INTENT_KEY_NOTIF_ID, notif.notificationId);
+ intent.putExtra(NI_INTENT_KEY_TITLE, title);
+ intent.putExtra(NI_INTENT_KEY_MESSAGE, message);
+ intent.putExtra(NI_INTENT_KEY_TIMEOUT, notif.timeout);
+ intent.putExtra(NI_INTENT_KEY_DEFAULT_RESPONSE, notif.defaultResponse);
+
+ if (DEBUG) Log.d(TAG, "generateIntent, title: " + title + ", message: " + message +
+ ", timeout: " + notif.timeout);
+
+ return intent;
}
-
+
// Converts a string (or Hex string) to a char array
static byte[] stringToByteArray(String original, boolean isHex)
{
- int length = isHex ? original.length() / 2 : original.length();
- byte[] output = new byte[length];
- int i;
-
- if (isHex)
- {
- for (i = 0; i < length; i++)
- {
- output[i] = (byte) Integer.parseInt(original.substring(i*2, i*2+2), 16);
- }
- }
- else {
- for (i = 0; i < length; i++)
- {
- output[i] = (byte) original.charAt(i);
- }
- }
-
- return output;
+ int length = isHex ? original.length() / 2 : original.length();
+ byte[] output = new byte[length];
+ int i;
+
+ if (isHex)
+ {
+ for (i = 0; i < length; i++)
+ {
+ output[i] = (byte) Integer.parseInt(original.substring(i*2, i*2+2), 16);
+ }
+ }
+ else {
+ for (i = 0; i < length; i++)
+ {
+ output[i] = (byte) original.charAt(i);
+ }
+ }
+
+ return output;
}
-
+
/**
* Unpacks an byte array containing 7-bit packed characters into a String.
- *
+ *
* @param input a 7-bit packed char array
* @return the unpacked String
*/
static String decodeGSMPackedString(byte[] input)
{
- final char CHAR_CR = 0x0D;
- int nStridx = 0;
- int nPckidx = 0;
- int num_bytes = input.length;
- int cPrev = 0;
- int cCurr = 0;
- byte nShift;
- byte nextChar;
- byte[] stringBuf = new byte[input.length * 2];
- String result = "";
-
- while(nPckidx < num_bytes)
- {
- nShift = (byte) (nStridx & 0x07);
- cCurr = input[nPckidx++];
- if (cCurr < 0) cCurr += 256;
-
- /* A 7-bit character can be split at the most between two bytes of packed
- ** data.
- */
- nextChar = (byte) (( (cCurr << nShift) | (cPrev >> (8-nShift)) ) & 0x7F);
- stringBuf[nStridx++] = nextChar;
-
- /* Special case where the whole of the next 7-bit character fits inside
- ** the current byte of packed data.
- */
- if(nShift == 6)
- {
- /* If the next 7-bit character is a CR (0x0D) and it is the last
- ** character, then it indicates a padding character. Drop it.
- */
- if (nPckidx == num_bytes || (cCurr >> 1) == CHAR_CR)
- {
- break;
- }
-
- nextChar = (byte) (cCurr >> 1);
- stringBuf[nStridx++] = nextChar;
- }
-
- cPrev = cCurr;
- }
-
- try{
- result = new String(stringBuf, 0, nStridx, "US-ASCII");
- }
- catch (UnsupportedEncodingException e)
- {
- Log.e(TAG, e.getMessage());
- }
-
- return result;
+ final char CHAR_CR = 0x0D;
+ int nStridx = 0;
+ int nPckidx = 0;
+ int num_bytes = input.length;
+ int cPrev = 0;
+ int cCurr = 0;
+ byte nShift;
+ byte nextChar;
+ byte[] stringBuf = new byte[input.length * 2];
+ String result = "";
+
+ while(nPckidx < num_bytes)
+ {
+ nShift = (byte) (nStridx & 0x07);
+ cCurr = input[nPckidx++];
+ if (cCurr < 0) cCurr += 256;
+
+ /* A 7-bit character can be split at the most between two bytes of packed
+ ** data.
+ */
+ nextChar = (byte) (( (cCurr << nShift) | (cPrev >> (8-nShift)) ) & 0x7F);
+ stringBuf[nStridx++] = nextChar;
+
+ /* Special case where the whole of the next 7-bit character fits inside
+ ** the current byte of packed data.
+ */
+ if(nShift == 6)
+ {
+ /* If the next 7-bit character is a CR (0x0D) and it is the last
+ ** character, then it indicates a padding character. Drop it.
+ */
+ if (nPckidx == num_bytes || (cCurr >> 1) == CHAR_CR)
+ {
+ break;
+ }
+
+ nextChar = (byte) (cCurr >> 1);
+ stringBuf[nStridx++] = nextChar;
+ }
+
+ cPrev = cCurr;
+ }
+
+ try {
+ result = new String(stringBuf, 0, nStridx, "US-ASCII");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ Log.e(TAG, e.getMessage());
+ }
+
+ return result;
}
-
+
static String decodeUTF8String(byte[] input)
{
- String decoded = "";
- try {
- decoded = new String(input, "UTF-8");
- }
- catch (UnsupportedEncodingException e)
- {
- Log.e(TAG, e.getMessage());
- }
- return decoded;
+ String decoded = "";
+ try {
+ decoded = new String(input, "UTF-8");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ Log.e(TAG, e.getMessage());
+ }
+ return decoded;
}
-
+
static String decodeUCS2String(byte[] input)
{
- String decoded = "";
- try {
- decoded = new String(input, "UTF-16");
- }
- catch (UnsupportedEncodingException e)
- {
- Log.e(TAG, e.getMessage());
- }
- return decoded;
+ String decoded = "";
+ try {
+ decoded = new String(input, "UTF-16");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ Log.e(TAG, e.getMessage());
+ }
+ return decoded;
}
-
+
/** Decode NI string
- *
+ *
* @param original The text string to be decoded
* @param isHex Specifies whether the content of the string has been encoded as a Hex string. Encoding
- * a string as Hex can allow zeros inside the coded text.
+ * a string as Hex can allow zeros inside the coded text.
* @param coding Specifies the coding scheme of the string, such as GSM, UTF8, UCS2, etc. This coding scheme
- * needs to match those used passed to HAL from the native GPS driver. Decoding is done according
+ * needs to match those used passed to HAL from the native GPS driver. Decoding is done according
* to the <code> coding </code>, after a Hex string is decoded. Generally, if the
- * notification strings don't need further decoding, <code> coding </code> encoding can be
+ * notification strings don't need further decoding, <code> coding </code> encoding can be
* set to -1, and <code> isHex </code> can be false.
* @return the decoded string
*/
static private String decodeString(String original, boolean isHex, int coding)
{
- String decoded = original;
- byte[] input = stringToByteArray(original, isHex);
-
- switch (coding) {
- case GPS_ENC_NONE:
- decoded = original;
- break;
-
- case GPS_ENC_SUPL_GSM_DEFAULT:
- decoded = decodeGSMPackedString(input);
- break;
-
- case GPS_ENC_SUPL_UTF8:
- decoded = decodeUTF8String(input);
- break;
-
- case GPS_ENC_SUPL_UCS2:
- decoded = decodeUCS2String(input);
- break;
-
- case GPS_ENC_UNKNOWN:
- decoded = original;
- break;
-
- default:
- Log.e(TAG, "Unknown encoding " + coding + " for NI text " + original);
- break;
- }
- return decoded;
+ String decoded = original;
+ byte[] input = stringToByteArray(original, isHex);
+
+ switch (coding) {
+ case GPS_ENC_NONE:
+ decoded = original;
+ break;
+
+ case GPS_ENC_SUPL_GSM_DEFAULT:
+ decoded = decodeGSMPackedString(input);
+ break;
+
+ case GPS_ENC_SUPL_UTF8:
+ decoded = decodeUTF8String(input);
+ break;
+
+ case GPS_ENC_SUPL_UCS2:
+ decoded = decodeUCS2String(input);
+ break;
+
+ case GPS_ENC_UNKNOWN:
+ decoded = original;
+ break;
+
+ default:
+ Log.e(TAG, "Unknown encoding " + coding + " for NI text " + original);
+ break;
+ }
+ return decoded;
}
-
+
// change this to configure notification display
static private String getNotifTicker(GpsNiNotification notif, Context context)
{
- String ticker = String.format(context.getString(R.string.gpsNotifTicker),
- decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding),
- decodeString(notif.text, mIsHexInput, notif.textEncoding));
- return ticker;
+ String ticker = String.format(context.getString(R.string.gpsNotifTicker),
+ decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding),
+ decodeString(notif.text, mIsHexInput, notif.textEncoding));
+ return ticker;
}
-
+
// change this to configure notification display
static private String getNotifTitle(GpsNiNotification notif, Context context)
{
- String title = String.format(context.getString(R.string.gpsNotifTitle));
- return title;
+ String title = String.format(context.getString(R.string.gpsNotifTitle));
+ return title;
}
-
+
// change this to configure notification display
static private String getNotifMessage(GpsNiNotification notif, Context context)
{
- String message = String.format(context.getString(R.string.gpsNotifMessage),
- decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding),
- decodeString(notif.text, mIsHexInput, notif.textEncoding));
- return message;
+ String message = String.format(context.getString(R.string.gpsNotifMessage),
+ decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding),
+ decodeString(notif.text, mIsHexInput, notif.textEncoding));
+ return message;
}
-
+
// change this to configure dialog display (for verification)
static public String getDialogTitle(GpsNiNotification notif, Context context)
{
- return getNotifTitle(notif, context);
+ return getNotifTitle(notif, context);
}
-
+
// change this to configure dialog display (for verification)
static private String getDialogMessage(GpsNiNotification notif, Context context)
{
- return getNotifMessage(notif, context);
+ return getNotifMessage(notif, context);
}
-
+
}
diff --git a/location/java/com/android/internal/location/GpsXtraDownloader.java b/location/java/com/android/internal/location/GpsXtraDownloader.java
deleted file mode 100644
index 978bda2..0000000
--- a/location/java/com/android/internal/location/GpsXtraDownloader.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2008 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 com.android.internal.location;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.StatusLine;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.conn.params.ConnRouteParams;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.util.Properties;
-import java.util.Random;
-
-import android.content.Context;
-import android.net.Proxy;
-import android.net.http.AndroidHttpClient;
-import android.util.Config;
-import android.util.Log;
-
-
-
-/**
- * A class for downloading GPS XTRA data.
- *
- * {@hide}
- */
-public class GpsXtraDownloader {
-
- private static final String TAG = "GpsXtraDownloader";
-
- private Context mContext;
- private String[] mXtraServers;
- // to load balance our server requests
- private int mNextServerIndex;
-
- GpsXtraDownloader(Context context, Properties properties) {
- mContext = context;
-
- // read XTRA servers from the Properties object
- int count = 0;
- String server1 = properties.getProperty("XTRA_SERVER_1");
- String server2 = properties.getProperty("XTRA_SERVER_2");
- String server3 = properties.getProperty("XTRA_SERVER_3");
- if (server1 != null) count++;
- if (server2 != null) count++;
- if (server3 != null) count++;
-
- if (count == 0) {
- Log.e(TAG, "No XTRA servers were specified in the GPS configuration");
- return;
- } else {
- mXtraServers = new String[count];
- count = 0;
- if (server1 != null) mXtraServers[count++] = server1;
- if (server2 != null) mXtraServers[count++] = server2;
- if (server3 != null) mXtraServers[count++] = server3;
-
- // randomize first server
- Random random = new Random();
- mNextServerIndex = random.nextInt(count);
- }
- }
-
- byte[] downloadXtraData() {
- String proxyHost = Proxy.getHost(mContext);
- int proxyPort = Proxy.getPort(mContext);
- boolean useProxy = (proxyHost != null && proxyPort != -1);
- byte[] result = null;
- int startIndex = mNextServerIndex;
-
- if (mXtraServers == null) {
- return null;
- }
-
- // load balance our requests among the available servers
- while (result == null) {
- result = doDownload(mXtraServers[mNextServerIndex], useProxy, proxyHost, proxyPort);
-
- // increment mNextServerIndex and wrap around if necessary
- mNextServerIndex++;
- if (mNextServerIndex == mXtraServers.length) {
- mNextServerIndex = 0;
- }
- // break if we have tried all the servers
- if (mNextServerIndex == startIndex) break;
- }
-
- return result;
- }
-
- protected static byte[] doDownload(String url, boolean isProxySet,
- String proxyHost, int proxyPort) {
- if (Config.LOGD) Log.d(TAG, "Downloading XTRA data from " + url);
-
- AndroidHttpClient client = null;
- try {
- client = AndroidHttpClient.newInstance("Android");
- HttpUriRequest req = new HttpGet(url);
-
- if (isProxySet) {
- HttpHost proxy = new HttpHost(proxyHost, proxyPort);
- ConnRouteParams.setDefaultProxy(req.getParams(), proxy);
- }
-
- req.addHeader(
- "Accept",
- "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic");
-
- req.addHeader(
- "x-wap-profile",
- "http://www.openmobilealliance.org/tech/profiles/UAPROF/ccppschema-20021212#");
-
- HttpResponse response = client.execute(req);
- StatusLine status = response.getStatusLine();
- if (status.getStatusCode() != 200) { // HTTP 200 is success.
- if (Config.LOGD) Log.d(TAG, "HTTP error: " + status.getReasonPhrase());
- return null;
- }
-
- HttpEntity entity = response.getEntity();
- byte[] body = null;
- if (entity != null) {
- try {
- if (entity.getContentLength() > 0) {
- body = new byte[(int) entity.getContentLength()];
- DataInputStream dis = new DataInputStream(entity.getContent());
- try {
- dis.readFully(body);
- } finally {
- try {
- dis.close();
- } catch (IOException e) {
- Log.e(TAG, "Unexpected IOException.", e);
- }
- }
- }
- } finally {
- if (entity != null) {
- entity.consumeContent();
- }
- }
- }
- return body;
- } catch (Exception e) {
- if (Config.LOGD) Log.d(TAG, "error " + e);
- } finally {
- if (client != null) {
- client.close();
- }
- }
- return null;
- }
-
-}
diff --git a/location/java/com/android/internal/location/LocationProviderProxy.java b/location/java/com/android/internal/location/LocationProviderProxy.java
deleted file mode 100644
index 31ec09a..0000000
--- a/location/java/com/android/internal/location/LocationProviderProxy.java
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * 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 com.android.internal.location;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.location.ILocationProvider;
-import android.location.Location;
-import android.location.LocationProviderInterface;
-import android.net.NetworkInfo;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.util.Log;
-
-/**
- * A class for proxying location providers implemented as services.
- *
- * {@hide}
- */
-public class LocationProviderProxy implements LocationProviderInterface {
-
- private static final String TAG = "LocationProviderProxy";
-
- private final Context mContext;
- private final String mName;
- private ILocationProvider mProvider;
- private Handler mHandler;
- private final Connection mServiceConnection = new Connection();
-
- // cached values set by the location manager
- private boolean mLocationTracking = false;
- private boolean mEnabled = false;
- private long mMinTime = -1;
- private int mNetworkState;
- private NetworkInfo mNetworkInfo;
-
- // for caching requiresNetwork, requiresSatellite, etc.
- private DummyLocationProvider mCachedAttributes;
-
- // constructor for proxying location providers implemented in a separate service
- public LocationProviderProxy(Context context, String name, String serviceName,
- Handler handler) {
- mContext = context;
- mName = name;
- mHandler = handler;
- mContext.bindService(new Intent(serviceName), mServiceConnection, Context.BIND_AUTO_CREATE);
- }
-
- private class Connection implements ServiceConnection {
- public void onServiceConnected(ComponentName className, IBinder service) {
- Log.d(TAG, "LocationProviderProxy.onServiceConnected " + className);
- synchronized (this) {
- mProvider = ILocationProvider.Stub.asInterface(service);
- if (mProvider != null) {
- mHandler.post(mServiceConnectedTask);
- }
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- Log.d(TAG, "LocationProviderProxy.onServiceDisconnected " + className);
- synchronized (this) {
- mProvider = null;
- }
- }
- }
-
- private Runnable mServiceConnectedTask = new Runnable() {
- public void run() {
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- if (provider == null) {
- return;
- }
- }
-
- if (mCachedAttributes == null) {
- try {
- mCachedAttributes = new DummyLocationProvider(mName);
- mCachedAttributes.setRequiresNetwork(provider.requiresNetwork());
- mCachedAttributes.setRequiresSatellite(provider.requiresSatellite());
- mCachedAttributes.setRequiresCell(provider.requiresCell());
- mCachedAttributes.setHasMonetaryCost(provider.hasMonetaryCost());
- mCachedAttributes.setSupportsAltitude(provider.supportsAltitude());
- mCachedAttributes.setSupportsSpeed(provider.supportsSpeed());
- mCachedAttributes.setSupportsBearing(provider.supportsBearing());
- mCachedAttributes.setPowerRequirement(provider.getPowerRequirement());
- mCachedAttributes.setAccuracy(provider.getAccuracy());
- } catch (RemoteException e) {
- mCachedAttributes = null;
- }
- }
-
- // resend previous values from the location manager if the service has restarted
- try {
- if (mEnabled) {
- provider.enable();
- }
- if (mLocationTracking) {
- provider.enableLocationTracking(true);
- }
- if (mMinTime >= 0) {
- provider.setMinTime(mMinTime);
- }
- if (mNetworkInfo != null) {
- provider.updateNetworkState(mNetworkState, mNetworkInfo);
- }
- } catch (RemoteException e) {
- }
- }
- };
-
- public String getName() {
- return mName;
- }
-
- public boolean requiresNetwork() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.requiresNetwork();
- } else {
- return false;
- }
- }
-
- public boolean requiresSatellite() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.requiresSatellite();
- } else {
- return false;
- }
- }
-
- public boolean requiresCell() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.requiresCell();
- } else {
- return false;
- }
- }
-
- public boolean hasMonetaryCost() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.hasMonetaryCost();
- } else {
- return false;
- }
- }
-
- public boolean supportsAltitude() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.supportsAltitude();
- } else {
- return false;
- }
- }
-
- public boolean supportsSpeed() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.supportsSpeed();
- } else {
- return false;
- }
- }
-
- public boolean supportsBearing() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.supportsBearing();
- } else {
- return false;
- }
- }
-
- public int getPowerRequirement() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.getPowerRequirement();
- } else {
- return -1;
- }
- }
-
- public int getAccuracy() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.getAccuracy();
- } else {
- return -1;
- }
- }
-
- public void enable() {
- mEnabled = true;
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.enable();
- } catch (RemoteException e) {
- }
- }
- }
-
- public void disable() {
- mEnabled = false;
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.disable();
- } catch (RemoteException e) {
- }
- }
- }
-
- public boolean isEnabled() {
- return mEnabled;
- }
-
- public int getStatus(Bundle extras) {
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- return provider.getStatus(extras);
- } catch (RemoteException e) {
- }
- }
- return 0;
- }
-
- public long getStatusUpdateTime() {
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- return provider.getStatusUpdateTime();
- } catch (RemoteException e) {
- }
- }
- return 0;
- }
-
- public String getInternalState() {
- try {
- return mProvider.getInternalState();
- } catch (RemoteException e) {
- Log.e(TAG, "getInternalState failed", e);
- return null;
- }
- }
-
- public boolean isLocationTracking() {
- return mLocationTracking;
- }
-
- public void enableLocationTracking(boolean enable) {
- mLocationTracking = enable;
- if (!enable) {
- mMinTime = -1;
- }
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.enableLocationTracking(enable);
- } catch (RemoteException e) {
- }
- }
- }
-
- public long getMinTime() {
- return mMinTime;
- }
-
- public void setMinTime(long minTime) {
- mMinTime = minTime;
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.setMinTime(minTime);
- } catch (RemoteException e) {
- }
- }
- }
-
- public void updateNetworkState(int state, NetworkInfo info) {
- mNetworkState = state;
- mNetworkInfo = info;
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.updateNetworkState(state, info);
- } catch (RemoteException e) {
- }
- }
- }
-
- public void updateLocation(Location location) {
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.updateLocation(location);
- } catch (RemoteException e) {
- }
- }
- }
-
- public boolean sendExtraCommand(String command, Bundle extras) {
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.sendExtraCommand(command, extras);
- } catch (RemoteException e) {
- }
- }
- return false;
- }
-
- public void addListener(int uid) {
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.addListener(uid);
- } catch (RemoteException e) {
- }
- }
- }
-
- public void removeListener(int uid) {
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.removeListener(uid);
- } catch (RemoteException e) {
- }
- }
- }
-}
diff --git a/location/java/com/android/internal/location/MockProvider.java b/location/java/com/android/internal/location/MockProvider.java
deleted file mode 100644
index d912740..0000000
--- a/location/java/com/android/internal/location/MockProvider.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * 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 com.android.internal.location;
-
-import android.location.ILocationManager;
-import android.location.Location;
-import android.location.LocationProvider;
-import android.location.LocationProviderInterface;
-import android.net.NetworkInfo;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-import android.util.PrintWriterPrinter;
-
-import java.io.PrintWriter;
-
-/**
- * A mock location provider used by LocationManagerService to implement test providers.
- *
- * {@hide}
- */
-public class MockProvider implements LocationProviderInterface {
- private final String mName;
- private final ILocationManager mLocationManager;
- private final boolean mRequiresNetwork;
- private final boolean mRequiresSatellite;
- private final boolean mRequiresCell;
- private final boolean mHasMonetaryCost;
- private final boolean mSupportsAltitude;
- private final boolean mSupportsSpeed;
- private final boolean mSupportsBearing;
- private final int mPowerRequirement;
- private final int mAccuracy;
- private final Location mLocation;
- private int mStatus;
- private long mStatusUpdateTime;
- private final Bundle mExtras = new Bundle();
- private boolean mHasLocation;
- private boolean mHasStatus;
- private boolean mEnabled;
-
- private static final String TAG = "MockProvider";
-
- public MockProvider(String name, ILocationManager locationManager,
- boolean requiresNetwork, boolean requiresSatellite,
- boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude,
- boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
- mName = name;
- mLocationManager = locationManager;
- mRequiresNetwork = requiresNetwork;
- mRequiresSatellite = requiresSatellite;
- mRequiresCell = requiresCell;
- mHasMonetaryCost = hasMonetaryCost;
- mSupportsAltitude = supportsAltitude;
- mSupportsBearing = supportsBearing;
- mSupportsSpeed = supportsSpeed;
- mPowerRequirement = powerRequirement;
- mAccuracy = accuracy;
- mLocation = new Location(name);
- }
-
- public String getName() {
- return mName;
- }
-
- public void disable() {
- mEnabled = false;
- }
-
- public void enable() {
- mEnabled = true;
- }
-
- public boolean isEnabled() {
- return mEnabled;
- }
-
- public int getStatus(Bundle extras) {
- if (mHasStatus) {
- extras.clear();
- extras.putAll(mExtras);
- return mStatus;
- } else {
- return LocationProvider.AVAILABLE;
- }
- }
-
- public long getStatusUpdateTime() {
- return mStatusUpdateTime;
- }
-
- public int getAccuracy() {
- return mAccuracy;
- }
-
- public int getPowerRequirement() {
- return mPowerRequirement;
- }
-
- public boolean hasMonetaryCost() {
- return mHasMonetaryCost;
- }
-
- public boolean requiresCell() {
- return mRequiresCell;
- }
-
- public boolean requiresNetwork() {
- return mRequiresNetwork;
- }
-
- public boolean requiresSatellite() {
- return mRequiresSatellite;
- }
-
- public boolean supportsAltitude() {
- return mSupportsAltitude;
- }
-
- public boolean supportsBearing() {
- return mSupportsBearing;
- }
-
- public boolean supportsSpeed() {
- return mSupportsSpeed;
- }
-
- public void setLocation(Location l) {
- mLocation.set(l);
- mHasLocation = true;
- try {
- mLocationManager.reportLocation(mLocation, false);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException calling reportLocation");
- }
- }
-
- public void clearLocation() {
- mHasLocation = false;
- }
-
- public void setStatus(int status, Bundle extras, long updateTime) {
- mStatus = status;
- mStatusUpdateTime = updateTime;
- mExtras.clear();
- if (extras != null) {
- mExtras.putAll(extras);
- }
- mHasStatus = true;
- }
-
- public void clearStatus() {
- mHasStatus = false;
- mStatusUpdateTime = 0;
- }
-
- public String getInternalState() {
- return null;
- }
-
- public void enableLocationTracking(boolean enable) {
- }
-
- public void setMinTime(long minTime) {
- }
-
- public void updateNetworkState(int state, NetworkInfo info) {
- }
-
- public void updateLocation(Location location) {
- }
-
- public boolean sendExtraCommand(String command, Bundle extras) {
- return false;
- }
-
- public void addListener(int uid) {
- }
-
- public void removeListener(int uid) {
- }
-
- public void dump(PrintWriter pw, String prefix) {
- pw.println(prefix + mName);
- pw.println(prefix + "mHasLocation=" + mHasLocation);
- pw.println(prefix + "mLocation:");
- mLocation.dump(new PrintWriterPrinter(pw), prefix + " ");
- pw.println(prefix + "mHasStatus=" + mHasStatus);
- pw.println(prefix + "mStatus=" + mStatus);
- pw.println(prefix + "mStatusUpdateTime=" + mStatusUpdateTime);
- pw.println(prefix + "mExtras=" + mExtras);
- }
-}
diff --git a/location/java/com/android/internal/location/PassiveProvider.java b/location/java/com/android/internal/location/PassiveProvider.java
deleted file mode 100644
index ab90937..0000000
--- a/location/java/com/android/internal/location/PassiveProvider.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2010 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 com.android.internal.location;
-
-import android.location.ILocationManager;
-import android.location.Location;
-import android.location.LocationManager;
-import android.location.LocationProvider;
-import android.location.LocationProviderInterface;
-import android.net.NetworkInfo;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * A passive location provider reports locations received from other providers
- * for clients that want to listen passively without actually triggering
- * location updates.
- *
- * {@hide}
- */
-public class PassiveProvider implements LocationProviderInterface {
-
- private static final String TAG = "PassiveProvider";
-
- private final ILocationManager mLocationManager;
- private boolean mTracking;
-
- public PassiveProvider(ILocationManager locationManager) {
- mLocationManager = locationManager;
- }
-
- public String getName() {
- return LocationManager.PASSIVE_PROVIDER;
- }
-
- public boolean requiresNetwork() {
- return false;
- }
-
- public boolean requiresSatellite() {
- return false;
- }
-
- public boolean requiresCell() {
- return false;
- }
-
- public boolean hasMonetaryCost() {
- return false;
- }
-
- public boolean supportsAltitude() {
- return false;
- }
-
- public boolean supportsSpeed() {
- return false;
- }
-
- public boolean supportsBearing() {
- return false;
- }
-
- public int getPowerRequirement() {
- return -1;
- }
-
- public int getAccuracy() {
- return -1;
- }
-
- public boolean isEnabled() {
- return true;
- }
-
- public void enable() {
- }
-
- public void disable() {
- }
-
- public int getStatus(Bundle extras) {
- if (mTracking) {
- return LocationProvider.AVAILABLE;
- } else {
- return LocationProvider.TEMPORARILY_UNAVAILABLE;
- }
- }
-
- public long getStatusUpdateTime() {
- return -1;
- }
-
- public String getInternalState() {
- return null;
- }
-
- public void enableLocationTracking(boolean enable) {
- mTracking = enable;
- }
-
- public void setMinTime(long minTime) {
- }
-
- public void updateNetworkState(int state, NetworkInfo info) {
- }
-
- public void updateLocation(Location location) {
- if (mTracking) {
- try {
- // pass the location back to the location manager
- mLocationManager.reportLocation(location, true);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException calling reportLocation");
- }
- }
- }
-
- public boolean sendExtraCommand(String command, Bundle extras) {
- return false;
- }
-
- public void addListener(int uid) {
- }
-
- public void removeListener(int uid) {
- }
-}
diff --git a/location/lib/Android.mk b/location/lib/Android.mk
new file mode 100644
index 0000000..a06478a
--- /dev/null
+++ b/location/lib/Android.mk
@@ -0,0 +1,45 @@
+#
+# Copyright (C) 2010 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+# the library
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= com.android.location.provider
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ $(call all-subdir-java-files)
+
+include $(BUILD_JAVA_LIBRARY)
+
+
+# ==== com.google.location.xml lib def ========================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := com.android.location.provider.xml
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_CLASS := ETC
+
+# This will install the file in /system/etc/permissions
+#
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
+
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+include $(BUILD_PREBUILT)
diff --git a/location/lib/com.android.location.provider.xml b/location/lib/com.android.location.provider.xml
new file mode 100644
index 0000000..000e68f
--- /dev/null
+++ b/location/lib/com.android.location.provider.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<permissions>
+ <library name="com.android.location.provider"
+ file="/system/framework/com.android.location.provider.jar" />
+</permissions>
diff --git a/location/java/android/location/provider/GeocodeProvider.java b/location/lib/java/com/android/location/provider/GeocodeProvider.java
index 86376a7..666bb02 100644
--- a/location/java/android/location/provider/GeocodeProvider.java
+++ b/location/lib/java/com/android/location/provider/GeocodeProvider.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.location.provider;
+package com.android.location.provider;
import android.os.IBinder;
@@ -53,7 +53,7 @@ public abstract class GeocodeProvider {
/**
* This method is overridden to implement the
- * {@link Geocoder#getFromLocation(double, double, int)} method.
+ * {@link android.location.Geocoder#getFromLocation(double, double, int)} method.
* Classes implementing this method should not hold a reference to the params parameter.
*/
public abstract String onGetFromLocation(double latitude, double longitude, int maxResults,
@@ -61,7 +61,7 @@ public abstract class GeocodeProvider {
/**
* This method is overridden to implement the
- * {@link Geocoder#getFromLocationName(String, int, double, double, double, double)} method.
+ * {@link android.location.Geocoder#getFromLocationName(String, int, double, double, double, double)} method.
* Classes implementing this method should not hold a reference to the params parameter.
*/
public abstract String onGetFromLocationName(String locationName,
@@ -80,4 +80,3 @@ public abstract class GeocodeProvider {
return mProvider;
}
}
-
diff --git a/location/java/android/location/provider/LocationProvider.java b/location/lib/java/com/android/location/provider/LocationProvider.java
index 56cfb33..3714f40 100644
--- a/location/java/android/location/provider/LocationProvider.java
+++ b/location/lib/java/com/android/location/provider/LocationProvider.java
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-package android.location.provider;
+package com.android.location.provider;
import android.content.Context;
import android.net.NetworkInfo;
+import android.location.Criteria;
import android.location.ILocationManager;
import android.location.ILocationProvider;
import android.location.Location;
@@ -25,6 +26,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.WorkSource;
import android.util.Log;
/**
@@ -75,6 +77,10 @@ public abstract class LocationProvider {
return LocationProvider.this.onGetPowerRequirement();
}
+ public boolean meetsCriteria(Criteria criteria) {
+ return LocationProvider.this.onMeetsCriteria(criteria);
+ }
+
public int getAccuracy() {
return LocationProvider.this.onGetAccuracy();
}
@@ -103,8 +109,8 @@ public abstract class LocationProvider {
LocationProvider.this.onEnableLocationTracking(enable);
}
- public void setMinTime(long minTime) {
- LocationProvider.this.onSetMinTime(minTime);
+ public void setMinTime(long minTime, WorkSource ws) {
+ LocationProvider.this.onSetMinTime(minTime, ws);
}
public void updateNetworkState(int state, NetworkInfo info) {
@@ -120,11 +126,11 @@ public abstract class LocationProvider {
}
public void addListener(int uid) {
- LocationProvider.this.onAddListener(uid);
+ LocationProvider.this.onAddListener(uid, new WorkSource(uid));
}
public void removeListener(int uid) {
- LocationProvider.this.onRemoveListener(uid);
+ LocationProvider.this.onRemoveListener(uid, new WorkSource(uid));
}
};
@@ -226,6 +232,12 @@ public abstract class LocationProvider {
public abstract int onGetPowerRequirement();
/**
+ * Returns true if this provider meets the given criteria,
+ * false otherwise.
+ */
+ public abstract boolean onMeetsCriteria(Criteria criteria);
+
+ /**
* Returns a constant describing horizontal accuracy of this provider.
* If the provider returns finer grain or exact location,
* {@link Criteria#ACCURACY_FINE} is returned, otherwise if the
@@ -246,11 +258,11 @@ public abstract class LocationProvider {
/**
* Returns a information on the status of this provider.
- * {@link #OUT_OF_SERVICE} is returned if the provider is
+ * {@link android.location.LocationProvider#OUT_OF_SERVICE} is returned if the provider is
* out of service, and this is not expected to change in the near
- * future; {@link #TEMPORARILY_UNAVAILABLE} is returned if
+ * future; {@link android.location.LocationProvider#TEMPORARILY_UNAVAILABLE} is returned if
* the provider is temporarily unavailable but is expected to be
- * available shortly; and {@link #AVAILABLE} is returned
+ * available shortly; and {@link android.location.LocationProvider#AVAILABLE} is returned
* if the provider is currently available.
*
* <p> If extras is non-null, additional status information may be
@@ -294,14 +306,15 @@ public abstract class LocationProvider {
* the frequency of updates to match the requested frequency.
*
* @param minTime the smallest minTime value over all listeners for this provider.
+ * @param ws the source this work is coming from.
*/
- public abstract void onSetMinTime(long minTime);
+ public abstract void onSetMinTime(long minTime, WorkSource ws);
/**
* Updates the network state for the given provider. This function must
- * be overwritten if {@link #requiresNetwork} returns true. The state is
- * {@link #TEMPORARILY_UNAVAILABLE} (disconnected), OR {@link #AVAILABLE}
- * (connected or connecting).
+ * be overwritten if {@link android.location.LocationProvider#requiresNetwork} returns true.
+ * The state is {@link android.location.LocationProvider#TEMPORARILY_UNAVAILABLE} (disconnected)
+ * OR {@link android.location.LocationProvider#AVAILABLE} (connected or connecting).
*
* @param state data state
*/
@@ -331,14 +344,15 @@ public abstract class LocationProvider {
* Notifies the location provider when a new client is listening for locations.
*
* @param uid user ID of the new client.
+ * @param ws a WorkSource representation of the client.
*/
- public abstract void onAddListener(int uid);
+ public abstract void onAddListener(int uid, WorkSource ws);
/**
* Notifies the location provider when a client is no longer listening for locations.
*
* @param uid user ID of the client no longer listening.
+ * @param ws a WorkSource representation of the client.
*/
- public abstract void onRemoveListener(int uid);
+ public abstract void onRemoveListener(int uid, WorkSource ws);
}
-