diff --git a/Android.mk b/Android.mk index c947b0e5b08eb..5983b308bddb0 100644 --- a/Android.mk +++ b/Android.mk @@ -331,10 +331,10 @@ LOCAL_SRC_FILES += \ location/java/android/location/IFusedProvider.aidl \ location/java/android/location/IGeocodeProvider.aidl \ location/java/android/location/IGeofenceProvider.aidl \ + location/java/android/location/IGnssStatusListener.aidl \ + location/java/android/location/IGnssStatusProvider.aidl \ location/java/android/location/IGpsMeasurementsListener.aidl \ location/java/android/location/IGpsNavigationMessageListener.aidl \ - location/java/android/location/IGpsStatusListener.aidl \ - location/java/android/location/IGpsStatusProvider.aidl \ location/java/android/location/ILocationListener.aidl \ location/java/android/location/ILocationManager.aidl \ location/java/android/location/IFusedGeofenceHardware.aidl \ diff --git a/api/current.txt b/api/current.txt index a311eeb4d78f7..0ca7560da2c77 100644 --- a/api/current.txt +++ b/api/current.txt @@ -19036,6 +19036,288 @@ package android.location { method public static boolean isPresent(); } + public abstract interface GnssNmeaListener { + method public abstract void onNmeaReceived(long, java.lang.String); + } + + public final class GnssStatus { + method public float getAzimuth(int); + method public int getConstellationType(int); + method public float getElevation(int); + method public int getNumSatellites(); + method public int getPrn(int); + method public float getSnr(int); + method public boolean hasAlmanac(int); + method public boolean hasEphemeris(int); + method public boolean usedInFix(int); + field public static final int CONSTELLATION_BEIDOU = 5; // 0x5 + field public static final int CONSTELLATION_GALILEO = 6; // 0x6 + field public static final int CONSTELLATION_GLONASS = 3; // 0x3 + field public static final int CONSTELLATION_GPS = 1; // 0x1 + field public static final int CONSTELLATION_QZSS = 4; // 0x4 + field public static final int CONSTELLATION_SBAS = 2; // 0x2 + field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0 + } + + public abstract class GnssStatusCallback { + ctor public GnssStatusCallback(); + method public void onFirstFix(int); + method public void onSatelliteStatusChanged(android.location.GnssStatus); + method public void onStarted(); + method public void onStopped(); + } + + public final class GpsClock implements android.os.Parcelable { + method public int describeContents(); + method public double getBiasInNs(); + method public double getBiasUncertaintyInNs(); + method public double getDriftInNsPerSec(); + method public double getDriftUncertaintyInNsPerSec(); + method public long getFullBiasInNs(); + method public short getLeapSecond(); + method public long getTimeInNs(); + method public long getTimeOfLastHwClockDiscontinuityInNs(); + method public double getTimeUncertaintyInNs(); + method public byte getType(); + method public boolean hasBiasInNs(); + method public boolean hasBiasUncertaintyInNs(); + method public boolean hasDriftInNsPerSec(); + method public boolean hasDriftUncertaintyInNsPerSec(); + method public boolean hasFullBiasInNs(); + method public boolean hasLeapSecond(); + method public boolean hasTimeUncertaintyInNs(); + method public void reset(); + method public void resetBiasInNs(); + method public void resetBiasUncertaintyInNs(); + method public void resetDriftInNsPerSec(); + method public void resetDriftUncertaintyInNsPerSec(); + method public void resetFullBiasInNs(); + method public void resetLeapSecond(); + method public void resetTimeUncertaintyInNs(); + method public void set(android.location.GpsClock); + method public void setBiasInNs(double); + method public void setBiasUncertaintyInNs(double); + method public void setDriftInNsPerSec(double); + method public void setDriftUncertaintyInNsPerSec(double); + method public void setFullBiasInNs(long); + method public void setLeapSecond(short); + method public void setTimeInNs(long); + method public void setTimeOfLastHwClockDiscontinuityInNs(long); + method public void setTimeUncertaintyInNs(double); + method public void setType(byte); + method public void writeToParcel(android.os.Parcel, int); + field public static final byte CLOCK_TYPE_GPS_TIME = 2; // 0x2 + field public static final byte CLOCK_TYPE_LOCAL_HW_TIME = 1; // 0x1 + field public static final byte CLOCK_TYPE_UNKNOWN = 0; // 0x0 + field public static final android.os.Parcelable.Creator CREATOR; + } + + public static abstract class GpsClock.GpsClockType implements java.lang.annotation.Annotation { + } + + public final class GpsMeasurement implements android.os.Parcelable { + method public int describeContents(); + method public double getAccumulatedDeltaRangeInMeters(); + method public short getAccumulatedDeltaRangeState(); + method public double getAccumulatedDeltaRangeUncertaintyInMeters(); + method public double getAzimuthInDeg(); + method public double getAzimuthUncertaintyInDeg(); + method public int getBitNumber(); + method public long getCarrierCycles(); + method public float getCarrierFrequencyInHz(); + method public double getCarrierPhase(); + method public double getCarrierPhaseUncertainty(); + method public double getCn0InDbHz(); + method public double getCodePhaseInChips(); + method public double getCodePhaseUncertaintyInChips(); + method public double getDopplerShiftInHz(); + method public double getDopplerShiftUncertaintyInHz(); + method public double getElevationInDeg(); + method public double getElevationUncertaintyInDeg(); + method public byte getLossOfLock(); + method public byte getMultipathIndicator(); + method public byte getPrn(); + method public double getPseudorangeInMeters(); + method public double getPseudorangeRateCarrierInMetersPerSec(); + method public double getPseudorangeRateCarrierUncertaintyInMetersPerSec(); + method public double getPseudorangeRateInMetersPerSec(); + method public double getPseudorangeRateUncertaintyInMetersPerSec(); + method public double getPseudorangeUncertaintyInMeters(); + method public long getReceivedGpsTowInNs(); + method public long getReceivedGpsTowUncertaintyInNs(); + method public double getSnrInDb(); + method public short getState(); + method public short getTimeFromLastBitInMs(); + method public double getTimeOffsetInNs(); + method public boolean hasAzimuthInDeg(); + method public boolean hasAzimuthUncertaintyInDeg(); + method public boolean hasBitNumber(); + method public boolean hasCarrierCycles(); + method public boolean hasCarrierFrequencyInHz(); + method public boolean hasCarrierPhase(); + method public boolean hasCarrierPhaseUncertainty(); + method public boolean hasCodePhaseInChips(); + method public boolean hasCodePhaseUncertaintyInChips(); + method public boolean hasDopplerShiftInHz(); + method public boolean hasDopplerShiftUncertaintyInHz(); + method public boolean hasElevationInDeg(); + method public boolean hasElevationUncertaintyInDeg(); + method public boolean hasPseudorangeInMeters(); + method public boolean hasPseudorangeUncertaintyInMeters(); + method public boolean hasSnrInDb(); + method public boolean hasTimeFromLastBitInMs(); + method public boolean isPseudorangeRateCorrected(); + method public boolean isUsedInFix(); + method public void reset(); + method public void resetAzimuthInDeg(); + method public void resetAzimuthUncertaintyInDeg(); + method public void resetBitNumber(); + method public void resetCarrierCycles(); + method public void resetCarrierFrequencyInHz(); + method public void resetCarrierPhase(); + method public void resetCarrierPhaseUncertainty(); + method public void resetCodePhaseInChips(); + method public void resetCodePhaseUncertaintyInChips(); + method public void resetDopplerShiftInHz(); + method public void resetDopplerShiftUncertaintyInHz(); + method public void resetElevationInDeg(); + method public void resetElevationUncertaintyInDeg(); + method public void resetPseudorangeInMeters(); + method public void resetPseudorangeUncertaintyInMeters(); + method public void resetSnrInDb(); + method public void resetTimeFromLastBitInMs(); + method public void set(android.location.GpsMeasurement); + method public void setAccumulatedDeltaRangeInMeters(double); + method public void setAccumulatedDeltaRangeState(short); + method public void setAccumulatedDeltaRangeUncertaintyInMeters(double); + method public void setAzimuthInDeg(double); + method public void setAzimuthUncertaintyInDeg(double); + method public void setBitNumber(int); + method public void setCarrierCycles(long); + method public void setCarrierFrequencyInHz(float); + method public void setCarrierPhase(double); + method public void setCarrierPhaseUncertainty(double); + method public void setCn0InDbHz(double); + method public void setCodePhaseInChips(double); + method public void setCodePhaseUncertaintyInChips(double); + method public void setDopplerShiftInHz(double); + method public void setDopplerShiftUncertaintyInHz(double); + method public void setElevationInDeg(double); + method public void setElevationUncertaintyInDeg(double); + method public void setLossOfLock(byte); + method public void setMultipathIndicator(byte); + method public void setPrn(byte); + method public void setPseudorangeInMeters(double); + method public void setPseudorangeRateCarrierInMetersPerSec(double); + method public void setPseudorangeRateCarrierUncertaintyInMetersPerSec(double); + method public void setPseudorangeRateInMetersPerSec(double); + method public void setPseudorangeRateUncertaintyInMetersPerSec(double); + method public void setPseudorangeUncertaintyInMeters(double); + method public void setReceivedGpsTowInNs(long); + method public void setReceivedGpsTowUncertaintyInNs(long); + method public void setSnrInDb(double); + method public void setState(short); + method public void setTimeFromLastBitInMs(short); + method public void setTimeOffsetInNs(double); + method public void setUsedInFix(boolean); + method public void writeToParcel(android.os.Parcel, int); + field public static final short ADR_STATE_CYCLE_SLIP = 4; // 0x4 + field public static final short ADR_STATE_RESET = 2; // 0x2 + field public static final short ADR_STATE_UNKNOWN = 0; // 0x0 + field public static final short ADR_STATE_VALID = 1; // 0x1 + field public static final android.os.Parcelable.Creator CREATOR; + field public static final byte LOSS_OF_LOCK_CYCLE_SLIP = 2; // 0x2 + field public static final byte LOSS_OF_LOCK_OK = 1; // 0x1 + field public static final byte LOSS_OF_LOCK_UNKNOWN = 0; // 0x0 + field public static final byte MULTIPATH_INDICATOR_DETECTED = 1; // 0x1 + field public static final byte MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2 + field public static final byte MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0 + field public static final short STATE_BIT_SYNC = 2; // 0x2 + field public static final short STATE_CODE_LOCK = 1; // 0x1 + field public static final short STATE_MSEC_AMBIGUOUS = 16; // 0x10 + field public static final short STATE_SUBFRAME_SYNC = 4; // 0x4 + field public static final short STATE_TOW_DECODED = 8; // 0x8 + field public static final short STATE_UNKNOWN = 0; // 0x0 + } + + public static abstract class GpsMeasurement.LossOfLockStatus implements java.lang.annotation.Annotation { + } + + public static abstract class GpsMeasurement.MultipathIndicator implements java.lang.annotation.Annotation { + } + + public final class GpsMeasurementsEvent implements android.os.Parcelable { + ctor public GpsMeasurementsEvent(android.location.GpsClock, android.location.GpsMeasurement[]); + method public int describeContents(); + method public android.location.GpsClock getClock(); + method public java.util.Collection getMeasurements(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator CREATOR; + field public static final int STATUS_GPS_LOCATION_DISABLED = 2; // 0x2 + field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0 + field public static final int STATUS_READY = 1; // 0x1 + } + + public static abstract class GpsMeasurementsEvent.Callback { + ctor public GpsMeasurementsEvent.Callback(); + method public void onGpsMeasurementsReceived(android.location.GpsMeasurementsEvent); + method public void onStatusChanged(int); + } + + public static abstract class GpsMeasurementsEvent.GpsMeasurementsStatus implements java.lang.annotation.Annotation { + } + + public final class GpsNavigationMessage implements android.os.Parcelable { + method public int describeContents(); + method public byte[] getData(); + method public short getMessageId(); + method public byte getPrn(); + method public short getStatus(); + method public short getSubmessageId(); + method public byte getType(); + method public void reset(); + method public void set(android.location.GpsNavigationMessage); + method public void setData(byte[]); + method public void setMessageId(short); + method public void setPrn(byte); + method public void setStatus(short); + method public void setSubmessageId(short); + method public void setType(byte); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator CREATOR; + field public static final byte MESSAGE_TYPE_CNAV2 = 4; // 0x4 + field public static final byte MESSAGE_TYPE_L1CA = 1; // 0x1 + field public static final byte MESSAGE_TYPE_L2CNAV = 2; // 0x2 + field public static final byte MESSAGE_TYPE_L5CNAV = 3; // 0x3 + field public static final byte MESSAGE_TYPE_UNKNOWN = 0; // 0x0 + field public static final short STATUS_PARITY_PASSED = 1; // 0x1 + field public static final short STATUS_PARITY_REBUILT = 2; // 0x2 + field public static final short STATUS_UNKNOWN = 0; // 0x0 + } + + public static abstract class GpsNavigationMessage.GpsNavigationMessageType implements java.lang.annotation.Annotation { + } + + public final class GpsNavigationMessageEvent implements android.os.Parcelable { + ctor public GpsNavigationMessageEvent(android.location.GpsNavigationMessage); + method public int describeContents(); + method public android.location.GpsNavigationMessage getNavigationMessage(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator CREATOR; + field public static final int STATUS_GPS_LOCATION_DISABLED = 2; // 0x2 + field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0 + field public static final int STATUS_READY = 1; // 0x1 + } + + public static abstract class GpsNavigationMessageEvent.Callback { + ctor public GpsNavigationMessageEvent.Callback(); + method public void onGpsNavigationMessageReceived(android.location.GpsNavigationMessageEvent); + method public void onStatusChanged(int); + } + + public static abstract class GpsNavigationMessageEvent.GpsNavigationMessageStatus implements java.lang.annotation.Annotation { + } + public final class GpsSatellite { method public float getAzimuth(); method public float getElevation(); @@ -19120,8 +19402,10 @@ package android.location { } public class LocationManager { - method public boolean addGpsStatusListener(android.location.GpsStatus.Listener); - method public boolean addNmeaListener(android.location.GpsStatus.NmeaListener); + method public deprecated boolean addGpsStatusListener(android.location.GpsStatus.Listener); + method public deprecated boolean addNmeaListener(android.location.GpsStatus.NmeaListener); + method public boolean addNmeaListener(android.location.GnssNmeaListener); + method public boolean addNmeaListener(android.location.GnssNmeaListener, android.os.Handler); method public void addProximityAlert(double, double, float, long, android.app.PendingIntent); method public void addTestProvider(java.lang.String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int); method public void clearTestProviderEnabled(java.lang.String); @@ -19129,14 +19413,21 @@ package android.location { method public void clearTestProviderStatus(java.lang.String); method public java.util.List getAllProviders(); method public java.lang.String getBestProvider(android.location.Criteria, boolean); - method public android.location.GpsStatus getGpsStatus(android.location.GpsStatus); + method public deprecated android.location.GpsStatus getGpsStatus(android.location.GpsStatus); method public android.location.Location getLastKnownLocation(java.lang.String); method public android.location.LocationProvider getProvider(java.lang.String); method public java.util.List getProviders(boolean); method public java.util.List getProviders(android.location.Criteria, boolean); method public boolean isProviderEnabled(java.lang.String); - method public void removeGpsStatusListener(android.location.GpsStatus.Listener); - method public void removeNmeaListener(android.location.GpsStatus.NmeaListener); + method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback); + method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback, android.os.Handler); + method public boolean registerGpsMeasurementCallback(android.location.GpsMeasurementsEvent.Callback); + method public boolean registerGpsMeasurementCallback(android.location.GpsMeasurementsEvent.Callback, android.os.Handler); + method public boolean registerGpsNavigationMessageCallback(android.location.GpsNavigationMessageEvent.Callback); + method public boolean registerGpsNavigationMessageCallback(android.location.GpsNavigationMessageEvent.Callback, android.os.Handler); + method public deprecated void removeGpsStatusListener(android.location.GpsStatus.Listener); + method public deprecated void removeNmeaListener(android.location.GpsStatus.NmeaListener); + method public void removeNmeaListener(android.location.GnssNmeaListener); method public void removeProximityAlert(android.app.PendingIntent); method public void removeTestProvider(java.lang.String); method public void removeUpdates(android.location.LocationListener); @@ -19154,6 +19445,9 @@ package android.location { method public void setTestProviderEnabled(java.lang.String, boolean); method public void setTestProviderLocation(java.lang.String, android.location.Location); method public void setTestProviderStatus(java.lang.String, int, android.os.Bundle, long); + method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback); + method public void unregisterGpsMeasurementCallback(android.location.GpsMeasurementsEvent.Callback); + method public void unregisterGpsNavigationMessageCallback(android.location.GpsNavigationMessageEvent.Callback); field public static final java.lang.String GPS_PROVIDER = "gps"; field public static final java.lang.String KEY_LOCATION_CHANGED = "location"; field public static final java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled"; diff --git a/api/system-current.txt b/api/system-current.txt index 40c62acf0c97e..d29c4963a1d2c 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -20072,7 +20072,38 @@ package android.location { method public static boolean isPresent(); } - public class GpsClock implements android.os.Parcelable { + public abstract interface GnssNmeaListener { + method public abstract void onNmeaReceived(long, java.lang.String); + } + + public final class GnssStatus { + method public float getAzimuth(int); + method public int getConstellationType(int); + method public float getElevation(int); + method public int getNumSatellites(); + method public int getPrn(int); + method public float getSnr(int); + method public boolean hasAlmanac(int); + method public boolean hasEphemeris(int); + method public boolean usedInFix(int); + field public static final int CONSTELLATION_BEIDOU = 5; // 0x5 + field public static final int CONSTELLATION_GALILEO = 6; // 0x6 + field public static final int CONSTELLATION_GLONASS = 3; // 0x3 + field public static final int CONSTELLATION_GPS = 1; // 0x1 + field public static final int CONSTELLATION_QZSS = 4; // 0x4 + field public static final int CONSTELLATION_SBAS = 2; // 0x2 + field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0 + } + + public abstract class GnssStatusCallback { + ctor public GnssStatusCallback(); + method public void onFirstFix(int); + method public void onSatelliteStatusChanged(android.location.GnssStatus); + method public void onStarted(); + method public void onStopped(); + } + + public final class GpsClock implements android.os.Parcelable { method public int describeContents(); method public double getBiasInNs(); method public double getBiasUncertaintyInNs(); @@ -20081,6 +20112,7 @@ package android.location { method public long getFullBiasInNs(); method public short getLeapSecond(); method public long getTimeInNs(); + method public long getTimeOfLastHwClockDiscontinuityInNs(); method public double getTimeUncertaintyInNs(); method public byte getType(); method public boolean hasBiasInNs(); @@ -20106,16 +20138,20 @@ package android.location { method public void setFullBiasInNs(long); method public void setLeapSecond(short); method public void setTimeInNs(long); + method public void setTimeOfLastHwClockDiscontinuityInNs(long); method public void setTimeUncertaintyInNs(double); method public void setType(byte); method public void writeToParcel(android.os.Parcel, int); + field public static final byte CLOCK_TYPE_GPS_TIME = 2; // 0x2 + field public static final byte CLOCK_TYPE_LOCAL_HW_TIME = 1; // 0x1 + field public static final byte CLOCK_TYPE_UNKNOWN = 0; // 0x0 field public static final android.os.Parcelable.Creator CREATOR; - field public static final byte TYPE_GPS_TIME = 2; // 0x2 - field public static final byte TYPE_LOCAL_HW_TIME = 1; // 0x1 - field public static final byte TYPE_UNKNOWN = 0; // 0x0 } - public class GpsMeasurement implements android.os.Parcelable { + public static abstract class GpsClock.GpsClockType implements java.lang.annotation.Annotation { + } + + public final class GpsMeasurement implements android.os.Parcelable { method public int describeContents(); method public double getAccumulatedDeltaRangeInMeters(); method public short getAccumulatedDeltaRangeState(); @@ -20138,6 +20174,8 @@ package android.location { method public byte getMultipathIndicator(); method public byte getPrn(); method public double getPseudorangeInMeters(); + method public double getPseudorangeRateCarrierInMetersPerSec(); + method public double getPseudorangeRateCarrierUncertaintyInMetersPerSec(); method public double getPseudorangeRateInMetersPerSec(); method public double getPseudorangeRateUncertaintyInMetersPerSec(); method public double getPseudorangeUncertaintyInMeters(); @@ -20206,6 +20244,8 @@ package android.location { method public void setMultipathIndicator(byte); method public void setPrn(byte); method public void setPseudorangeInMeters(double); + method public void setPseudorangeRateCarrierInMetersPerSec(double); + method public void setPseudorangeRateCarrierUncertaintyInMetersPerSec(double); method public void setPseudorangeRateInMetersPerSec(double); method public void setPseudorangeRateUncertaintyInMetersPerSec(double); method public void setPseudorangeUncertaintyInMeters(double); @@ -20236,7 +20276,13 @@ package android.location { field public static final short STATE_UNKNOWN = 0; // 0x0 } - public class GpsMeasurementsEvent implements android.os.Parcelable { + public static abstract class GpsMeasurement.LossOfLockStatus implements java.lang.annotation.Annotation { + } + + public static abstract class GpsMeasurement.MultipathIndicator implements java.lang.annotation.Annotation { + } + + public final class GpsMeasurementsEvent implements android.os.Parcelable { ctor public GpsMeasurementsEvent(android.location.GpsClock, android.location.GpsMeasurement[]); method public int describeContents(); method public android.location.GpsClock getClock(); @@ -20248,12 +20294,16 @@ package android.location { field public static final int STATUS_READY = 1; // 0x1 } - public static abstract interface GpsMeasurementsEvent.Listener { - method public abstract void onGpsMeasurementsReceived(android.location.GpsMeasurementsEvent); - method public abstract void onStatusChanged(int); + public static abstract class GpsMeasurementsEvent.Callback { + ctor public GpsMeasurementsEvent.Callback(); + method public void onGpsMeasurementsReceived(android.location.GpsMeasurementsEvent); + method public void onStatusChanged(int); } - public class GpsNavigationMessage implements android.os.Parcelable { + public static abstract class GpsMeasurementsEvent.GpsMeasurementsStatus implements java.lang.annotation.Annotation { + } + + public final class GpsNavigationMessage implements android.os.Parcelable { method public int describeContents(); method public byte[] getData(); method public short getMessageId(); @@ -20271,30 +20321,37 @@ package android.location { method public void setType(byte); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; + field public static final byte MESSAGE_TYPE_CNAV2 = 4; // 0x4 + field public static final byte MESSAGE_TYPE_L1CA = 1; // 0x1 + field public static final byte MESSAGE_TYPE_L2CNAV = 2; // 0x2 + field public static final byte MESSAGE_TYPE_L5CNAV = 3; // 0x3 + field public static final byte MESSAGE_TYPE_UNKNOWN = 0; // 0x0 field public static final short STATUS_PARITY_PASSED = 1; // 0x1 field public static final short STATUS_PARITY_REBUILT = 2; // 0x2 field public static final short STATUS_UNKNOWN = 0; // 0x0 - field public static final byte TYPE_CNAV2 = 4; // 0x4 - field public static final byte TYPE_L1CA = 1; // 0x1 - field public static final byte TYPE_L2CNAV = 2; // 0x2 - field public static final byte TYPE_L5CNAV = 3; // 0x3 - field public static final byte TYPE_UNKNOWN = 0; // 0x0 } - public class GpsNavigationMessageEvent implements android.os.Parcelable { + public static abstract class GpsNavigationMessage.GpsNavigationMessageType implements java.lang.annotation.Annotation { + } + + public final class GpsNavigationMessageEvent implements android.os.Parcelable { ctor public GpsNavigationMessageEvent(android.location.GpsNavigationMessage); method public int describeContents(); method public android.location.GpsNavigationMessage getNavigationMessage(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; - field public static int STATUS_GPS_LOCATION_DISABLED; - field public static int STATUS_NOT_SUPPORTED; - field public static int STATUS_READY; + field public static final int STATUS_GPS_LOCATION_DISABLED = 2; // 0x2 + field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0 + field public static final int STATUS_READY = 1; // 0x1 } - public static abstract interface GpsNavigationMessageEvent.Listener { - method public abstract void onGpsNavigationMessageReceived(android.location.GpsNavigationMessageEvent); - method public abstract void onStatusChanged(int); + public static abstract class GpsNavigationMessageEvent.Callback { + ctor public GpsNavigationMessageEvent.Callback(); + method public void onGpsNavigationMessageReceived(android.location.GpsNavigationMessageEvent); + method public void onStatusChanged(int); + } + + public static abstract class GpsNavigationMessageEvent.GpsNavigationMessageStatus implements java.lang.annotation.Annotation { } public final class GpsSatellite { @@ -20401,10 +20458,10 @@ package android.location { } public class LocationManager { - method public boolean addGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener); - method public boolean addGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener); - method public boolean addGpsStatusListener(android.location.GpsStatus.Listener); - method public boolean addNmeaListener(android.location.GpsStatus.NmeaListener); + method public deprecated boolean addGpsStatusListener(android.location.GpsStatus.Listener); + method public deprecated boolean addNmeaListener(android.location.GpsStatus.NmeaListener); + method public boolean addNmeaListener(android.location.GnssNmeaListener); + method public boolean addNmeaListener(android.location.GnssNmeaListener, android.os.Handler); method public void addProximityAlert(double, double, float, long, android.app.PendingIntent); method public void addTestProvider(java.lang.String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int); method public void clearTestProviderEnabled(java.lang.String); @@ -20412,16 +20469,21 @@ package android.location { method public void clearTestProviderStatus(java.lang.String); method public java.util.List getAllProviders(); method public java.lang.String getBestProvider(android.location.Criteria, boolean); - method public android.location.GpsStatus getGpsStatus(android.location.GpsStatus); + method public deprecated android.location.GpsStatus getGpsStatus(android.location.GpsStatus); method public android.location.Location getLastKnownLocation(java.lang.String); method public android.location.LocationProvider getProvider(java.lang.String); method public java.util.List getProviders(boolean); method public java.util.List getProviders(android.location.Criteria, boolean); method public boolean isProviderEnabled(java.lang.String); - method public void removeGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener); - method public void removeGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener); - method public void removeGpsStatusListener(android.location.GpsStatus.Listener); - method public void removeNmeaListener(android.location.GpsStatus.NmeaListener); + method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback); + method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback, android.os.Handler); + method public boolean registerGpsMeasurementCallback(android.location.GpsMeasurementsEvent.Callback); + method public boolean registerGpsMeasurementCallback(android.location.GpsMeasurementsEvent.Callback, android.os.Handler); + method public boolean registerGpsNavigationMessageCallback(android.location.GpsNavigationMessageEvent.Callback); + method public boolean registerGpsNavigationMessageCallback(android.location.GpsNavigationMessageEvent.Callback, android.os.Handler); + method public deprecated void removeGpsStatusListener(android.location.GpsStatus.Listener); + method public deprecated void removeNmeaListener(android.location.GpsStatus.NmeaListener); + method public void removeNmeaListener(android.location.GnssNmeaListener); method public void removeProximityAlert(android.app.PendingIntent); method public void removeTestProvider(java.lang.String); method public void removeUpdates(android.location.LocationListener); @@ -20441,6 +20503,9 @@ package android.location { method public void setTestProviderEnabled(java.lang.String, boolean); method public void setTestProviderLocation(java.lang.String, android.location.Location); method public void setTestProviderStatus(java.lang.String, int, android.os.Bundle, long); + method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback); + method public void unregisterGpsMeasurementCallback(android.location.GpsMeasurementsEvent.Callback); + method public void unregisterGpsNavigationMessageCallback(android.location.GpsNavigationMessageEvent.Callback); field public static final java.lang.String GPS_PROVIDER = "gps"; field public static final java.lang.String KEY_LOCATION_CHANGED = "location"; field public static final java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled"; diff --git a/api/test-current.txt b/api/test-current.txt index d28c463a559ba..37978055dd2d7 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -19044,6 +19044,288 @@ package android.location { method public static boolean isPresent(); } + public abstract interface GnssNmeaListener { + method public abstract void onNmeaReceived(long, java.lang.String); + } + + public final class GnssStatus { + method public float getAzimuth(int); + method public int getConstellationType(int); + method public float getElevation(int); + method public int getNumSatellites(); + method public int getPrn(int); + method public float getSnr(int); + method public boolean hasAlmanac(int); + method public boolean hasEphemeris(int); + method public boolean usedInFix(int); + field public static final int CONSTELLATION_BEIDOU = 5; // 0x5 + field public static final int CONSTELLATION_GALILEO = 6; // 0x6 + field public static final int CONSTELLATION_GLONASS = 3; // 0x3 + field public static final int CONSTELLATION_GPS = 1; // 0x1 + field public static final int CONSTELLATION_QZSS = 4; // 0x4 + field public static final int CONSTELLATION_SBAS = 2; // 0x2 + field public static final int CONSTELLATION_UNKNOWN = 0; // 0x0 + } + + public abstract class GnssStatusCallback { + ctor public GnssStatusCallback(); + method public void onFirstFix(int); + method public void onSatelliteStatusChanged(android.location.GnssStatus); + method public void onStarted(); + method public void onStopped(); + } + + public final class GpsClock implements android.os.Parcelable { + method public int describeContents(); + method public double getBiasInNs(); + method public double getBiasUncertaintyInNs(); + method public double getDriftInNsPerSec(); + method public double getDriftUncertaintyInNsPerSec(); + method public long getFullBiasInNs(); + method public short getLeapSecond(); + method public long getTimeInNs(); + method public long getTimeOfLastHwClockDiscontinuityInNs(); + method public double getTimeUncertaintyInNs(); + method public byte getType(); + method public boolean hasBiasInNs(); + method public boolean hasBiasUncertaintyInNs(); + method public boolean hasDriftInNsPerSec(); + method public boolean hasDriftUncertaintyInNsPerSec(); + method public boolean hasFullBiasInNs(); + method public boolean hasLeapSecond(); + method public boolean hasTimeUncertaintyInNs(); + method public void reset(); + method public void resetBiasInNs(); + method public void resetBiasUncertaintyInNs(); + method public void resetDriftInNsPerSec(); + method public void resetDriftUncertaintyInNsPerSec(); + method public void resetFullBiasInNs(); + method public void resetLeapSecond(); + method public void resetTimeUncertaintyInNs(); + method public void set(android.location.GpsClock); + method public void setBiasInNs(double); + method public void setBiasUncertaintyInNs(double); + method public void setDriftInNsPerSec(double); + method public void setDriftUncertaintyInNsPerSec(double); + method public void setFullBiasInNs(long); + method public void setLeapSecond(short); + method public void setTimeInNs(long); + method public void setTimeOfLastHwClockDiscontinuityInNs(long); + method public void setTimeUncertaintyInNs(double); + method public void setType(byte); + method public void writeToParcel(android.os.Parcel, int); + field public static final byte CLOCK_TYPE_GPS_TIME = 2; // 0x2 + field public static final byte CLOCK_TYPE_LOCAL_HW_TIME = 1; // 0x1 + field public static final byte CLOCK_TYPE_UNKNOWN = 0; // 0x0 + field public static final android.os.Parcelable.Creator CREATOR; + } + + public static abstract class GpsClock.GpsClockType implements java.lang.annotation.Annotation { + } + + public final class GpsMeasurement implements android.os.Parcelable { + method public int describeContents(); + method public double getAccumulatedDeltaRangeInMeters(); + method public short getAccumulatedDeltaRangeState(); + method public double getAccumulatedDeltaRangeUncertaintyInMeters(); + method public double getAzimuthInDeg(); + method public double getAzimuthUncertaintyInDeg(); + method public int getBitNumber(); + method public long getCarrierCycles(); + method public float getCarrierFrequencyInHz(); + method public double getCarrierPhase(); + method public double getCarrierPhaseUncertainty(); + method public double getCn0InDbHz(); + method public double getCodePhaseInChips(); + method public double getCodePhaseUncertaintyInChips(); + method public double getDopplerShiftInHz(); + method public double getDopplerShiftUncertaintyInHz(); + method public double getElevationInDeg(); + method public double getElevationUncertaintyInDeg(); + method public byte getLossOfLock(); + method public byte getMultipathIndicator(); + method public byte getPrn(); + method public double getPseudorangeInMeters(); + method public double getPseudorangeRateCarrierInMetersPerSec(); + method public double getPseudorangeRateCarrierUncertaintyInMetersPerSec(); + method public double getPseudorangeRateInMetersPerSec(); + method public double getPseudorangeRateUncertaintyInMetersPerSec(); + method public double getPseudorangeUncertaintyInMeters(); + method public long getReceivedGpsTowInNs(); + method public long getReceivedGpsTowUncertaintyInNs(); + method public double getSnrInDb(); + method public short getState(); + method public short getTimeFromLastBitInMs(); + method public double getTimeOffsetInNs(); + method public boolean hasAzimuthInDeg(); + method public boolean hasAzimuthUncertaintyInDeg(); + method public boolean hasBitNumber(); + method public boolean hasCarrierCycles(); + method public boolean hasCarrierFrequencyInHz(); + method public boolean hasCarrierPhase(); + method public boolean hasCarrierPhaseUncertainty(); + method public boolean hasCodePhaseInChips(); + method public boolean hasCodePhaseUncertaintyInChips(); + method public boolean hasDopplerShiftInHz(); + method public boolean hasDopplerShiftUncertaintyInHz(); + method public boolean hasElevationInDeg(); + method public boolean hasElevationUncertaintyInDeg(); + method public boolean hasPseudorangeInMeters(); + method public boolean hasPseudorangeUncertaintyInMeters(); + method public boolean hasSnrInDb(); + method public boolean hasTimeFromLastBitInMs(); + method public boolean isPseudorangeRateCorrected(); + method public boolean isUsedInFix(); + method public void reset(); + method public void resetAzimuthInDeg(); + method public void resetAzimuthUncertaintyInDeg(); + method public void resetBitNumber(); + method public void resetCarrierCycles(); + method public void resetCarrierFrequencyInHz(); + method public void resetCarrierPhase(); + method public void resetCarrierPhaseUncertainty(); + method public void resetCodePhaseInChips(); + method public void resetCodePhaseUncertaintyInChips(); + method public void resetDopplerShiftInHz(); + method public void resetDopplerShiftUncertaintyInHz(); + method public void resetElevationInDeg(); + method public void resetElevationUncertaintyInDeg(); + method public void resetPseudorangeInMeters(); + method public void resetPseudorangeUncertaintyInMeters(); + method public void resetSnrInDb(); + method public void resetTimeFromLastBitInMs(); + method public void set(android.location.GpsMeasurement); + method public void setAccumulatedDeltaRangeInMeters(double); + method public void setAccumulatedDeltaRangeState(short); + method public void setAccumulatedDeltaRangeUncertaintyInMeters(double); + method public void setAzimuthInDeg(double); + method public void setAzimuthUncertaintyInDeg(double); + method public void setBitNumber(int); + method public void setCarrierCycles(long); + method public void setCarrierFrequencyInHz(float); + method public void setCarrierPhase(double); + method public void setCarrierPhaseUncertainty(double); + method public void setCn0InDbHz(double); + method public void setCodePhaseInChips(double); + method public void setCodePhaseUncertaintyInChips(double); + method public void setDopplerShiftInHz(double); + method public void setDopplerShiftUncertaintyInHz(double); + method public void setElevationInDeg(double); + method public void setElevationUncertaintyInDeg(double); + method public void setLossOfLock(byte); + method public void setMultipathIndicator(byte); + method public void setPrn(byte); + method public void setPseudorangeInMeters(double); + method public void setPseudorangeRateCarrierInMetersPerSec(double); + method public void setPseudorangeRateCarrierUncertaintyInMetersPerSec(double); + method public void setPseudorangeRateInMetersPerSec(double); + method public void setPseudorangeRateUncertaintyInMetersPerSec(double); + method public void setPseudorangeUncertaintyInMeters(double); + method public void setReceivedGpsTowInNs(long); + method public void setReceivedGpsTowUncertaintyInNs(long); + method public void setSnrInDb(double); + method public void setState(short); + method public void setTimeFromLastBitInMs(short); + method public void setTimeOffsetInNs(double); + method public void setUsedInFix(boolean); + method public void writeToParcel(android.os.Parcel, int); + field public static final short ADR_STATE_CYCLE_SLIP = 4; // 0x4 + field public static final short ADR_STATE_RESET = 2; // 0x2 + field public static final short ADR_STATE_UNKNOWN = 0; // 0x0 + field public static final short ADR_STATE_VALID = 1; // 0x1 + field public static final android.os.Parcelable.Creator CREATOR; + field public static final byte LOSS_OF_LOCK_CYCLE_SLIP = 2; // 0x2 + field public static final byte LOSS_OF_LOCK_OK = 1; // 0x1 + field public static final byte LOSS_OF_LOCK_UNKNOWN = 0; // 0x0 + field public static final byte MULTIPATH_INDICATOR_DETECTED = 1; // 0x1 + field public static final byte MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2 + field public static final byte MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0 + field public static final short STATE_BIT_SYNC = 2; // 0x2 + field public static final short STATE_CODE_LOCK = 1; // 0x1 + field public static final short STATE_MSEC_AMBIGUOUS = 16; // 0x10 + field public static final short STATE_SUBFRAME_SYNC = 4; // 0x4 + field public static final short STATE_TOW_DECODED = 8; // 0x8 + field public static final short STATE_UNKNOWN = 0; // 0x0 + } + + public static abstract class GpsMeasurement.LossOfLockStatus implements java.lang.annotation.Annotation { + } + + public static abstract class GpsMeasurement.MultipathIndicator implements java.lang.annotation.Annotation { + } + + public final class GpsMeasurementsEvent implements android.os.Parcelable { + ctor public GpsMeasurementsEvent(android.location.GpsClock, android.location.GpsMeasurement[]); + method public int describeContents(); + method public android.location.GpsClock getClock(); + method public java.util.Collection getMeasurements(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator CREATOR; + field public static final int STATUS_GPS_LOCATION_DISABLED = 2; // 0x2 + field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0 + field public static final int STATUS_READY = 1; // 0x1 + } + + public static abstract class GpsMeasurementsEvent.Callback { + ctor public GpsMeasurementsEvent.Callback(); + method public void onGpsMeasurementsReceived(android.location.GpsMeasurementsEvent); + method public void onStatusChanged(int); + } + + public static abstract class GpsMeasurementsEvent.GpsMeasurementsStatus implements java.lang.annotation.Annotation { + } + + public final class GpsNavigationMessage implements android.os.Parcelable { + method public int describeContents(); + method public byte[] getData(); + method public short getMessageId(); + method public byte getPrn(); + method public short getStatus(); + method public short getSubmessageId(); + method public byte getType(); + method public void reset(); + method public void set(android.location.GpsNavigationMessage); + method public void setData(byte[]); + method public void setMessageId(short); + method public void setPrn(byte); + method public void setStatus(short); + method public void setSubmessageId(short); + method public void setType(byte); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator CREATOR; + field public static final byte MESSAGE_TYPE_CNAV2 = 4; // 0x4 + field public static final byte MESSAGE_TYPE_L1CA = 1; // 0x1 + field public static final byte MESSAGE_TYPE_L2CNAV = 2; // 0x2 + field public static final byte MESSAGE_TYPE_L5CNAV = 3; // 0x3 + field public static final byte MESSAGE_TYPE_UNKNOWN = 0; // 0x0 + field public static final short STATUS_PARITY_PASSED = 1; // 0x1 + field public static final short STATUS_PARITY_REBUILT = 2; // 0x2 + field public static final short STATUS_UNKNOWN = 0; // 0x0 + } + + public static abstract class GpsNavigationMessage.GpsNavigationMessageType implements java.lang.annotation.Annotation { + } + + public final class GpsNavigationMessageEvent implements android.os.Parcelable { + ctor public GpsNavigationMessageEvent(android.location.GpsNavigationMessage); + method public int describeContents(); + method public android.location.GpsNavigationMessage getNavigationMessage(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator CREATOR; + field public static final int STATUS_GPS_LOCATION_DISABLED = 2; // 0x2 + field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0 + field public static final int STATUS_READY = 1; // 0x1 + } + + public static abstract class GpsNavigationMessageEvent.Callback { + ctor public GpsNavigationMessageEvent.Callback(); + method public void onGpsNavigationMessageReceived(android.location.GpsNavigationMessageEvent); + method public void onStatusChanged(int); + } + + public static abstract class GpsNavigationMessageEvent.GpsNavigationMessageStatus implements java.lang.annotation.Annotation { + } + public final class GpsSatellite { method public float getAzimuth(); method public float getElevation(); @@ -19128,8 +19410,10 @@ package android.location { } public class LocationManager { - method public boolean addGpsStatusListener(android.location.GpsStatus.Listener); - method public boolean addNmeaListener(android.location.GpsStatus.NmeaListener); + method public deprecated boolean addGpsStatusListener(android.location.GpsStatus.Listener); + method public deprecated boolean addNmeaListener(android.location.GpsStatus.NmeaListener); + method public boolean addNmeaListener(android.location.GnssNmeaListener); + method public boolean addNmeaListener(android.location.GnssNmeaListener, android.os.Handler); method public void addProximityAlert(double, double, float, long, android.app.PendingIntent); method public void addTestProvider(java.lang.String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int); method public void clearTestProviderEnabled(java.lang.String); @@ -19137,14 +19421,22 @@ package android.location { method public void clearTestProviderStatus(java.lang.String); method public java.util.List getAllProviders(); method public java.lang.String getBestProvider(android.location.Criteria, boolean); - method public android.location.GpsStatus getGpsStatus(android.location.GpsStatus); + method public deprecated android.location.GpsStatus getGpsStatus(android.location.GpsStatus); + method public int getGpsYearOfHardware(); method public android.location.Location getLastKnownLocation(java.lang.String); method public android.location.LocationProvider getProvider(java.lang.String); method public java.util.List getProviders(boolean); method public java.util.List getProviders(android.location.Criteria, boolean); method public boolean isProviderEnabled(java.lang.String); - method public void removeGpsStatusListener(android.location.GpsStatus.Listener); - method public void removeNmeaListener(android.location.GpsStatus.NmeaListener); + method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback); + method public boolean registerGnssStatusCallback(android.location.GnssStatusCallback, android.os.Handler); + method public boolean registerGpsMeasurementCallback(android.location.GpsMeasurementsEvent.Callback); + method public boolean registerGpsMeasurementCallback(android.location.GpsMeasurementsEvent.Callback, android.os.Handler); + method public boolean registerGpsNavigationMessageCallback(android.location.GpsNavigationMessageEvent.Callback); + method public boolean registerGpsNavigationMessageCallback(android.location.GpsNavigationMessageEvent.Callback, android.os.Handler); + method public deprecated void removeGpsStatusListener(android.location.GpsStatus.Listener); + method public deprecated void removeNmeaListener(android.location.GpsStatus.NmeaListener); + method public void removeNmeaListener(android.location.GnssNmeaListener); method public void removeProximityAlert(android.app.PendingIntent); method public void removeTestProvider(java.lang.String); method public void removeUpdates(android.location.LocationListener); @@ -19162,6 +19454,9 @@ package android.location { method public void setTestProviderEnabled(java.lang.String, boolean); method public void setTestProviderLocation(java.lang.String, android.location.Location); method public void setTestProviderStatus(java.lang.String, int, android.os.Bundle, long); + method public void unregisterGnssStatusCallback(android.location.GnssStatusCallback); + method public void unregisterGpsMeasurementCallback(android.location.GpsMeasurementsEvent.Callback); + method public void unregisterGpsNavigationMessageCallback(android.location.GpsNavigationMessageEvent.Callback); field public static final java.lang.String GPS_PROVIDER = "gps"; field public static final java.lang.String KEY_LOCATION_CHANGED = "location"; field public static final java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled"; diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 92c721bdb0178..25b38c07aa667 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -1189,7 +1189,7 @@ public class ConnectivityManager { return TYPE_NONE; } - // Do this only for SUPL, until GpsLocationProvider is fixed. http://b/25876485 . + // Do this only for SUPL, until GnssLocationProvider is fixed. http://b/25876485 . if (!netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) { // NOTE: if this causes app breakage, we should not just comment out this early return; // instead, we should make this early return conditional on the requesting app's target @@ -3170,7 +3170,7 @@ public class ConnectivityManager { // Checks whether the calling app can use the legacy routing API (startUsingNetworkFeature, // stopUsingNetworkFeature, requestRouteToHost), and if not throw UnsupportedOperationException. - // TODO: convert the existing system users (Tethering, GpsLocationProvider) to the new APIs and + // TODO: convert the existing system users (Tethering, GnssLocationProvider) to the new APIs and // remove these exemptions. Note that this check is not secure, and apps can still access these // functions by accessing ConnectivityService directly. However, it should be clear that doing // so is unsupported and may break in the future. http://b/22728205 diff --git a/core/java/com/android/internal/app/NetInitiatedActivity.java b/core/java/com/android/internal/app/NetInitiatedActivity.java index b951f50e1cd0c..d3bae16d03a7b 100644 --- a/core/java/com/android/internal/app/NetInitiatedActivity.java +++ b/core/java/com/android/internal/app/NetInitiatedActivity.java @@ -133,7 +133,7 @@ public class NetInitiatedActivity extends AlertActivity implements DialogInterfa notificationId = -1; } - // Respond to NI Handler under GpsLocationProvider, 1 = accept, 2 = deny + // Respond to NI Handler under GnssLocationProvider, 1 = accept, 2 = deny private void sendUserResponse(int response) { if (DEBUG) Log.d(TAG, "sendUserResponse, response: " + response); LocationManager locationManager = (LocationManager) diff --git a/location/java/android/location/GnssNmeaListener.java b/location/java/android/location/GnssNmeaListener.java new file mode 100644 index 0000000000000..6c9b08a67bd12 --- /dev/null +++ b/location/java/android/location/GnssNmeaListener.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2016 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; + +/** +* Used for receiving NMEA sentences from the GNSS. +* NMEA 0183 is a standard for communicating with marine electronic devices +* and is a common method for receiving data from a GNSS, typically over a serial port. +* See NMEA 0183 for more details. +* You can implement this interface and call {@link LocationManager#addNmeaListener} +* to receive NMEA data from the GNSS engine. +*/ +public interface GnssNmeaListener { + /** Called when an NMEA message is received. */ + void onNmeaReceived(long timestamp, String nmea); +} \ No newline at end of file diff --git a/location/java/android/location/GnssStatus.java b/location/java/android/location/GnssStatus.java new file mode 100644 index 0000000000000..77e8a5bbaca07 --- /dev/null +++ b/location/java/android/location/GnssStatus.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2016 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; + +/** + * This class represents the current state of the GNSS engine. + * This class is used in conjunction with the {@link GnssStatusCallback}. + */ +public final class GnssStatus { + /** Unknown constellation type. */ + public static final int CONSTELLATION_UNKNOWN = 0; + /** Constellation type constant for GPS. */ + public static final int CONSTELLATION_GPS = 1; + /** Constellation type constant for SBAS. */ + public static final int CONSTELLATION_SBAS = 2; + /** Constellation type constant for Glonass. */ + public static final int CONSTELLATION_GLONASS = 3; + /** Constellation type constant for QZSS. */ + public static final int CONSTELLATION_QZSS = 4; + /** Constellation type constant for Beidou. */ + public static final int CONSTELLATION_BEIDOU = 5; + /** Constellation type constant for Galileo. */ + public static final int CONSTELLATION_GALILEO = 6; + + // these must match the definitions in gps.h + /** @hide */ + public static final int GNSS_SV_FLAGS_NONE = 0; + /** @hide */ + public static final int GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA = (1 << 0); + /** @hide */ + public static final int GNSS_SV_FLAGS_HAS_ALMANAC_DATA = (1 << 1); + /** @hide */ + public static final int GNSS_SV_FLAGS_USED_IN_FIX = (1 << 2); + + /** @hide */ + public static final int PRN_SHIFT_WIDTH = 3; + + /* These package private values are modified by the LocationManager class */ + /* package */ int[] mPrnWithFlags; + /* package */ float[] mSnrs; + /* package */ float[] mElevations; + /* package */ float[] mAzimuths; + /* package */ int[] mConstellationTypes; + /* package */ int mSvCount; + + GnssStatus(int svCount, int[] prnWithFlags, float[] snrs, float[] elevations, float[] azimuths, + int[] constellationTypes) { + mSvCount = svCount; + mPrnWithFlags = prnWithFlags; + mSnrs = snrs; + mElevations = elevations; + mAzimuths = azimuths; + mConstellationTypes = constellationTypes; + } + + /** + * Gets the total number of satellites in satellite list. + */ + public int getNumSatellites() { + return mSvCount; + } + + /** + * Retrieves the constellation type of the satellite at the specified position. + * @param satIndex the index of the satellite in the list. + */ + public int getConstellationType(int satIndex) { + return mConstellationTypes[satIndex]; + } + + /** + * Retrieves the pseudo-random number of the satellite at the specified position. + * @param satIndex the index of the satellite in the list. + */ + public int getPrn(int satIndex) { + return mPrnWithFlags[satIndex] >> PRN_SHIFT_WIDTH; + } + + /** + * Retrieves the signal-noise ration of the satellite at the specified position. + * @param satIndex the index of the satellite in the list. + */ + public float getSnr(int satIndex) { + return mSnrs[satIndex]; + } + + /** + * Retrieves the elevation of the satellite at the specified position. + * @param satIndex the index of the satellite in the list. + */ + public float getElevation(int satIndex) { + return 0f; + } + + /** + * Retrieves the azimuth the satellite at the specified position. + * @param satIndex the index of the satellite in the list. + */ + public float getAzimuth(int satIndex) { + return mAzimuths[satIndex]; + } + + /** + * Detects whether the satellite at the specified position has ephemeris data. + * @param satIndex the index of the satellite in the list. + */ + public boolean hasEphemeris(int satIndex) { + return (mPrnWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0; + } + + /** + * Detects whether the satellite at the specified position has almanac data. + * @param satIndex the index of the satellite in the list. + */ + public boolean hasAlmanac(int satIndex) { + return (mPrnWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_ALMANAC_DATA) != 0; + } + + /** + * Detects whether the satellite at the specified position is used in fix. + * @param satIndex the index of the satellite in the list. + */ + public boolean usedInFix(int satIndex) { + return (mPrnWithFlags[satIndex] & GNSS_SV_FLAGS_USED_IN_FIX) != 0; + } +} diff --git a/location/java/android/location/GnssStatusCallback.java b/location/java/android/location/GnssStatusCallback.java new file mode 100644 index 0000000000000..b86171b35eefc --- /dev/null +++ b/location/java/android/location/GnssStatusCallback.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2016 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; + +/** + * Used for receiving notifications when GNSS events happen. + */ +public abstract class GnssStatusCallback { + /** + * Called when GNSS system has started. + */ + public void onStarted() {} + + /** + * Called when GNSS system has stopped. + */ + public void onStopped() {} + + /** + * Called when the GNSS system has received its first fix since starting. + * @param ttff the time from start to first fix. + */ + public void onFirstFix(int ttff) {} + + /** + * Called periodically to report GNSS satellite status. + * @param status the current status of all satellites. + */ + public void onSatelliteStatusChanged(GnssStatus status) {} +} \ No newline at end of file diff --git a/location/java/android/location/GpsClock.java b/location/java/android/location/GpsClock.java index 4135a1c949bb1..719e56f9dcce7 100644 --- a/location/java/android/location/GpsClock.java +++ b/location/java/android/location/GpsClock.java @@ -16,36 +16,41 @@ package android.location; -import android.annotation.SystemApi; +import android.annotation.IntDef; import android.os.Parcel; import android.os.Parcelable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * A class containing a GPS clock timestamp. * It represents a measurement of the GPS receiver's clock. - * - * @hide */ -@SystemApi -public class GpsClock implements Parcelable { +public final class GpsClock implements Parcelable { // The following enumerations must be in sync with the values declared in gps.h + /** The type of the GPS Clock. */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({CLOCK_TYPE_UNKNOWN, CLOCK_TYPE_LOCAL_HW_TIME, CLOCK_TYPE_GPS_TIME}) + public @interface GpsClockType {} + /** * The type of the time stored is not available or it is unknown. */ - public static final byte TYPE_UNKNOWN = 0; + public static final byte CLOCK_TYPE_UNKNOWN = 0; /** * The source of the time value reported by this class is the 'Local Hardware Clock'. */ - public static final byte TYPE_LOCAL_HW_TIME = 1; + public static final byte CLOCK_TYPE_LOCAL_HW_TIME = 1; /** * The source of the time value reported by this class is the 'GPS time' derived from * satellites (epoch = Jan 6, 1980). */ - public static final byte TYPE_GPS_TIME = 2; + public static final byte CLOCK_TYPE_GPS_TIME = 2; private static final short HAS_NO_FLAGS = 0; private static final short HAS_LEAP_SECOND = (1<<0); @@ -68,6 +73,7 @@ public class GpsClock implements Parcelable { private double mBiasUncertaintyInNs; private double mDriftInNsPerSec; private double mDriftUncertaintyInNsPerSec; + private long mTimeOfLastHwClockDiscontinuityInNs; GpsClock() { initialize(); @@ -87,6 +93,7 @@ public class GpsClock implements Parcelable { mBiasUncertaintyInNs = clock.mBiasUncertaintyInNs; mDriftInNsPerSec = clock.mDriftInNsPerSec; mDriftUncertaintyInNsPerSec = clock.mDriftUncertaintyInNsPerSec; + mTimeOfLastHwClockDiscontinuityInNs = clock.mTimeOfLastHwClockDiscontinuityInNs; } /** @@ -99,6 +106,7 @@ public class GpsClock implements Parcelable { /** * Gets the type of time reported by {@link #getTimeInNs()}. */ + @GpsClockType public byte getType() { return mType; } @@ -106,7 +114,7 @@ public class GpsClock implements Parcelable { /** * Sets the type of time reported. */ - public void setType(byte value) { + public void setType(@GpsClockType byte value) { mType = value; } @@ -116,11 +124,11 @@ public class GpsClock implements Parcelable { */ private String getTypeString() { switch (mType) { - case TYPE_UNKNOWN: + case CLOCK_TYPE_UNKNOWN: return "Unknown"; - case TYPE_GPS_TIME: + case CLOCK_TYPE_GPS_TIME: return "GpsTime"; - case TYPE_LOCAL_HW_TIME: + case CLOCK_TYPE_LOCAL_HW_TIME: return "LocalHwClock"; default: return ""; @@ -163,8 +171,8 @@ public class GpsClock implements Parcelable { /** * Gets the GPS receiver internal clock value in nanoseconds. - * This can be either the 'local hardware clock' value ({@link #TYPE_LOCAL_HW_TIME}), or the - * current GPS time derived inside GPS receiver ({@link #TYPE_GPS_TIME}). + * This can be either the 'local hardware clock' value ({@link #CLOCK_TYPE_LOCAL_HW_TIME}), or the + * current GPS time derived inside GPS receiver ({@link #CLOCK_TYPE_GPS_TIME}). * {@link #getType()} defines the time reported. * * For 'local hardware clock' this value is expected to be monotonically increasing during the @@ -223,7 +231,7 @@ public class GpsClock implements Parcelable { } /** - * Returns true if {@link @getFullBiasInNs()} is available, false otherwise. + * Returns true if {@link #getFullBiasInNs()} is available, false otherwise. */ public boolean hasFullBiasInNs() { return isFlagSet(HAS_FULL_BIAS); @@ -233,7 +241,7 @@ public class GpsClock implements Parcelable { * Gets the difference between hardware clock ({@link #getTimeInNs()}) inside GPS receiver and * the true GPS time since 0000Z, January 6, 1980, in nanoseconds. * - * This value is available if {@link #TYPE_LOCAL_HW_TIME} is set, and GPS receiver has solved + * This value is available if {@link #CLOCK_TYPE_LOCAL_HW_TIME} is set, and GPS receiver has solved * the clock for GPS time. * {@link #getBiasUncertaintyInNs()} should be used for quality check. * @@ -386,6 +394,20 @@ public class GpsClock implements Parcelable { mDriftUncertaintyInNsPerSec = driftUncertaintyInNsPerSec; } + /** + * Gets time of last hardware clock discontinuity. + */ + public long getTimeOfLastHwClockDiscontinuityInNs() { + return mTimeOfLastHwClockDiscontinuityInNs; + } + + /** + * Sets time of last hardware clock discontinuity. + */ + public void setTimeOfLastHwClockDiscontinuityInNs(long timeOfLastHwClockDiscontinuityInNs) { + mTimeOfLastHwClockDiscontinuityInNs = timeOfLastHwClockDiscontinuityInNs; + } + /** * Resets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second. */ @@ -409,6 +431,7 @@ public class GpsClock implements Parcelable { gpsClock.mBiasUncertaintyInNs = parcel.readDouble(); gpsClock.mDriftInNsPerSec = parcel.readDouble(); gpsClock.mDriftUncertaintyInNsPerSec = parcel.readDouble(); + gpsClock.mTimeOfLastHwClockDiscontinuityInNs = parcel.readLong(); return gpsClock; } @@ -430,6 +453,7 @@ public class GpsClock implements Parcelable { parcel.writeDouble(mBiasUncertaintyInNs); parcel.writeDouble(mDriftInNsPerSec); parcel.writeDouble(mDriftUncertaintyInNsPerSec); + parcel.writeLong(mTimeOfLastHwClockDiscontinuityInNs); } @Override @@ -473,13 +497,17 @@ public class GpsClock implements Parcelable { "DriftUncertaintyInNsPerSec", hasDriftUncertaintyInNsPerSec() ? mDriftUncertaintyInNsPerSec : null)); + builder.append(String.format(format, "TimeOfLastHwClockDiscontinuityInNs", + getType() == CLOCK_TYPE_LOCAL_HW_TIME + ? mTimeOfLastHwClockDiscontinuityInNs : null)); + return builder.toString(); } private void initialize() { mFlags = HAS_NO_FLAGS; resetLeapSecond(); - setType(TYPE_UNKNOWN); + setType(CLOCK_TYPE_UNKNOWN); setTimeInNs(Long.MIN_VALUE); resetTimeUncertaintyInNs(); resetFullBiasInNs(); @@ -487,6 +515,7 @@ public class GpsClock implements Parcelable { resetBiasUncertaintyInNs(); resetDriftInNsPerSec(); resetDriftUncertaintyInNsPerSec(); + setTimeOfLastHwClockDiscontinuityInNs(Long.MIN_VALUE); } private void setFlag(short flag) { diff --git a/location/java/android/location/GpsMeasurement.java b/location/java/android/location/GpsMeasurement.java index f13a440f411ae..366ad61f4188e 100644 --- a/location/java/android/location/GpsMeasurement.java +++ b/location/java/android/location/GpsMeasurement.java @@ -16,17 +16,17 @@ package android.location; -import android.annotation.SystemApi; +import android.annotation.IntDef; import android.os.Parcel; import android.os.Parcelable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * A class representing a GPS satellite measurement, containing raw and computed information. - * - * @hide */ -@SystemApi -public class GpsMeasurement implements Parcelable { +public final class GpsMeasurement implements Parcelable { private int mFlags; private byte mPrn; private double mTimeOffsetInNs; @@ -59,6 +59,8 @@ public class GpsMeasurement implements Parcelable { private double mAzimuthInDeg; private double mAzimuthUncertaintyInDeg; private boolean mUsedInFix; + private double mPseudorangeRateCarrierInMetersPerSec; + private double mPseudorangeRateCarrierUncertaintyInMetersPerSec; // The following enumerations must be in sync with the values declared in gps.h @@ -83,6 +85,11 @@ public class GpsMeasurement implements Parcelable { private static final int HAS_USED_IN_FIX = (1<<17); private static final int GPS_MEASUREMENT_HAS_UNCORRECTED_PSEUDORANGE_RATE = (1<<18); + /** The status of 'loss of lock'. */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({LOSS_OF_LOCK_UNKNOWN, LOSS_OF_LOCK_OK, LOSS_OF_LOCK_CYCLE_SLIP}) + public @interface LossOfLockStatus {} + /** * The indicator is not available or it is unknown. */ @@ -98,6 +105,12 @@ public class GpsMeasurement implements Parcelable { */ public static final byte LOSS_OF_LOCK_CYCLE_SLIP = 2; + /** The status of multipath. */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({MULTIPATH_INDICATOR_UNKNOWN, MULTIPATH_INDICATOR_DETECTED, + MULTIPATH_INDICATOR_NOT_USED}) + public @interface MultipathIndicator {} + /** * The indicator is not available or it is unknown. */ @@ -218,6 +231,10 @@ public class GpsMeasurement implements Parcelable { mAzimuthInDeg = measurement.mAzimuthInDeg; mAzimuthUncertaintyInDeg = measurement.mAzimuthUncertaintyInDeg; mUsedInFix = measurement.mUsedInFix; + mPseudorangeRateCarrierInMetersPerSec = + measurement.mPseudorangeRateCarrierInMetersPerSec; + mPseudorangeRateCarrierUncertaintyInMetersPerSec = + measurement.mPseudorangeRateCarrierUncertaintyInMetersPerSec; } /** @@ -776,6 +793,7 @@ public class GpsMeasurement implements Parcelable { /** * Gets a value indicating the 'loss of lock' state of the event. */ + @LossOfLockStatus public byte getLossOfLock() { return mLossOfLock; } @@ -783,7 +801,7 @@ public class GpsMeasurement implements Parcelable { /** * Sets the 'loss of lock' status. */ - public void setLossOfLock(byte value) { + public void setLossOfLock(@LossOfLockStatus byte value) { mLossOfLock = value; } @@ -941,6 +959,7 @@ public class GpsMeasurement implements Parcelable { /** * Gets a value indicating the 'multipath' state of the event. */ + @MultipathIndicator public byte getMultipathIndicator() { return mMultipathIndicator; } @@ -948,7 +967,7 @@ public class GpsMeasurement implements Parcelable { /** * Sets the 'multi-path' indicator. */ - public void setMultipathIndicator(byte value) { + public void setMultipathIndicator(@MultipathIndicator byte value) { mMultipathIndicator = value; } @@ -1157,6 +1176,34 @@ public class GpsMeasurement implements Parcelable { mUsedInFix = value; } + /** + * Gets pseudorange rate (based on carrier phase changes) at the timestamp in m/s. + */ + public double getPseudorangeRateCarrierInMetersPerSec() { + return mPseudorangeRateCarrierInMetersPerSec; + } + + /** + * Sets pseudorange rate (based on carrier phase changes) at the timestamp in m/s. + */ + public void setPseudorangeRateCarrierInMetersPerSec(double value) { + mPseudorangeRateCarrierInMetersPerSec = value; + } + + /** + * Gets 1-Sigma uncertainty of the pseudorange rate carrier. + */ + public double getPseudorangeRateCarrierUncertaintyInMetersPerSec() { + return mPseudorangeRateCarrierUncertaintyInMetersPerSec; + } + + /** + * Sets 1-Sigma uncertainty of the pseudorange rate carrier. + */ + public void setPseudorangeRateCarrierUncertaintyInMetersPerSec(double value) { + mPseudorangeRateCarrierUncertaintyInMetersPerSec = value; + } + public static final Creator CREATOR = new Creator() { @Override public GpsMeasurement createFromParcel(Parcel parcel) { @@ -1194,6 +1241,8 @@ public class GpsMeasurement implements Parcelable { gpsMeasurement.mAzimuthInDeg = parcel.readDouble(); gpsMeasurement.mAzimuthUncertaintyInDeg = parcel.readDouble(); gpsMeasurement.mUsedInFix = parcel.readInt() != 0; + gpsMeasurement.mPseudorangeRateCarrierInMetersPerSec = parcel.readDouble(); + gpsMeasurement.mPseudorangeRateCarrierUncertaintyInMetersPerSec = parcel.readDouble(); return gpsMeasurement; } @@ -1237,6 +1286,8 @@ public class GpsMeasurement implements Parcelable { parcel.writeDouble(mAzimuthInDeg); parcel.writeDouble(mAzimuthUncertaintyInDeg); parcel.writeInt(mUsedInFix ? 1 : 0); + parcel.writeDouble(mPseudorangeRateCarrierInMetersPerSec); + parcel.writeDouble(mPseudorangeRateCarrierUncertaintyInMetersPerSec); } @Override @@ -1361,6 +1412,11 @@ public class GpsMeasurement implements Parcelable { builder.append(String.format(format, "UsedInFix", mUsedInFix)); + builder.append(String.format(format, "PseudorangeRateCarrierInMetersPerSec", + mPseudorangeRateCarrierInMetersPerSec)); + builder.append(String.format(format, "PseudorangeRateCarrierUncertaintyInMetersPerSec", + mPseudorangeRateCarrierUncertaintyInMetersPerSec)); + return builder.toString(); } @@ -1397,6 +1453,8 @@ public class GpsMeasurement implements Parcelable { resetAzimuthInDeg(); resetAzimuthUncertaintyInDeg(); setUsedInFix(false); + setPseudorangeRateCarrierInMetersPerSec(Double.MIN_VALUE); + setPseudorangeRateCarrierUncertaintyInMetersPerSec(Double.MIN_VALUE); } private void setFlag(int flag) { diff --git a/location/java/android/location/GpsMeasurementListenerTransport.java b/location/java/android/location/GpsMeasurementCallbackTransport.java similarity index 68% rename from location/java/android/location/GpsMeasurementListenerTransport.java rename to location/java/android/location/GpsMeasurementCallbackTransport.java index 610da96e0fda8..02d9026de6ce3 100644 --- a/location/java/android/location/GpsMeasurementListenerTransport.java +++ b/location/java/android/location/GpsMeasurementCallbackTransport.java @@ -20,17 +20,17 @@ import android.content.Context; import android.os.RemoteException; /** - * A handler class to manage transport listeners for {@link GpsMeasurementsEvent.Listener}. + * A handler class to manage transport callbacks for {@link GpsMeasurementsEvent.Callback}. * * @hide */ -class GpsMeasurementListenerTransport - extends LocalListenerHelper { +class GpsMeasurementCallbackTransport + extends LocalListenerHelper { private final ILocationManager mLocationManager; private final IGpsMeasurementsListener mListenerTransport = new ListenerTransport(); - public GpsMeasurementListenerTransport(Context context, ILocationManager locationManager) { + public GpsMeasurementCallbackTransport(Context context, ILocationManager locationManager) { super(context, "GpsMeasurementListenerTransport"); mLocationManager = locationManager; } @@ -50,11 +50,11 @@ class GpsMeasurementListenerTransport private class ListenerTransport extends IGpsMeasurementsListener.Stub { @Override public void onGpsMeasurementsReceived(final GpsMeasurementsEvent event) { - ListenerOperation operation = - new ListenerOperation() { + ListenerOperation operation = + new ListenerOperation() { @Override - public void execute(GpsMeasurementsEvent.Listener listener) throws RemoteException { - listener.onGpsMeasurementsReceived(event); + public void execute(GpsMeasurementsEvent.Callback callback) throws RemoteException { + callback.onGpsMeasurementsReceived(event); } }; foreach(operation); @@ -62,11 +62,11 @@ class GpsMeasurementListenerTransport @Override public void onStatusChanged(final int status) { - ListenerOperation operation = - new ListenerOperation() { + ListenerOperation operation = + new ListenerOperation() { @Override - public void execute(GpsMeasurementsEvent.Listener listener) throws RemoteException { - listener.onStatusChanged(status); + public void execute(GpsMeasurementsEvent.Callback callback) throws RemoteException { + callback.onStatusChanged(status); } }; foreach(operation); diff --git a/location/java/android/location/GpsMeasurementsEvent.java b/location/java/android/location/GpsMeasurementsEvent.java index 1366873378617..ef9edeb7692dd 100644 --- a/location/java/android/location/GpsMeasurementsEvent.java +++ b/location/java/android/location/GpsMeasurementsEvent.java @@ -16,11 +16,13 @@ package android.location; +import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.security.InvalidParameterException; import java.util.Arrays; import java.util.Collection; @@ -28,12 +30,13 @@ import java.util.Collections; /** * A class implementing a container for data associated with a measurement event. - * Events are delivered to registered instances of {@link Listener}. - * - * @hide + * Events are delivered to registered instances of {@link Callback}. */ -@SystemApi -public class GpsMeasurementsEvent implements Parcelable { +public final class GpsMeasurementsEvent implements Parcelable { + /** The status of GPS measurements event. */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_GPS_LOCATION_DISABLED}) + public @interface GpsMeasurementsStatus {} /** * The system does not support tracking of GPS Measurements. This status will not change in the @@ -58,22 +61,20 @@ public class GpsMeasurementsEvent implements Parcelable { /** * Used for receiving GPS satellite measurements from the GPS engine. * Each measurement contains raw and computed data identifying a satellite. - * You can implement this interface and call {@link LocationManager#addGpsMeasurementListener}. - * - * @hide + * You can implement this interface and call + * {@link LocationManager#registerGpsMeasurementCallback}. */ - @SystemApi - public interface Listener { + public static abstract class Callback { /** * Returns the latest collected GPS Measurements. */ - void onGpsMeasurementsReceived(GpsMeasurementsEvent eventArgs); + public void onGpsMeasurementsReceived(GpsMeasurementsEvent eventArgs) {} /** * Returns the latest status of the GPS Measurements sub-system. */ - void onStatusChanged(int status); + public void onStatusChanged(@GpsMeasurementsStatus int status) {} } public GpsMeasurementsEvent(GpsClock clock, GpsMeasurement[] measurements) { diff --git a/location/java/android/location/GpsNavigationMessage.java b/location/java/android/location/GpsNavigationMessage.java index 5c3c71012cdd5..d799572436766 100644 --- a/location/java/android/location/GpsNavigationMessage.java +++ b/location/java/android/location/GpsNavigationMessage.java @@ -16,49 +16,54 @@ package android.location; +import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.security.InvalidParameterException; /** * A class containing a GPS satellite Navigation Message. - * - * @hide */ -@SystemApi -public class GpsNavigationMessage implements Parcelable { +public final class GpsNavigationMessage implements Parcelable { private static final byte[] EMPTY_ARRAY = new byte[0]; + /** The type of the GPS Clock. */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({MESSAGE_TYPE_UNKNOWN, MESSAGE_TYPE_L1CA, MESSAGE_TYPE_L2CNAV, MESSAGE_TYPE_L5CNAV, + MESSAGE_TYPE_CNAV2}) + public @interface GpsNavigationMessageType {} + // The following enumerations must be in sync with the values declared in gps.h /** * The type of the navigation message is not available or unknown. */ - public static final byte TYPE_UNKNOWN = 0; + public static final byte MESSAGE_TYPE_UNKNOWN = 0; /** * The Navigation Message is of type L1 C/A. */ - public static final byte TYPE_L1CA = 1; + public static final byte MESSAGE_TYPE_L1CA = 1; /** * The Navigation Message is of type L1-CNAV. */ - public static final byte TYPE_L2CNAV = 2; + public static final byte MESSAGE_TYPE_L2CNAV = 2; /** * The Navigation Message is of type L5-CNAV. */ - public static final byte TYPE_L5CNAV = 3; + public static final byte MESSAGE_TYPE_L5CNAV = 3; /** * The Navigation Message is of type CNAV-2. */ - public static final byte TYPE_CNAV2 = 4; + public static final byte MESSAGE_TYPE_CNAV2 = 4; /** * The Navigation Message Status is 'unknown'. @@ -111,6 +116,7 @@ public class GpsNavigationMessage implements Parcelable { /** * Gets the type of the navigation message contained in the object. */ + @GpsNavigationMessageType public byte getType() { return mType; } @@ -118,7 +124,7 @@ public class GpsNavigationMessage implements Parcelable { /** * Sets the type of the navigation message. */ - public void setType(byte value) { + public void setType(@GpsNavigationMessageType byte value) { mType = value; } @@ -128,15 +134,15 @@ public class GpsNavigationMessage implements Parcelable { */ private String getTypeString() { switch (mType) { - case TYPE_UNKNOWN: + case MESSAGE_TYPE_UNKNOWN: return "Unknown"; - case TYPE_L1CA: + case MESSAGE_TYPE_L1CA: return "L1 C/A"; - case TYPE_L2CNAV: + case MESSAGE_TYPE_L2CNAV: return "L2-CNAV"; - case TYPE_L5CNAV: + case MESSAGE_TYPE_L5CNAV: return "L5-CNAV"; - case TYPE_CNAV2: + case MESSAGE_TYPE_CNAV2: return "CNAV-2"; default: return ""; @@ -314,7 +320,7 @@ public class GpsNavigationMessage implements Parcelable { } private void initialize() { - mType = TYPE_UNKNOWN; + mType = MESSAGE_TYPE_UNKNOWN; mPrn = 0; mMessageId = -1; mSubmessageId = -1; diff --git a/location/java/android/location/GpsNavigationMessageListenerTransport.java b/location/java/android/location/GpsNavigationMessageCallbackTransport.java similarity index 73% rename from location/java/android/location/GpsNavigationMessageListenerTransport.java rename to location/java/android/location/GpsNavigationMessageCallbackTransport.java index f6ba407d9c707..155d96dce35e0 100644 --- a/location/java/android/location/GpsNavigationMessageListenerTransport.java +++ b/location/java/android/location/GpsNavigationMessageCallbackTransport.java @@ -20,20 +20,20 @@ import android.content.Context; import android.os.RemoteException; /** - * A handler class to manage transport listeners for {@link GpsNavigationMessageEvent.Listener}. + * A handler class to manage transport callback for {@link GpsNavigationMessageEvent.Callback}. * * @hide */ -class GpsNavigationMessageListenerTransport - extends LocalListenerHelper { +class GpsNavigationMessageCallbackTransport + extends LocalListenerHelper { private final ILocationManager mLocationManager; private final IGpsNavigationMessageListener mListenerTransport = new ListenerTransport(); - public GpsNavigationMessageListenerTransport( + public GpsNavigationMessageCallbackTransport( Context context, ILocationManager locationManager) { - super(context, "GpsNavigationMessageListenerTransport"); + super(context, "GpsNavigationMessageCallbackTransport"); mLocationManager = locationManager; } @@ -52,12 +52,12 @@ class GpsNavigationMessageListenerTransport private class ListenerTransport extends IGpsNavigationMessageListener.Stub { @Override public void onGpsNavigationMessageReceived(final GpsNavigationMessageEvent event) { - ListenerOperation operation = - new ListenerOperation() { + ListenerOperation operation = + new ListenerOperation() { @Override - public void execute(GpsNavigationMessageEvent.Listener listener) + public void execute(GpsNavigationMessageEvent.Callback callback) throws RemoteException { - listener.onGpsNavigationMessageReceived(event); + callback.onGpsNavigationMessageReceived(event); } }; foreach(operation); @@ -65,12 +65,12 @@ class GpsNavigationMessageListenerTransport @Override public void onStatusChanged(final int status) { - ListenerOperation operation = - new ListenerOperation() { + ListenerOperation operation = + new ListenerOperation() { @Override - public void execute(GpsNavigationMessageEvent.Listener listener) + public void execute(GpsNavigationMessageEvent.Callback callback) throws RemoteException { - listener.onStatusChanged(status); + callback.onStatusChanged(status); } }; foreach(operation); diff --git a/location/java/android/location/GpsNavigationMessageEvent.java b/location/java/android/location/GpsNavigationMessageEvent.java index bd6921c741529..b16a4855f3899 100644 --- a/location/java/android/location/GpsNavigationMessageEvent.java +++ b/location/java/android/location/GpsNavigationMessageEvent.java @@ -16,60 +16,60 @@ package android.location; +import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.security.InvalidParameterException; /** * A class implementing a container for data associated with a navigation message event. - * Events are delivered to registered instances of {@link Listener}. - * - * @hide + * Events are delivered to registered instances of {@link Callback}. */ -@SystemApi -public class GpsNavigationMessageEvent implements Parcelable { +public final class GpsNavigationMessageEvent implements Parcelable { + /** The status of GPS measurements event. */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_GPS_LOCATION_DISABLED}) + public @interface GpsNavigationMessageStatus {} /** * The system does not support tracking of GPS Navigation Messages. This status will not change * in the future. */ - public static int STATUS_NOT_SUPPORTED = 0; + public static final int STATUS_NOT_SUPPORTED = 0; /** * GPS Navigation Messages are successfully being tracked, it will receive updates once they are * available. */ - public static int STATUS_READY = 1; + public static final int STATUS_READY = 1; /** * GPS provider or Location is disabled, updated will not be received until they are enabled. */ - public static int STATUS_GPS_LOCATION_DISABLED = 2; + public static final int STATUS_GPS_LOCATION_DISABLED = 2; private final GpsNavigationMessage mNavigationMessage; /** * Used for receiving GPS satellite Navigation Messages from the GPS engine. * You can implement this interface and call - * {@link LocationManager#addGpsNavigationMessageListener}. - * - * @hide + * {@link LocationManager#registerGpsNavigationMessageCallback}. */ - @SystemApi - public interface Listener { + public static abstract class Callback { /** * Returns the latest collected GPS Navigation Message. */ - void onGpsNavigationMessageReceived(GpsNavigationMessageEvent event); + public void onGpsNavigationMessageReceived(GpsNavigationMessageEvent event) {} /** * Returns the latest status of the GPS Navigation Messages sub-system. */ - void onStatusChanged(int status); + public void onStatusChanged(@GpsNavigationMessageStatus int status) {} } public GpsNavigationMessageEvent(GpsNavigationMessage message) { diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java index 323f3269368ef..8d2f781e497fd 100644 --- a/location/java/android/location/GpsStatus.java +++ b/location/java/android/location/GpsStatus.java @@ -34,17 +34,15 @@ public final class GpsStatus { private final SparseArray mSatellites = new SparseArray<>(); private final class SatelliteIterator implements Iterator { - - private final SparseArray mSatellites; private final int mSatellitesCount; private int mIndex = 0; - SatelliteIterator(SparseArray satellites) { - mSatellites = satellites; - mSatellitesCount = satellites.size(); + SatelliteIterator() { + mSatellitesCount = mSatellites.size(); } + @Override public boolean hasNext() { for (; mIndex < mSatellitesCount; ++mIndex) { GpsSatellite satellite = mSatellites.valueAt(mIndex); @@ -55,6 +53,7 @@ public final class GpsStatus { return false; } + @Override public GpsSatellite next() { while (mIndex < mSatellitesCount) { GpsSatellite satellite = mSatellites.valueAt(mIndex); @@ -66,14 +65,16 @@ public final class GpsStatus { throw new NoSuchElementException(); } + @Override public void remove() { throw new UnsupportedOperationException(); } } private Iterable mSatelliteList = new Iterable() { + @Override public Iterator iterator() { - return new SatelliteIterator(mSatellites); + return new SatelliteIterator(); } }; @@ -137,18 +138,15 @@ public final class GpsStatus { // For API-compat a public ctor() is not available GpsStatus() {} - /** - * Used internally within {@link LocationManager} to copy GPS status - * data from the Location Manager Service to its cached GpsStatus instance. - * Is synchronized to ensure that GPS status updates are atomic. - */ - synchronized void setStatus(int svCount, int[] prns, float[] snrs, - float[] elevations, float[] azimuths, int ephemerisMask, - int almanacMask, int usedInFixMask) { + private void setStatus(int svCount, int[] prnWithFlags, float[] snrs, float[] elevations, + float[] azimuths, int[] constellationTypes) { clearSatellites(); for (int i = 0; i < svCount; i++) { - int prn = prns[i]; - int prnShift = (1 << (prn - 1)); + // Skip all non-GPS satellites. + if (constellationTypes[i] != GnssStatus.CONSTELLATION_GPS) { + continue; + } + int prn = prnWithFlags[i] >> GnssStatus.PRN_SHIFT_WIDTH; if (prn > 0 && prn <= NUM_SATELLITES) { GpsSatellite satellite = mSatellites.get(prn); if (satellite == null) { @@ -160,53 +158,26 @@ public final class GpsStatus { 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); + satellite.mHasEphemeris = + (prnWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0; + satellite.mHasAlmanac = + (prnWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) != 0; + satellite.mUsedInFix = + (prnWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0; } } } /** - * Used by {@link LocationManager#getGpsStatus} to copy LocationManager's - * cached GpsStatus instance to the client's copy. + * Copies GPS satellites information from GnssStatus object. * Since this method is only used within {@link LocationManager#getGpsStatus}, * it does not need to be synchronized. + * @hide */ - void setStatus(GpsStatus status) { - mTimeToFirstFix = status.getTimeToFirstFix(); - clearSatellites(); - - SparseArray otherSatellites = status.mSatellites; - int otherSatellitesCount = otherSatellites.size(); - int satelliteIndex = 0; - // merge both sparse arrays, note that we have already invalidated the elements in the - // receiver array - for (int i = 0; i < otherSatellitesCount; ++i) { - GpsSatellite otherSatellite = otherSatellites.valueAt(i); - int otherSatellitePrn = otherSatellite.getPrn(); - - int satellitesCount = mSatellites.size(); - while (satelliteIndex < satellitesCount - && mSatellites.valueAt(satelliteIndex).getPrn() < otherSatellitePrn) { - ++satelliteIndex; - } - - if (satelliteIndex < mSatellites.size()) { - GpsSatellite satellite = mSatellites.valueAt(satelliteIndex); - if (satellite.getPrn() == otherSatellitePrn) { - satellite.setStatus(otherSatellite); - } else { - satellite = new GpsSatellite(otherSatellitePrn); - satellite.setStatus(otherSatellite); - mSatellites.put(otherSatellitePrn, satellite); - } - } else { - GpsSatellite satellite = new GpsSatellite(otherSatellitePrn); - satellite.setStatus(otherSatellite); - mSatellites.append(otherSatellitePrn, satellite); - } - } + void setStatus(GnssStatus status, int timeToFirstFix) { + mTimeToFirstFix = timeToFirstFix; + setStatus(status.mSvCount, status.mPrnWithFlags, status.mSnrs, status.mElevations, + status.mAzimuths, status.mConstellationTypes); } void setTimeToFirstFix(int ttff) { diff --git a/location/java/android/location/IGpsStatusListener.aidl b/location/java/android/location/IGnssStatusListener.aidl similarity index 73% rename from location/java/android/location/IGpsStatusListener.aidl rename to location/java/android/location/IGnssStatusListener.aidl index 62b1c6b9b35c1..d1c6a85a9fdd1 100644 --- a/location/java/android/location/IGpsStatusListener.aidl +++ b/location/java/android/location/IGnssStatusListener.aidl @@ -21,13 +21,12 @@ import android.location.Location; /** * {@hide} */ -oneway interface IGpsStatusListener +oneway interface IGnssStatusListener { - void onGpsStarted(); - void onGpsStopped(); + void onGnssStarted(); + void onGnssStopped(); void onFirstFix(int ttff); - void onSvStatusChanged(int svCount, in int[] prns, in float[] snrs, - in float[] elevations, in float[] azimuths, - int ephemerisMask, int almanacMask, int usedInFixMask); + void onSvStatusChanged(int svCount, in int[] prnWithFlags, in float[] snrs, + in float[] elevations, in float[] azimuths, in int[] constellationTypes); void onNmeaReceived(long timestamp, String nmea); } diff --git a/location/java/android/location/IGpsStatusProvider.aidl b/location/java/android/location/IGnssStatusProvider.aidl similarity index 69% rename from location/java/android/location/IGpsStatusProvider.aidl rename to location/java/android/location/IGnssStatusProvider.aidl index cf277c8c5d01d..006b5d3c0c20a 100644 --- a/location/java/android/location/IGpsStatusProvider.aidl +++ b/location/java/android/location/IGnssStatusProvider.aidl @@ -16,14 +16,14 @@ package android.location; -import android.location.IGpsStatusListener; +import android.location.IGnssStatusListener; /** - * An interface for location providers that provide GPS status information. + * An interface for location providers that provide GNSS status information. * * {@hide} */ -interface IGpsStatusProvider { - void addGpsStatusListener(IGpsStatusListener listener); - void removeGpsStatusListener(IGpsStatusListener listener); +interface IGnssStatusProvider { + void registerGnssStatusCallback(IGnssStatusListener callback); + void unregisterGnssStatusCallback(IGnssStatusListener callback); } diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl index f3d755ce34e87..49d841fb11169 100644 --- a/location/java/android/location/ILocationManager.aidl +++ b/location/java/android/location/ILocationManager.aidl @@ -21,9 +21,9 @@ import android.location.Address; import android.location.Criteria; import android.location.GeocoderParams; import android.location.Geofence; +import android.location.IGnssStatusListener; import android.location.IGpsMeasurementsListener; import android.location.IGpsNavigationMessageListener; -import android.location.IGpsStatusListener; import android.location.ILocationListener; import android.location.Location; import android.location.LocationRequest; @@ -48,8 +48,8 @@ interface ILocationManager Location getLastLocation(in LocationRequest request, String packageName); - boolean addGpsStatusListener(IGpsStatusListener listener, String packageName); - void removeGpsStatusListener(IGpsStatusListener listener); + boolean registerGnssStatusCallback(IGnssStatusListener callback, String packageName); + void unregisterGnssStatusCallback(IGnssStatusListener callback); boolean geocoderIsPresent(); String getFromLocation(double latitude, double longitude, int maxResults, @@ -69,6 +69,8 @@ interface ILocationManager in String packageName); void removeGpsNavigationMessageListener(in IGpsNavigationMessageListener listener); + int getGpsYearOfHardware(); + // --- deprecated --- List getAllProviders(); List getProviders(in Criteria criteria, boolean enabledOnly); diff --git a/location/java/android/location/LocalListenerHelper.java b/location/java/android/location/LocalListenerHelper.java index 458c451c61238..d7d2c5131606b 100644 --- a/location/java/android/location/LocalListenerHelper.java +++ b/location/java/android/location/LocalListenerHelper.java @@ -20,12 +20,14 @@ import com.android.internal.util.Preconditions; import android.annotation.NonNull; import android.content.Context; +import android.os.Handler; import android.os.RemoteException; import android.util.Log; import java.util.ArrayList; import java.util.Collection; -import java.util.HashSet; +import java.util.HashMap; +import java.util.Map; /** * A base handler class to manage transport and local listeners. @@ -33,7 +35,7 @@ import java.util.HashSet; * @hide */ abstract class LocalListenerHelper { - private final HashSet mListeners = new HashSet<>(); + private final HashMap mListeners = new HashMap<>(); private final String mTag; private final Context mContext; @@ -44,7 +46,7 @@ abstract class LocalListenerHelper { mTag = name; } - public boolean add(@NonNull TListener listener) { + public boolean add(@NonNull TListener listener, Handler handler) { Preconditions.checkNotNull(listener); synchronized (mListeners) { // we need to register with the service first, because we need to find out if the @@ -62,17 +64,19 @@ abstract class LocalListenerHelper { return false; } } - if (mListeners.contains(listener)) { + if (mListeners.containsKey(listener)) { return true; } - return mListeners.add(listener); + mListeners.put(listener, handler); + return true; } } public void remove(@NonNull TListener listener) { Preconditions.checkNotNull(listener); synchronized (mListeners) { - boolean removed = mListeners.remove(listener); + boolean removed = mListeners.containsKey(listener); + mListeners.remove(listener); boolean isLastRemoved = removed && mListeners.isEmpty(); if (isLastRemoved) { try { @@ -95,17 +99,30 @@ abstract class LocalListenerHelper { return mContext; } - protected void foreach(ListenerOperation operation) { - Collection listeners; - synchronized (mListeners) { - listeners = new ArrayList<>(mListeners); + private void executeOperation(ListenerOperation operation, TListener listener) { + try { + operation.execute(listener); + } catch (RemoteException e) { + Log.e(mTag, "Error in monitored listener.", e); + // don't return, give a fair chance to all listeners to receive the event } - for (TListener listener : listeners) { - try { - operation.execute(listener); - } catch (RemoteException e) { - Log.e(mTag, "Error in monitored listener.", e); - // don't return, give a fair chance to all listeners to receive the event + } + + protected void foreach(final ListenerOperation operation) { + Collection> listeners; + synchronized (mListeners) { + listeners = new ArrayList<>(mListeners.entrySet()); + } + for (final Map.Entry listener : listeners) { + if (listener.getValue() == null) { + executeOperation(operation, listener.getKey()); + } else { + listener.getValue().post(new Runnable() { + @Override + public void run() { + executeOperation(operation, listener.getKey()); + } + }); } } } diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 2c1932439584c..5447bb13707f6 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -20,6 +20,7 @@ import com.android.internal.location.ProviderProperties; import android.annotation.RequiresPermission; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; @@ -63,13 +64,18 @@ public class LocationManager { private final Context mContext; private final ILocationManager mService; - private final GpsMeasurementListenerTransport mGpsMeasurementListenerTransport; - private final GpsNavigationMessageListenerTransport mGpsNavigationMessageListenerTransport; - private final HashMap mGpsStatusListeners = - new HashMap(); - private final HashMap mNmeaListeners = - new HashMap(); - private final GpsStatus mGpsStatus = new GpsStatus(); + private final GpsMeasurementCallbackTransport mGpsMeasurementCallbackTransport; + private final GpsNavigationMessageCallbackTransport mGpsNavigationMessageCallbackTransport; + private final HashMap mGpsStatusListeners = + new HashMap<>(); + private final HashMap mGpsNmeaListeners = + new HashMap<>(); + private final HashMap mGnssStatusListeners = + new HashMap<>(); + private final HashMap mGnssNmeaListeners = + new HashMap<>(); + private GnssStatus mGnssStatus; + private int mTimeToFirstFix; /** * Name of the network location provider. @@ -315,9 +321,9 @@ public class LocationManager { public LocationManager(Context context, ILocationManager service) { mService = service; mContext = context; - mGpsMeasurementListenerTransport = new GpsMeasurementListenerTransport(mContext, mService); - mGpsNavigationMessageListenerTransport = - new GpsNavigationMessageListenerTransport(mContext, mService); + mGpsMeasurementCallbackTransport = new GpsMeasurementCallbackTransport(mContext, mService); + mGpsNavigationMessageCallbackTransport = + new GpsNavigationMessageCallbackTransport(mContext, mService); } private LocationProvider createProvider(String name, ProviderProperties properties) { @@ -1389,11 +1395,51 @@ public class LocationManager { // --- GPS-specific support --- - // This class is used to send GPS status events to the client's main thread. - private class GpsStatusListenerTransport extends IGpsStatusListener.Stub { + // This class is used to send Gnss status events to the client's specific thread. + private class GnssStatusListenerTransport extends IGnssStatusListener.Stub { - private final GpsStatus.Listener mListener; - private final GpsStatus.NmeaListener mNmeaListener; + private final GpsStatus.Listener mGpsListener; + private final GpsStatus.NmeaListener mGpsNmeaListener; + private final GnssStatusCallback mGnssCallback; + private final GnssNmeaListener mGnssNmeaListener; + + private class GnssHandler extends Handler { + public GnssHandler(Handler handler) { + super(handler != null ? handler.getLooper() : Looper.myLooper()); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case NMEA_RECEIVED: + synchronized (mNmeaBuffer) { + int length = mNmeaBuffer.size(); + for (int i = 0; i < length; i++) { + Nmea nmea = mNmeaBuffer.get(i); + mGnssNmeaListener.onNmeaReceived(nmea.mTimestamp, nmea.mNmea); + } + mNmeaBuffer.clear(); + } + break; + case GpsStatus.GPS_EVENT_STARTED: + mGnssCallback.onStarted(); + break; + case GpsStatus.GPS_EVENT_STOPPED: + mGnssCallback.onStopped(); + break; + case GpsStatus.GPS_EVENT_FIRST_FIX: + mGnssCallback.onFirstFix(mTimeToFirstFix); + break; + case GpsStatus.GPS_EVENT_SATELLITE_STATUS: + mGnssCallback.onSatelliteStatusChanged(mGnssStatus); + break; + default: + break; + } + } + } + + private final Handler mGnssHandler; // This must not equal any of the GpsStatus event IDs private static final int NMEA_RECEIVED = 1000; @@ -1407,97 +1453,141 @@ public class LocationManager { mNmea = nmea; } } - private ArrayList mNmeaBuffer; + private final ArrayList mNmeaBuffer; - GpsStatusListenerTransport(GpsStatus.Listener listener) { - mListener = listener; - mNmeaListener = null; + GnssStatusListenerTransport(GpsStatus.Listener listener) { + this(listener, null); } - GpsStatusListenerTransport(GpsStatus.NmeaListener listener) { - mNmeaListener = listener; - mListener = null; + GnssStatusListenerTransport(GpsStatus.Listener listener, Handler handler) { + mGpsListener = listener; + mGnssHandler = new GnssHandler(handler); + mGpsNmeaListener = null; + mNmeaBuffer = null; + mGnssCallback = new GnssStatusCallback() { + @Override + public void onStarted() { + mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STARTED); + } + + @Override + public void onStopped() { + mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STOPPED); + } + + @Override + public void onFirstFix(int ttff) { + mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_FIRST_FIX); + } + + @Override + public void onSatelliteStatusChanged(GnssStatus status) { + mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_SATELLITE_STATUS); + } + }; + mGnssNmeaListener = null; + } + + GnssStatusListenerTransport(GpsStatus.NmeaListener listener) { + this(listener, null); + } + + GnssStatusListenerTransport(GpsStatus.NmeaListener listener, Handler handler) { + mGpsListener = null; + mGnssHandler = new GnssHandler(handler); + mGpsNmeaListener = listener; + mNmeaBuffer = new ArrayList(); + mGnssCallback = null; + mGnssNmeaListener = new GnssNmeaListener() { + @Override + public void onNmeaReceived(long timestamp, String nmea) { + mGpsNmeaListener.onNmeaReceived(timestamp, nmea); + } + }; + } + + GnssStatusListenerTransport(GnssStatusCallback callback) { + this(callback, null); + } + + GnssStatusListenerTransport(GnssStatusCallback callback, Handler handler) { + mGnssCallback = callback; + mGnssHandler = new GnssHandler(handler); + mGnssNmeaListener = null; + mNmeaBuffer = null; + mGpsListener = null; + mGpsNmeaListener = null; + } + + GnssStatusListenerTransport(GnssNmeaListener listener) { + this(listener, null); + } + + GnssStatusListenerTransport(GnssNmeaListener listener, Handler handler) { + mGnssCallback = null; + mGnssHandler = new GnssHandler(handler); + mGnssNmeaListener = listener; + mGpsListener = null; + mGpsNmeaListener = null; mNmeaBuffer = new ArrayList(); } @Override - public void onGpsStarted() { - if (mListener != null) { + public void onGnssStarted() { + if (mGpsListener != null) { Message msg = Message.obtain(); msg.what = GpsStatus.GPS_EVENT_STARTED; - mGpsHandler.sendMessage(msg); + mGnssHandler.sendMessage(msg); } } @Override - public void onGpsStopped() { - if (mListener != null) { + public void onGnssStopped() { + if (mGpsListener != null) { Message msg = Message.obtain(); msg.what = GpsStatus.GPS_EVENT_STOPPED; - mGpsHandler.sendMessage(msg); + mGnssHandler.sendMessage(msg); } } @Override public void onFirstFix(int ttff) { - if (mListener != null) { - mGpsStatus.setTimeToFirstFix(ttff); + if (mGpsListener != null) { + mTimeToFirstFix = ttff; Message msg = Message.obtain(); msg.what = GpsStatus.GPS_EVENT_FIRST_FIX; - mGpsHandler.sendMessage(msg); + mGnssHandler.sendMessage(msg); } } @Override - public void onSvStatusChanged(int svCount, int[] prns, float[] snrs, - float[] elevations, float[] azimuths, int ephemerisMask, - int almanacMask, int usedInFixMask) { - if (mListener != null) { - mGpsStatus.setStatus(svCount, prns, snrs, elevations, azimuths, - ephemerisMask, almanacMask, usedInFixMask); + public void onSvStatusChanged(int svCount, int[] prnWithFlags, + float[] snrs, float[] elevations, float[] azimuths, int[] constellationTypes) { + if (mGnssCallback != null) { + mGnssStatus = new GnssStatus(svCount, prnWithFlags, snrs, elevations, azimuths, + constellationTypes); Message msg = Message.obtain(); msg.what = GpsStatus.GPS_EVENT_SATELLITE_STATUS; // remove any SV status messages already in the queue - mGpsHandler.removeMessages(GpsStatus.GPS_EVENT_SATELLITE_STATUS); - mGpsHandler.sendMessage(msg); + mGnssHandler.removeMessages(GpsStatus.GPS_EVENT_SATELLITE_STATUS); + mGnssHandler.sendMessage(msg); } } @Override public void onNmeaReceived(long timestamp, String nmea) { - if (mNmeaListener != null) { + if (mGnssNmeaListener != null) { synchronized (mNmeaBuffer) { mNmeaBuffer.add(new Nmea(timestamp, nmea)); } Message msg = Message.obtain(); msg.what = NMEA_RECEIVED; // remove any NMEA_RECEIVED messages already in the queue - mGpsHandler.removeMessages(NMEA_RECEIVED); - mGpsHandler.sendMessage(msg); + mGnssHandler.removeMessages(NMEA_RECEIVED); + mGnssHandler.sendMessage(msg); } } - - private final Handler mGpsHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - if (msg.what == NMEA_RECEIVED) { - synchronized (mNmeaBuffer) { - int length = mNmeaBuffer.size(); - for (int i = 0; i < length; i++) { - Nmea nmea = mNmeaBuffer.get(i); - mNmeaListener.onNmeaReceived(nmea.mTimestamp, nmea.mNmea); - } - mNmeaBuffer.clear(); - } - } else { - // synchronize on mGpsStatus to ensure the data is copied atomically. - synchronized(mGpsStatus) { - mListener.onGpsStatusChanged(msg.what); - } - } - } - }; } /** @@ -1508,7 +1598,9 @@ public class LocationManager { * @return true if the listener was successfully added * * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present + * @deprecated use {@link #registerGnssStatusCallback(GnssStatusCallback)} instead. */ + @Deprecated @RequiresPermission(ACCESS_FINE_LOCATION) public boolean addGpsStatusListener(GpsStatus.Listener listener) { boolean result; @@ -1518,8 +1610,8 @@ public class LocationManager { return true; } try { - GpsStatusListenerTransport transport = new GpsStatusListenerTransport(listener); - result = mService.addGpsStatusListener(transport, mContext.getPackageName()); + GnssStatusListenerTransport transport = new GnssStatusListenerTransport(listener); + result = mService.registerGnssStatusCallback(transport, mContext.getPackageName()); if (result) { mGpsStatusListeners.put(listener, transport); } @@ -1536,17 +1628,81 @@ public class LocationManager { * * @param listener GPS status listener object to remove */ + @Deprecated public void removeGpsStatusListener(GpsStatus.Listener listener) { try { - GpsStatusListenerTransport transport = mGpsStatusListeners.remove(listener); + GnssStatusListenerTransport transport = mGpsStatusListeners.remove(listener); if (transport != null) { - mService.removeGpsStatusListener(transport); + mService.unregisterGnssStatusCallback(transport); } } catch (RemoteException e) { Log.e(TAG, "RemoteException in unregisterGpsStatusListener: ", e); } } + + /** + * Registers a GNSS status listener. + * + * @param callback GNSS status listener object to register + * + * @return true if the listener was successfully added + * + * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present + */ + @RequiresPermission(ACCESS_FINE_LOCATION) + public boolean registerGnssStatusCallback(GnssStatusCallback callback) { + return registerGnssStatusCallback(callback, null); + } + + /** + * Registers a GNSS status listener. + * + * @param callback GNSS status listener object to register + * @param handler the handler that the callback runs on. + * + * @return true if the listener was successfully added + * + * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present + */ + @RequiresPermission(ACCESS_FINE_LOCATION) + public boolean registerGnssStatusCallback(GnssStatusCallback callback, Handler handler) { + boolean result; + if (mGnssStatusListeners.get(callback) != null) { + // listener is already registered + return true; + } + try { + GnssStatusListenerTransport transport = + new GnssStatusListenerTransport(callback, handler); + result = mService.registerGnssStatusCallback(transport, mContext.getPackageName()); + if (result) { + mGnssStatusListeners.put(callback, transport); + } + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in registerGnssStatusCallback: ", e); + result = false; + } + + return result; + } + + /** + * Removes a GNSS status listener. + * + * @param callback GNSS status listener object to remove + */ + public void unregisterGnssStatusCallback(GnssStatusCallback callback) { + try { + GnssStatusListenerTransport transport = mGnssStatusListeners.remove(callback); + if (transport != null) { + mService.unregisterGnssStatusCallback(transport); + } + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in unregisterGnssStatusCallback: ", e); + } + } + /** * Adds an NMEA listener. * @@ -1555,20 +1711,22 @@ public class LocationManager { * @return true if the listener was successfully added * * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present + * @deprecated use {@link #addNmeaListener(GnssNmeaListener)} instead. */ + @Deprecated @RequiresPermission(ACCESS_FINE_LOCATION) public boolean addNmeaListener(GpsStatus.NmeaListener listener) { boolean result; - if (mNmeaListeners.get(listener) != null) { + if (mGpsNmeaListeners.get(listener) != null) { // listener is already registered return true; } try { - GpsStatusListenerTransport transport = new GpsStatusListenerTransport(listener); - result = mService.addGpsStatusListener(transport, mContext.getPackageName()); + GnssStatusListenerTransport transport = new GnssStatusListenerTransport(listener); + result = mService.registerGnssStatusCallback(transport, mContext.getPackageName()); if (result) { - mNmeaListeners.put(listener, transport); + mGpsNmeaListeners.put(listener, transport); } } catch (RemoteException e) { Log.e(TAG, "RemoteException in registerGpsStatusListener: ", e); @@ -1583,11 +1741,12 @@ public class LocationManager { * * @param listener a {@link GpsStatus.NmeaListener} object to remove */ + @Deprecated public void removeNmeaListener(GpsStatus.NmeaListener listener) { try { - GpsStatusListenerTransport transport = mNmeaListeners.remove(listener); + GnssStatusListenerTransport transport = mGpsNmeaListeners.remove(listener); if (transport != null) { - mService.removeGpsStatusListener(transport); + mService.unregisterGnssStatusCallback(transport); } } catch (RemoteException e) { Log.e(TAG, "RemoteException in unregisterGpsStatusListener: ", e); @@ -1595,54 +1754,133 @@ public class LocationManager { } /** - * Adds a GPS Measurement listener. + * Adds an NMEA listener. * - * @param listener a {@link GpsMeasurementsEvent.Listener} object to register. - * @return {@code true} if the listener was added successfully, {@code false} otherwise. + * @param listener a {@link GnssNmeaListener} object to register * - * @hide + * @return true if the listener was successfully added + * + * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present */ - @SystemApi - public boolean addGpsMeasurementListener(GpsMeasurementsEvent.Listener listener) { - return mGpsMeasurementListenerTransport.add(listener); + @RequiresPermission(ACCESS_FINE_LOCATION) + public boolean addNmeaListener(GnssNmeaListener listener) { + return addNmeaListener(listener, null); } /** - * Removes a GPS Measurement listener. + * Adds an NMEA listener. * - * @param listener a {@link GpsMeasurementsEvent.Listener} object to remove. + * @param listener a {@link GnssNmeaListener} object to register + * @param handler the handler that the listener runs on. * - * @hide + * @return true if the listener was successfully added + * + * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present */ - @SystemApi - public void removeGpsMeasurementListener(GpsMeasurementsEvent.Listener listener) { - mGpsMeasurementListenerTransport.remove(listener); + @RequiresPermission(ACCESS_FINE_LOCATION) + public boolean addNmeaListener(GnssNmeaListener listener, Handler handler) { + boolean result; + + if (mGpsNmeaListeners.get(listener) != null) { + // listener is already registered + return true; + } + try { + GnssStatusListenerTransport transport = + new GnssStatusListenerTransport(listener, handler); + result = mService.registerGnssStatusCallback(transport, mContext.getPackageName()); + if (result) { + mGnssNmeaListeners.put(listener, transport); + } + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in registerGnssStatusCallback: ", e); + result = false; + } + + return result; } /** - * Adds a GPS Navigation Message listener. + * Removes an NMEA listener. * - * @param listener a {@link GpsNavigationMessageEvent.Listener} object to register. - * @return {@code true} if the listener was added successfully, {@code false} otherwise. - * - * @hide + * @param listener a {@link GnssNmeaListener} object to remove */ - @SystemApi - public boolean addGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) { - return mGpsNavigationMessageListenerTransport.add(listener); + public void removeNmeaListener(GnssNmeaListener listener) { + try { + GnssStatusListenerTransport transport = mGnssNmeaListeners.remove(listener); + if (transport != null) { + mService.unregisterGnssStatusCallback(transport); + } + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in unregisterGnssStatusCallback: ", e); + } } /** - * Removes a GPS Navigation Message listener. + * Registers a GPS Measurement callback. * - * @param listener a {@link GpsNavigationMessageEvent.Listener} object to remove. - * - * @hide + * @param callback a {@link GpsMeasurementsEvent.Callback} object to register. + * @return {@code true} if the callback was added successfully, {@code false} otherwise. */ - @SystemApi - public void removeGpsNavigationMessageListener( - GpsNavigationMessageEvent.Listener listener) { - mGpsNavigationMessageListenerTransport.remove(listener); + @RequiresPermission(ACCESS_FINE_LOCATION) + public boolean registerGpsMeasurementCallback(GpsMeasurementsEvent.Callback callback) { + return registerGpsMeasurementCallback(callback, null); + } + + /** + * Registers a GPS Measurement callback. + * + * @param callback a {@link GpsMeasurementsEvent.Callback} object to register. + * @param handler the handler that the callback runs on. + * @return {@code true} if the callback was added successfully, {@code false} otherwise. + */ + @RequiresPermission(ACCESS_FINE_LOCATION) + public boolean registerGpsMeasurementCallback(GpsMeasurementsEvent.Callback callback, + Handler handler) { + return mGpsMeasurementCallbackTransport.add(callback, handler); + } + + /** + * Unregisters a GPS Measurement callback. + * + * @param callback a {@link GpsMeasurementsEvent.Callback} object to remove. + */ + public void unregisterGpsMeasurementCallback(GpsMeasurementsEvent.Callback callback) { + mGpsMeasurementCallbackTransport.remove(callback); + } + + /** + * Registers a GPS Navigation Message callback. + * + * @param callback a {@link GpsNavigationMessageEvent.Callback} object to register. + * @return {@code true} if the callback was added successfully, {@code false} otherwise. + */ + public boolean registerGpsNavigationMessageCallback( + GpsNavigationMessageEvent.Callback callback) { + return registerGpsNavigationMessageCallback(callback, null); + } + + /** + * Registers a GPS Navigation Message callback. + * + * @param callback a {@link GpsNavigationMessageEvent.Callback} object to register. + * @param handler the handler that the callback runs on. + * @return {@code true} if the callback was added successfully, {@code false} otherwise. + */ + @RequiresPermission(ACCESS_FINE_LOCATION) + public boolean registerGpsNavigationMessageCallback( + GpsNavigationMessageEvent.Callback callback, Handler handler) { + return mGpsNavigationMessageCallbackTransport.add(callback, handler); + } + + /** + * Unregisters a GPS Navigation Message callback. + * + * @param callback a {@link GpsNavigationMessageEvent.Callback} object to remove. + */ + public void unregisterGpsNavigationMessageCallback( + GpsNavigationMessageEvent.Callback callback) { + mGpsNavigationMessageCallbackTransport.remove(callback); } /** @@ -1656,14 +1894,35 @@ public class LocationManager { * @param status object containing GPS status details, or null. * @return status object containing updated GPS status. */ + @Deprecated + @RequiresPermission(ACCESS_FINE_LOCATION) public GpsStatus getGpsStatus(GpsStatus status) { if (status == null) { status = new GpsStatus(); } - status.setStatus(mGpsStatus); + // When mGnssStatus is null, that means that this method is called outside + // onGpsStatusChanged(). Return an empty status to maintain backwards compatibility. + if (mGnssStatus != null) { + status.setStatus(mGnssStatus, mTimeToFirstFix); + } return status; } + /** + * Returns the system information of the GPS hardware. + * May return 0 if GPS hardware is earlier than 2016. + * @hide + */ + @TestApi + public int getGpsYearOfHardware() { + try { + return mService.getGpsYearOfHardware(); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in getGpsSystemInfo: ", e); + return 0; + } + } + /** * Sends additional commands to a location provider. * Can be used to support provider specific extensions to the Location Manager API diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java index 260f380d93e90..93e86afe2589c 100644 --- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java +++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java @@ -62,7 +62,7 @@ public class GpsNetInitiatedHandler { public static final String NI_INTENT_KEY_TIMEOUT = "timeout"; public static final String NI_INTENT_KEY_DEFAULT_RESPONSE = "default_resp"; - // the extra command to send NI response to GpsLocationProvider + // the extra command to send NI response to GnssLocationProvider public static final String NI_RESPONSE_EXTRA_CMD = "send_ni_response"; // the extra command parameter names in the Bundle diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java index 9405d8e05c5e7..c55c5b61c9995 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java @@ -24,10 +24,10 @@ import com.android.internal.os.BackgroundThread; import com.android.server.location.ActivityRecognitionProxy; import com.android.server.location.FlpHardwareProvider; import com.android.server.location.FusedProxy; +import com.android.server.location.GnssLocationProvider; import com.android.server.location.GeocoderProxy; import com.android.server.location.GeofenceManager; import com.android.server.location.GeofenceProxy; -import com.android.server.location.GpsLocationProvider; import com.android.server.location.GpsMeasurementsProvider; import com.android.server.location.GpsNavigationMessageProvider; import com.android.server.location.LocationBlacklist; @@ -61,11 +61,11 @@ import android.location.Address; import android.location.Criteria; import android.location.GeocoderParams; import android.location.Geofence; +import android.location.IGnssStatusListener; +import android.location.IGnssStatusProvider; import android.location.IGpsGeofenceHardware; import android.location.IGpsMeasurementsListener; import android.location.IGpsNavigationMessageListener; -import android.location.IGpsStatusListener; -import android.location.IGpsStatusProvider; import android.location.ILocationListener; import android.location.ILocationManager; import android.location.INetInitiatedListener; @@ -157,7 +157,7 @@ public class LocationManagerService extends ILocationManager.Stub { private PowerManager mPowerManager; private UserManager mUserManager; private GeocoderProxy mGeocodeProvider; - private IGpsStatusProvider mGpsStatusProvider; + private IGnssStatusProvider mGnssStatusProvider; private INetInitiatedListener mNetInitiatedListener; private LocationWorkerHandler mLocationHandler; private PassiveProvider mPassiveProvider; // track passive provider for special cases @@ -214,6 +214,8 @@ public class LocationManagerService extends ILocationManager.Stub { private int mCurrentUserId = UserHandle.USER_SYSTEM; private int[] mCurrentUserProfiles = new int[] { UserHandle.USER_SYSTEM }; + private GnssLocationProvider.GpsSystemInfoProvider mGpsSystemInfoProvider; + public LocationManagerService(Context context) { super(); mContext = context; @@ -456,17 +458,18 @@ public class LocationManagerService extends ILocationManager.Stub { mEnabledProviders.add(passiveProvider.getName()); mPassiveProvider = passiveProvider; - if (GpsLocationProvider.isSupported()) { + if (GnssLocationProvider.isSupported()) { // Create a gps location provider - GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this, + GnssLocationProvider gnssProvider = new GnssLocationProvider(mContext, this, mLocationHandler.getLooper()); - mGpsStatusProvider = gpsProvider.getGpsStatusProvider(); - mNetInitiatedListener = gpsProvider.getNetInitiatedListener(); - addProviderLocked(gpsProvider); - mRealProviders.put(LocationManager.GPS_PROVIDER, gpsProvider); - mGpsMeasurementsProvider = gpsProvider.getGpsMeasurementsProvider(); - mGpsNavigationMessageProvider = gpsProvider.getGpsNavigationMessageProvider(); - mGpsGeofenceProxy = gpsProvider.getGpsGeofenceProxy(); + mGpsSystemInfoProvider = gnssProvider.getGpsSystemInfoProvider(); + mGnssStatusProvider = gnssProvider.getGnssStatusProvider(); + mNetInitiatedListener = gnssProvider.getNetInitiatedListener(); + addProviderLocked(gnssProvider); + mRealProviders.put(LocationManager.GPS_PROVIDER, gnssProvider); + mGpsMeasurementsProvider = gnssProvider.getGpsMeasurementsProvider(); + mGpsNavigationMessageProvider = gnssProvider.getGpsNavigationMessageProvider(); + mGpsGeofenceProxy = gnssProvider.getGpsGeofenceProxy(); } /* @@ -986,6 +989,18 @@ public class LocationManagerService extends ILocationManager.Stub { } } + /** + * Returns the system information of the GPS hardware. + */ + @Override + public int getGpsYearOfHardware() { + if (mGpsNavigationMessageProvider != null) { + return mGpsSystemInfoProvider.getGpsYearOfHardware(); + } else { + return 0; + } + } + private void addProviderLocked(LocationProviderInterface provider) { mProviders.add(provider); mProvidersByName.put(provider.getName(), provider); @@ -1867,7 +1882,7 @@ public class LocationManagerService extends ILocationManager.Stub { @Override - public boolean addGpsStatusListener(IGpsStatusListener listener, String packageName) { + public boolean registerGnssStatusCallback(IGnssStatusListener callback, String packageName) { int allowedResolutionLevel = getCallerAllowedResolutionLevel(); checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, LocationManager.GPS_PROVIDER); @@ -1883,26 +1898,26 @@ public class LocationManagerService extends ILocationManager.Stub { Binder.restoreCallingIdentity(ident); } - if (mGpsStatusProvider == null) { + if (mGnssStatusProvider == null) { return false; } try { - mGpsStatusProvider.addGpsStatusListener(listener); + mGnssStatusProvider.registerGnssStatusCallback(callback); } catch (RemoteException e) { - Slog.e(TAG, "mGpsStatusProvider.addGpsStatusListener failed", e); + Slog.e(TAG, "mGpsStatusProvider.registerGnssStatusCallback failed", e); return false; } return true; } @Override - public void removeGpsStatusListener(IGpsStatusListener listener) { + public void unregisterGnssStatusCallback(IGnssStatusListener callback) { synchronized (mLock) { try { - mGpsStatusProvider.removeGpsStatusListener(listener); + mGnssStatusProvider.unregisterGnssStatusCallback(callback); } catch (Exception e) { - Slog.e(TAG, "mGpsStatusProvider.removeGpsStatusListener failed", e); + Slog.e(TAG, "mGpsStatusProvider.unregisterGnssStatusCallback failed", e); } } } diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java similarity index 96% rename from services/core/java/com/android/server/location/GpsLocationProvider.java rename to services/core/java/com/android/server/location/GnssLocationProvider.java index 88ab2c65e979e..9798e56237e54 100644 --- a/services/core/java/com/android/server/location/GpsLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -35,11 +35,12 @@ import android.hardware.location.GeofenceHardware; import android.hardware.location.GeofenceHardwareImpl; import android.location.Criteria; import android.location.FusedBatchOptions; +import android.location.GnssStatus; +import android.location.IGnssStatusListener; +import android.location.IGnssStatusProvider; import android.location.GpsMeasurementsEvent; import android.location.GpsNavigationMessageEvent; import android.location.IGpsGeofenceHardware; -import android.location.IGpsStatusListener; -import android.location.IGpsStatusProvider; import android.location.ILocationManager; import android.location.INetInitiatedListener; import android.location.Location; @@ -100,9 +101,9 @@ import libcore.io.IoUtils; * * {@hide} */ -public class GpsLocationProvider implements LocationProviderInterface { +public class GnssLocationProvider implements LocationProviderInterface { - private static final String TAG = "GpsLocationProvider"; + private static final String TAG = "GnssLocationProvider"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE); @@ -366,7 +367,7 @@ public class GpsLocationProvider implements LocationProviderInterface { private final ILocationManager mILocationManager; private Location mLocation = new Location(LocationManager.GPS_PROVIDER); private Bundle mLocationExtras = new Bundle(); - private final GpsStatusListenerHelper mListenerHelper; + private final GnssStatusListenerHelper mListenerHelper; private final GpsMeasurementsProvider mGpsMeasurementsProvider; private final GpsNavigationMessageProvider mGpsNavigationMessageProvider; @@ -382,7 +383,7 @@ public class GpsLocationProvider implements LocationProviderInterface { private final GpsNetInitiatedHandler mNIHandler; // Wakelocks - private final static String WAKELOCK_KEY = "GpsLocationProvider"; + private final static String WAKELOCK_KEY = "GnssLocationProvider"; private final PowerManager.WakeLock mWakeLock; // Alarms @@ -405,20 +406,22 @@ public class GpsLocationProvider implements LocationProviderInterface { private GeofenceHardwareImpl mGeofenceHardwareImpl; - private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() { + private int mYearOfHardware = 0; + + private final IGnssStatusProvider mGnssStatusProvider = new IGnssStatusProvider.Stub() { @Override - public void addGpsStatusListener(IGpsStatusListener listener) { - mListenerHelper.addListener(listener); + public void registerGnssStatusCallback(IGnssStatusListener callback) { + mListenerHelper.addListener(callback); } @Override - public void removeGpsStatusListener(IGpsStatusListener listener) { - mListenerHelper.removeListener(listener); + public void unregisterGnssStatusCallback(IGnssStatusListener callback) { + mListenerHelper.removeListener(callback); } }; - public IGpsStatusProvider getGpsStatusProvider() { - return mGpsStatusProvider; + public IGnssStatusProvider getGnssStatusProvider() { + return mGnssStatusProvider; } public IGpsGeofenceHardware getGpsGeofenceProxy() { @@ -655,7 +658,7 @@ public class GpsLocationProvider implements LocationProviderInterface { return true; } - public GpsLocationProvider(Context context, ILocationManager ilocationManager, + public GnssLocationProvider(Context context, ILocationManager ilocationManager, Looper looper) { mContext = context; mNtpTime = NtpTrustedTime.getInstance(context); @@ -698,7 +701,7 @@ public class GpsLocationProvider implements LocationProviderInterface { mNetInitiatedListener, mSuplEsEnabled); - mListenerHelper = new GpsStatusListenerHelper(mHandler) { + mListenerHelper = new GnssStatusListenerHelper(mHandler) { @Override protected boolean isAvailableInPlatform() { return isSupported(); @@ -1554,34 +1557,40 @@ public class GpsLocationProvider implements LocationProviderInterface { * called from native code to update SV info */ private void reportSvStatus() { - int svCount = native_read_sv_status(mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks); + int svCount = native_read_sv_status(mPrnWithFlags, mSnrs, mSvElevations, mSvAzimuths, + mConstellationTypes); mListenerHelper.onSvStatusChanged( svCount, - mSvs, + mPrnWithFlags, mSnrs, mSvElevations, mSvAzimuths, - mSvMasks[EPHEMERIS_MASK], - mSvMasks[ALMANAC_MASK], - mSvMasks[USED_FOR_FIX_MASK]); + mConstellationTypes); 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] + + Log.v(TAG, "SV count: " + svCount); + } + // Calculate number of sets used in fix. + int usedInFixCount = 0; + for (int i = 0; i < svCount; i++) { + if ((mPrnWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) { + ++usedInFixCount; + } + if (VERBOSE) { + Log.v(TAG, "prn: " + (mPrnWithFlags[i] >> GnssStatus.PRN_SHIFT_WIDTH) + " snr: " + 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")); + ((mPrnWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0 + ? " " : " E") + + ((mPrnWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) == 0 + ? " " : " A") + + ((mPrnWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0 + ? "" : "U")); } } - // return number of sets used in fix instead of total - updateStatus(mStatus, Integer.bitCount(mSvMasks[USED_FOR_FIX_MASK])); + updateStatus(mStatus, usedInFixCount); if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 && System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT) { @@ -1674,6 +1683,33 @@ public class GpsLocationProvider implements LocationProviderInterface { (capabilities & GPS_CAPABILITY_NAV_MESSAGES) == GPS_CAPABILITY_NAV_MESSAGES); } + /** + * Called from native code to inform us the hardware information. + */ + private void setGpsYearOfHardware(int yearOfHardware) { + if (DEBUG) Log.d(TAG, "setGpsYearOfHardware called with " + yearOfHardware); + mYearOfHardware = yearOfHardware; + } + + public interface GpsSystemInfoProvider { + /** + * Returns the year of GPS hardware. + */ + int getGpsYearOfHardware(); + } + + /** + * @hide + */ + public GpsSystemInfoProvider getGpsSystemInfoProvider() { + return new GpsSystemInfoProvider() { + @Override + public int getGpsYearOfHardware() { + return mYearOfHardware; + } + }; + } + /** * called from native code to request XTRA data */ @@ -2067,7 +2103,7 @@ public class GpsLocationProvider implements LocationProviderInterface { } /** - * This method is bound to {@link #GpsLocationProvider(Context, ILocationManager, Looper)}. + * This method is bound to {@link #GnssLocationProvider(Context, ILocationManager, Looper)}. * It is in charge of loading properties and registering for events that will be posted to * this handler. */ @@ -2362,17 +2398,14 @@ public class GpsLocationProvider implements LocationProviderInterface { } // 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; + private static final int MAX_SVS = 512; // preallocated arrays, to avoid memory allocation in reportStatus() - private int mSvs[] = new int[MAX_SVS]; + private int mPrnWithFlags[] = 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 mConstellationTypes[] = new int[MAX_SVS]; private int mSvCount; // preallocated to avoid memory allocation in reportNmea() private byte[] mNmeaBuffer = new byte[120]; @@ -2392,8 +2425,8 @@ public class GpsLocationProvider implements LocationProviderInterface { private native void native_delete_aiding_data(int flags); // 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_sv_status(int[] prnWithFlags, float[] snrs, float[] elevations, + float[] azimuths, int[] constellationTypes); private native int native_read_nmea(byte[] buffer, int bufferSize); private native void native_inject_location(double latitude, double longitude, float accuracy); diff --git a/services/core/java/com/android/server/location/GpsStatusListenerHelper.java b/services/core/java/com/android/server/location/GnssStatusListenerHelper.java similarity index 62% rename from services/core/java/com/android/server/location/GpsStatusListenerHelper.java rename to services/core/java/com/android/server/location/GnssStatusListenerHelper.java index 53ff6c24ae6b7..9840c61ec516d 100644 --- a/services/core/java/com/android/server/location/GpsStatusListenerHelper.java +++ b/services/core/java/com/android/server/location/GnssStatusListenerHelper.java @@ -16,17 +16,17 @@ package com.android.server.location; -import android.location.IGpsStatusListener; +import android.location.IGnssStatusListener; import android.os.Handler; import android.os.RemoteException; /** - * Implementation of a handler for {@link IGpsStatusListener}. + * Implementation of a handler for {@link IGnssStatusListener}. */ -abstract class GpsStatusListenerHelper extends RemoteListenerHelper { - protected GpsStatusListenerHelper(Handler handler) { - super(handler, "GpsStatusListenerHelper"); - setSupported(GpsLocationProvider.isSupported()); +abstract class GnssStatusListenerHelper extends RemoteListenerHelper { + protected GnssStatusListenerHelper(Handler handler) { + super(handler, "GnssStatusListenerHelper"); + setSupported(GnssLocationProvider.isSupported()); } @Override @@ -38,7 +38,7 @@ abstract class GpsStatusListenerHelper extends RemoteListenerHelper getHandlerOperation(int result) { + protected ListenerOperation getHandlerOperation(int result) { return null; } @@ -47,15 +47,15 @@ abstract class GpsStatusListenerHelper extends RemoteListenerHelper {} + private interface Operation extends ListenerOperation {} } diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk index 98d8d086e5117..d1b8648781098 100644 --- a/services/core/jni/Android.mk +++ b/services/core/jni/Android.mk @@ -22,7 +22,7 @@ LOCAL_SRC_FILES += \ $(LOCAL_REL_DIR)/com_android_server_input_InputManagerService.cpp \ $(LOCAL_REL_DIR)/com_android_server_input_InputWindowHandle.cpp \ $(LOCAL_REL_DIR)/com_android_server_lights_LightsService.cpp \ - $(LOCAL_REL_DIR)/com_android_server_location_GpsLocationProvider.cpp \ + $(LOCAL_REL_DIR)/com_android_server_location_GnssLocationProvider.cpp \ $(LOCAL_REL_DIR)/com_android_server_location_FlpHardwareProvider.cpp \ $(LOCAL_REL_DIR)/com_android_server_power_PowerManagerService.cpp \ $(LOCAL_REL_DIR)/com_android_server_SerialService.cpp \ diff --git a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp similarity index 79% rename from services/core/jni/com_android_server_location_GpsLocationProvider.cpp rename to services/core/jni/com_android_server_location_GnssLocationProvider.cpp index b8d4196dad16f..0c85a1578065f 100644 --- a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -14,14 +14,14 @@ * limitations under the License. */ -#define LOG_TAG "GpsLocationProvider" +#define LOG_TAG "GnssLocationProvider" #define LOG_NDEBUG 0 #include "JNIHelp.h" #include "jni.h" #include "hardware/hardware.h" -#include "hardware/gps.h" +#include "hardware/gps_internal.h" #include "hardware_legacy/power.h" #include "utils/Log.h" #include "utils/misc.h" @@ -42,6 +42,7 @@ static jmethodID method_reportSvStatus; static jmethodID method_reportAGpsStatus; static jmethodID method_reportNmea; static jmethodID method_setEngineCapabilities; +static jmethodID method_setGpsYearOfHardware; static jmethodID method_xtraDownloadRequest; static jmethodID method_reportNiNotification; static jmethodID method_requestRefLocation; @@ -67,8 +68,14 @@ static const GpsMeasurementInterface* sGpsMeasurementInterface = NULL; static const GpsNavigationMessageInterface* sGpsNavigationMessageInterface = NULL; static const GnssConfigurationInterface* sGnssConfigurationInterface = NULL; +#define MAX_SATELLITE_COUNT 512 +#define MAX_GPS_SATELLITE_COUNT 512 + +#define PRN_SHIFT_WIDTH 3 + // temporary storage for GPS callbacks -static GpsSvStatus sGpsSvStatus; +static GnssSvInfo sGnssSvList[MAX_SATELLITE_COUNT]; +static size_t sGnssSvListSize; static const char* sNmeaString; static int sNmeaStringLength; @@ -105,7 +112,57 @@ static void status_callback(GpsStatus* status) static void sv_status_callback(GpsSvStatus* sv_status) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - memcpy(&sGpsSvStatus, sv_status, sizeof(sGpsSvStatus)); + size_t status_size = sv_status->size; + // Some drive doesn't set the size field correctly. Assume GpsSvStatus_v1 if + // it doesn't provide a valid size. + if (status_size == 0) { + status_size = sizeof(GpsSvStatus_v1); + } + if (status_size == sizeof(GpsSvStatus)) { + sGnssSvListSize = sv_status->gnss_sv_list_size; + // Cramp the list size + if (sGnssSvListSize > MAX_SATELLITE_COUNT) { + sGnssSvListSize = MAX_SATELLITE_COUNT; + } + // Copy GNSS SV info into sGnssSvList, if any. + if (sGnssSvListSize > 0 && sv_status->gnss_sv_list) { + memcpy(sGnssSvList, sv_status->gnss_sv_list, sizeof(GnssSvInfo) * sGnssSvListSize); + } + } else if (status_size == sizeof(GpsSvStatus_v1)) { + sGnssSvListSize = sv_status->num_svs; + // Cramp the list size + if (sGnssSvListSize > MAX_GPS_SATELLITE_COUNT) { + sGnssSvListSize = MAX_GPS_SATELLITE_COUNT; + } + uint32_t ephemeris_mask = sv_status->ephemeris_mask; + uint32_t almanac_mask = sv_status->almanac_mask; + uint32_t used_in_fix_mask = sv_status->used_in_fix_mask; + for (size_t i = 0; i < sGnssSvListSize; i++) { + GnssSvInfo& info = sGnssSvList[i]; + info.constellation = GNSS_CONSTELLATION_GPS; + info.prn = sv_status->sv_list[i].prn; + info.snr = sv_status->sv_list[i].snr; + info.elevation = sv_status->sv_list[i].elevation; + info.azimuth = sv_status->sv_list[i].azimuth; + info.flags = GNSS_SV_FLAGS_NONE; + if (info.prn > 0 && info.prn <= 32) { + int32_t this_prn_mask = (1 << (info.prn - 1)); + if ((ephemeris_mask & this_prn_mask) != 0) { + info.flags |= GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA; + } + if ((almanac_mask & this_prn_mask) != 0) { + info.flags |= GNSS_SV_FLAGS_HAS_ALMANAC_DATA; + } + if ((used_in_fix_mask & this_prn_mask) != 0) { + info.flags |= GNSS_SV_FLAGS_USED_IN_FIX; + } + } + } + } else { + sGnssSvListSize = 0; + ALOGE("Invalid size of GpsSvStatus found: %zd.", status_size); + return; + } env->CallVoidMethod(mCallbacksObj, method_reportSvStatus); checkAndClearExceptionFromCallback(env, __FUNCTION__); } @@ -121,6 +178,14 @@ static void nmea_callback(GpsUtcTime timestamp, const char* nmea, int length) checkAndClearExceptionFromCallback(env, __FUNCTION__); } +static void set_system_info_callback(const GpsSystemInfo* info) { + ALOGD("set_system_info_callback: year_of_hw=%d\n", info->year_of_hw); + JNIEnv* env = AndroidRuntime::getJNIEnv(); + env->CallVoidMethod(mCallbacksObj, method_setGpsYearOfHardware, + info->year_of_hw); + checkAndClearExceptionFromCallback(env, __FUNCTION__); +} + static void set_capabilities_callback(uint32_t capabilities) { ALOGD("set_capabilities_callback: %du\n", capabilities); @@ -162,6 +227,7 @@ GpsCallbacks sGpsCallbacks = { release_wakelock_callback, create_thread_callback, request_utc_time_callback, + set_system_info_callback, }; static void xtra_download_request_callback() @@ -213,7 +279,7 @@ static void agps_status_callback(AGpsStatus* agps_status) bool isSupported = false; size_t status_size = agps_status->size; - if (status_size == sizeof(AGpsStatus_v3)) { + if (status_size == sizeof(AGpsStatus)) { ALOGV("AGpsStatus is V3: %zd", status_size); switch (agps_status->addr.ss_family) { @@ -439,7 +505,7 @@ GpsGeofenceCallbacks sGpsGeofenceCallbacks = { create_thread_callback, }; -static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) { +static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) { int err; hw_module_t* module; @@ -449,6 +515,7 @@ static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V"); method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V"); method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V"); + method_setGpsYearOfHardware = env->GetMethodID(clazz, "setGpsYearOfHardware", "(I)V"); method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V"); method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification", "(IIIIILjava/lang/String;Ljava/lang/String;IILjava/lang/String;)V"); @@ -509,13 +576,13 @@ static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, } } -static jboolean android_location_GpsLocationProvider_is_supported( +static jboolean android_location_GnssLocationProvider_is_supported( JNIEnv* /* env */, jclass /* clazz */) { return (sGpsInterface != NULL) ? JNI_TRUE : JNI_FALSE; } -static jboolean android_location_GpsLocationProvider_is_agps_ril_supported( +static jboolean android_location_GnssLocationProvider_is_agps_ril_supported( JNIEnv* /* env */, jclass /* clazz */) { return (sAGpsRilInterface != NULL) ? JNI_TRUE : JNI_FALSE; @@ -527,7 +594,7 @@ static jboolean android_location_gpsLocationProvider_is_gnss_configuration_suppo return (sGnssConfigurationInterface != NULL) ? JNI_TRUE : JNI_FALSE; } -static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj) +static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) { // this must be set before calling into the HAL library if (!mCallbacksObj) @@ -553,13 +620,13 @@ static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject o return JNI_TRUE; } -static void android_location_GpsLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) +static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) { if (sGpsInterface) sGpsInterface->cleanup(); } -static jboolean android_location_GpsLocationProvider_set_position_mode(JNIEnv* /* env */, +static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */, jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy, jint preferred_time) { @@ -575,7 +642,7 @@ static jboolean android_location_GpsLocationProvider_set_position_mode(JNIEnv* / return JNI_FALSE; } -static jboolean android_location_GpsLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) +static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) { if (sGpsInterface) { if (sGpsInterface->start() == 0) { @@ -588,7 +655,7 @@ static jboolean android_location_GpsLocationProvider_start(JNIEnv* /* env */, jo return JNI_FALSE; } -static jboolean android_location_GpsLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) +static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) { if (sGpsInterface) { if (sGpsInterface->stop() == 0) { @@ -601,7 +668,7 @@ static jboolean android_location_GpsLocationProvider_stop(JNIEnv* /* env */, job return JNI_FALSE; } -static void android_location_GpsLocationProvider_delete_aiding_data(JNIEnv* /* env */, +static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */, jobject /* obj */, jint flags) { @@ -609,38 +676,36 @@ static void android_location_GpsLocationProvider_delete_aiding_data(JNIEnv* /* e sGpsInterface->delete_aiding_data(flags); } -static jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */, - jintArray prnArray, jfloatArray snrArray, jfloatArray elevArray, jfloatArray azumArray, - jintArray maskArray) +static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */, + jintArray prnWithFlagArray, jfloatArray snrArray, jfloatArray elevArray, + jfloatArray azumArray, jintArray constellationTypeArray) { // this should only be called from within a call to reportSvStatus - - jint* prns = env->GetIntArrayElements(prnArray, 0); + jint* prnWithFlags = env->GetIntArrayElements(prnWithFlagArray, 0); jfloat* snrs = env->GetFloatArrayElements(snrArray, 0); jfloat* elev = env->GetFloatArrayElements(elevArray, 0); jfloat* azim = env->GetFloatArrayElements(azumArray, 0); - jint* mask = env->GetIntArrayElements(maskArray, 0); + jint* constellationTypes = env->GetIntArrayElements(constellationTypeArray, 0); - int num_svs = sGpsSvStatus.num_svs; - for (int i = 0; i < num_svs; i++) { - prns[i] = sGpsSvStatus.sv_list[i].prn; - snrs[i] = sGpsSvStatus.sv_list[i].snr; - elev[i] = sGpsSvStatus.sv_list[i].elevation; - azim[i] = sGpsSvStatus.sv_list[i].azimuth; + // GNSS SV info. + for (size_t i = 0; i < sGnssSvListSize; ++i) { + const GnssSvInfo& info = sGnssSvList[i]; + constellationTypes[i] = info.constellation; + prnWithFlags[i] = (info.prn << PRN_SHIFT_WIDTH) | info.flags; + snrs[i] = info.snr; + elev[i] = info.elevation; + azim[i] = info.azimuth; } - mask[0] = sGpsSvStatus.ephemeris_mask; - mask[1] = sGpsSvStatus.almanac_mask; - mask[2] = sGpsSvStatus.used_in_fix_mask; - env->ReleaseIntArrayElements(prnArray, prns, 0); + env->ReleaseIntArrayElements(prnWithFlagArray, prnWithFlags, 0); env->ReleaseFloatArrayElements(snrArray, snrs, 0); env->ReleaseFloatArrayElements(elevArray, elev, 0); env->ReleaseFloatArrayElements(azumArray, azim, 0); - env->ReleaseIntArrayElements(maskArray, mask, 0); - return (jint) num_svs; + env->ReleaseIntArrayElements(constellationTypeArray, constellationTypes, 0); + return (jint) sGnssSvListSize; } -static void android_location_GpsLocationProvider_agps_set_reference_location_cellid( +static void android_location_GnssLocationProvider_agps_set_reference_location_cellid( JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) { AGpsRefLocation location; @@ -667,7 +732,7 @@ static void android_location_GpsLocationProvider_agps_set_reference_location_cel sAGpsRilInterface->set_ref_location(&location, sizeof(location)); } -static void android_location_GpsLocationProvider_agps_send_ni_message(JNIEnv* env, +static void android_location_GnssLocationProvider_agps_send_ni_message(JNIEnv* env, jobject /* obj */, jbyteArray ni_msg, jint size) { size_t sz; @@ -684,7 +749,7 @@ static void android_location_GpsLocationProvider_agps_send_ni_message(JNIEnv* en env->ReleaseByteArrayElements(ni_msg,b,0); } -static void android_location_GpsLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */, +static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */, jint type, jstring setid_string) { if (!sAGpsRilInterface) { @@ -697,7 +762,7 @@ static void android_location_GpsLocationProvider_agps_set_id(JNIEnv *env, jobjec env->ReleaseStringUTFChars(setid_string, setid); } -static jint android_location_GpsLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */, +static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */, jbyteArray nmeaArray, jint buffer_size) { // this should only be called from within a call to reportNmea @@ -710,27 +775,27 @@ static jint android_location_GpsLocationProvider_read_nmea(JNIEnv* env, jobject return (jint) length; } -static void android_location_GpsLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */, +static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */, jlong time, jlong timeReference, jint uncertainty) { if (sGpsInterface) sGpsInterface->inject_time(time, timeReference, uncertainty); } -static void android_location_GpsLocationProvider_inject_location(JNIEnv* /* env */, +static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */, jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) { if (sGpsInterface) sGpsInterface->inject_location(latitude, longitude, accuracy); } -static jboolean android_location_GpsLocationProvider_supports_xtra( +static jboolean android_location_GnssLocationProvider_supports_xtra( JNIEnv* /* env */, jobject /* obj */) { return (sGpsXtraInterface != NULL) ? JNI_TRUE : JNI_FALSE; } -static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */, +static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */, jbyteArray data, jint length) { if (!sGpsXtraInterface) { @@ -743,7 +808,7 @@ static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, j env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT); } -static void android_location_GpsLocationProvider_agps_data_conn_open( +static void android_location_GnssLocationProvider_agps_data_conn_open( JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) { if (!sAGpsInterface) { @@ -758,7 +823,7 @@ static void android_location_GpsLocationProvider_agps_data_conn_open( const char *apnStr = env->GetStringUTFChars(apn, NULL); size_t interface_size = sAGpsInterface->size; - if (interface_size == sizeof(AGpsInterface_v2)) { + if (interface_size == sizeof(AGpsInterface)) { sAGpsInterface->data_conn_open_with_apn_ip_type(apnStr, apnIpType); } else if (interface_size == sizeof(AGpsInterface_v1)) { sAGpsInterface->data_conn_open(apnStr); @@ -769,7 +834,7 @@ static void android_location_GpsLocationProvider_agps_data_conn_open( env->ReleaseStringUTFChars(apn, apnStr); } -static void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* /* env */, +static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */, jobject /* obj */) { if (!sAGpsInterface) { @@ -779,7 +844,7 @@ static void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* / sAGpsInterface->data_conn_closed(); } -static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* /* env */, +static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */, jobject /* obj */) { if (!sAGpsInterface) { @@ -789,7 +854,7 @@ static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* / sAGpsInterface->data_conn_failed(); } -static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */, +static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */, jint type, jstring hostname, jint port) { if (!sAGpsInterface) { @@ -801,7 +866,7 @@ static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jo env->ReleaseStringUTFChars(hostname, c_hostname); } -static void android_location_GpsLocationProvider_send_ni_response(JNIEnv* /* env */, +static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */, jobject /* obj */, jint notifId, jint response) { if (!sGpsNiInterface) { @@ -812,7 +877,7 @@ static void android_location_GpsLocationProvider_send_ni_response(JNIEnv* /* env sGpsNiInterface->respond(notifId, response); } -static jstring android_location_GpsLocationProvider_get_internal_state(JNIEnv* env, +static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env, jobject /* obj */) { jstring result = NULL; if (sGpsDebugInterface) { @@ -826,7 +891,7 @@ static jstring android_location_GpsLocationProvider_get_internal_state(JNIEnv* e return result; } -static void android_location_GpsLocationProvider_update_network_state(JNIEnv* env, jobject /* obj */, +static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env, jobject /* obj */, jboolean connected, jint type, jboolean roaming, jboolean available, jstring extraInfo, jstring apn) { @@ -849,13 +914,13 @@ static void android_location_GpsLocationProvider_update_network_state(JNIEnv* en } } -static jboolean android_location_GpsLocationProvider_is_geofence_supported( +static jboolean android_location_GnssLocationProvider_is_geofence_supported( JNIEnv* /* env */, jobject /* obj */) { return (sGpsGeofencingInterface != NULL) ? JNI_TRUE : JNI_FALSE; } -static jboolean android_location_GpsLocationProvider_add_geofence(JNIEnv* /* env */, +static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */, jobject /* obj */, jint geofence_id, jdouble latitude, jdouble longitude, jdouble radius, jint last_transition, jint monitor_transition, jint notification_responsiveness, jint unknown_timer) { @@ -870,7 +935,7 @@ static jboolean android_location_GpsLocationProvider_add_geofence(JNIEnv* /* env return JNI_FALSE; } -static jboolean android_location_GpsLocationProvider_remove_geofence(JNIEnv* /* env */, +static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */, jobject /* obj */, jint geofence_id) { if (sGpsGeofencingInterface != NULL) { sGpsGeofencingInterface->remove_geofence_area(geofence_id); @@ -881,7 +946,7 @@ static jboolean android_location_GpsLocationProvider_remove_geofence(JNIEnv* /* return JNI_FALSE; } -static jboolean android_location_GpsLocationProvider_pause_geofence(JNIEnv* /* env */, +static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */, jobject /* obj */, jint geofence_id) { if (sGpsGeofencingInterface != NULL) { sGpsGeofencingInterface->pause_geofence(geofence_id); @@ -892,7 +957,7 @@ static jboolean android_location_GpsLocationProvider_pause_geofence(JNIEnv* /* e return JNI_FALSE; } -static jboolean android_location_GpsLocationProvider_resume_geofence(JNIEnv* /* env */, +static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */, jobject /* obj */, jint geofence_id, jint monitor_transition) { if (sGpsGeofencingInterface != NULL) { sGpsGeofencingInterface->resume_geofence(geofence_id, monitor_transition); @@ -903,10 +968,12 @@ static jboolean android_location_GpsLocationProvider_resume_geofence(JNIEnv* /* return JNI_FALSE; } -static jobject translate_gps_clock(JNIEnv* env, GpsClock* clock) { +static jobject translate_gps_clock(JNIEnv* env, void* data, size_t size) { const char* doubleSignature = "(D)V"; const char* longSignature = "(J)V"; + GpsClock* clock = reinterpret_cast(data); + jclass gpsClockClass = env->FindClass("android/location/GpsClock"); jmethodID gpsClockCtor = env->GetMethodID(gpsClockClass, "", "()V"); @@ -958,11 +1025,23 @@ static jobject translate_gps_clock(JNIEnv* env, GpsClock* clock) { env->CallVoidMethod(gpsClockObject, setterMethod, clock->drift_uncertainty_nsps); } + if (flags & GPS_CLOCK_TYPE_LOCAL_HW_TIME) { + if (size == sizeof(GpsClock)) { + jmethodID setterMethod = + env->GetMethodID(gpsClockClass, + "setTimeOfLastHwClockDiscontinuityInNs", + longSignature); + env->CallVoidMethod(gpsClockObject, + setterMethod, + clock->time_of_last_hw_clock_discontinuity_ns); + } + } + env->DeleteLocalRef(gpsClockClass); return gpsClockObject; } -static jobject translate_gps_measurement(JNIEnv* env, GpsMeasurement* measurement) { +static jobject translate_gps_measurement(JNIEnv* env, void* data, size_t size) { const char* byteSignature = "(B)V"; const char* shortSignature = "(S)V"; const char* intSignature = "(I)V"; @@ -972,6 +1051,7 @@ static jobject translate_gps_measurement(JNIEnv* env, GpsMeasurement* measuremen jclass gpsMeasurementClass = env->FindClass("android/location/GpsMeasurement"); jmethodID gpsMeasurementCtor = env->GetMethodID(gpsMeasurementClass, "", "()V"); + GpsMeasurement* measurement = reinterpret_cast(data); jobject gpsMeasurementObject = env->NewObject(gpsMeasurementClass, gpsMeasurementCtor); GpsMeasurementFlags flags = measurement->flags; @@ -1205,12 +1285,38 @@ static jobject translate_gps_measurement(JNIEnv* env, GpsMeasurement* measuremen usedInFixSetterMethod, (flags & GPS_MEASUREMENT_HAS_USED_IN_FIX) && measurement->used_in_fix); + if (size == sizeof(GpsMeasurement)) { + jmethodID setterMethod = + env->GetMethodID(gpsMeasurementClass, + "setPseudorangeRateCarrierInMetersPerSec", + doubleSignature); + env->CallVoidMethod( + gpsMeasurementObject, + setterMethod, + measurement->pseudorange_rate_carrier_mps); + + setterMethod = + env->GetMethodID(gpsMeasurementClass, + "setPseudorangeRateCarrierUncertaintyInMetersPerSec", + doubleSignature); + env->CallVoidMethod( + gpsMeasurementObject, + setterMethod, + measurement->pseudorange_rate_carrier_uncertainty_mps); + } + env->DeleteLocalRef(gpsMeasurementClass); return gpsMeasurementObject; } -static jobjectArray translate_gps_measurements(JNIEnv* env, GpsData* data) { - size_t measurementCount = data->measurement_count; +/** + * can only be GpsData or GpsData_v1. Must rewrite this function if more + * types are introduced in the future releases. + */ +template +static jobjectArray translate_gps_measurements(JNIEnv* env, void* data) { + T* gps_data = reinterpret_cast(data); + size_t measurementCount = gps_data->measurement_count; if (measurementCount == 0) { return NULL; } @@ -1221,9 +1327,11 @@ static jobjectArray translate_gps_measurements(JNIEnv* env, GpsData* data) { gpsMeasurementClass, NULL /* initialElement */); - GpsMeasurement* gpsMeasurements = data->measurements; for (uint16_t i = 0; i < measurementCount; ++i) { - jobject gpsMeasurement = translate_gps_measurement(env, &gpsMeasurements[i]); + jobject gpsMeasurement = translate_gps_measurement( + env, + &(gps_data->measurements[i]), + sizeof(gps_data->measurements[0])); env->SetObjectArrayElement(gpsMeasurementArray, i, gpsMeasurement); env->DeleteLocalRef(gpsMeasurement); } @@ -1238,33 +1346,39 @@ static void measurement_callback(GpsData* data) { ALOGE("Invalid data provided to gps_measurement_callback"); return; } - - if (data->size == sizeof(GpsData)) { - jobject gpsClock = translate_gps_clock(env, &data->clock); - jobjectArray measurementArray = translate_gps_measurements(env, data); - - jclass gpsMeasurementsEventClass = env->FindClass("android/location/GpsMeasurementsEvent"); - jmethodID gpsMeasurementsEventCtor = env->GetMethodID( - gpsMeasurementsEventClass, - "", - "(Landroid/location/GpsClock;[Landroid/location/GpsMeasurement;)V"); - - jobject gpsMeasurementsEvent = env->NewObject( - gpsMeasurementsEventClass, - gpsMeasurementsEventCtor, - gpsClock, - measurementArray); - - env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData, gpsMeasurementsEvent); - checkAndClearExceptionFromCallback(env, __FUNCTION__); - - env->DeleteLocalRef(gpsClock); - env->DeleteLocalRef(measurementArray); - env->DeleteLocalRef(gpsMeasurementsEventClass); - env->DeleteLocalRef(gpsMeasurementsEvent); - } else { + if (data->size != sizeof(GpsData) && data->size != sizeof(GpsData_v1)) { ALOGE("Invalid GpsData size found in gps_measurement_callback, size=%zd", data->size); + return; } + + jobject gpsClock; + jobjectArray measurementArray; + if (data->size == sizeof(GpsData)) { + gpsClock = translate_gps_clock(env, &data->clock, sizeof(GpsClock)); + measurementArray = translate_gps_measurements(env, data); + } else { + gpsClock = translate_gps_clock(env, &data->clock, sizeof(GpsClock_v1)); + measurementArray = translate_gps_measurements(env, data); + } + jclass gpsMeasurementsEventClass = env->FindClass("android/location/GpsMeasurementsEvent"); + jmethodID gpsMeasurementsEventCtor = env->GetMethodID( + gpsMeasurementsEventClass, + "", + "(Landroid/location/GpsClock;[Landroid/location/GpsMeasurement;)V"); + + jobject gpsMeasurementsEvent = env->NewObject( + gpsMeasurementsEventClass, + gpsMeasurementsEventCtor, + gpsClock, + measurementArray); + + env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData, gpsMeasurementsEvent); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + + env->DeleteLocalRef(gpsClock); + env->DeleteLocalRef(measurementArray); + env->DeleteLocalRef(gpsMeasurementsEventClass); + env->DeleteLocalRef(gpsMeasurementsEvent); } GpsMeasurementCallbacks sGpsMeasurementCallbacks = { @@ -1272,7 +1386,7 @@ GpsMeasurementCallbacks sGpsMeasurementCallbacks = { measurement_callback, }; -static jboolean android_location_GpsLocationProvider_is_measurement_supported( +static jboolean android_location_GnssLocationProvider_is_measurement_supported( JNIEnv* env, jclass clazz) { if (sGpsMeasurementInterface != NULL) { @@ -1281,7 +1395,7 @@ static jboolean android_location_GpsLocationProvider_is_measurement_supported( return JNI_FALSE; } -static jboolean android_location_GpsLocationProvider_start_measurement_collection( +static jboolean android_location_GnssLocationProvider_start_measurement_collection( JNIEnv* env, jobject obj) { if (sGpsMeasurementInterface == NULL) { @@ -1298,7 +1412,7 @@ static jboolean android_location_GpsLocationProvider_start_measurement_collectio return JNI_TRUE; } -static jboolean android_location_GpsLocationProvider_stop_measurement_collection( +static jboolean android_location_GnssLocationProvider_stop_measurement_collection( JNIEnv* env, jobject obj) { if (sGpsMeasurementInterface == NULL) { @@ -1382,7 +1496,7 @@ GpsNavigationMessageCallbacks sGpsNavigationMessageCallbacks = { navigation_message_callback, }; -static jboolean android_location_GpsLocationProvider_is_navigation_message_supported( +static jboolean android_location_GnssLocationProvider_is_navigation_message_supported( JNIEnv* env, jclass clazz) { if(sGpsNavigationMessageInterface != NULL) { @@ -1391,7 +1505,7 @@ static jboolean android_location_GpsLocationProvider_is_navigation_message_suppo return JNI_FALSE; } -static jboolean android_location_GpsLocationProvider_start_navigation_message_collection( +static jboolean android_location_GnssLocationProvider_start_navigation_message_collection( JNIEnv* env, jobject obj) { if (sGpsNavigationMessageInterface == NULL) { @@ -1408,7 +1522,7 @@ static jboolean android_location_GpsLocationProvider_start_navigation_message_co return JNI_TRUE; } -static jboolean android_location_GpsLocationProvider_stop_navigation_message_collection( +static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection( JNIEnv* env, jobject obj) { if (sGpsNavigationMessageInterface == NULL) { @@ -1420,7 +1534,7 @@ static jboolean android_location_GpsLocationProvider_stop_navigation_message_col return JNI_TRUE; } -static void android_location_GpsLocationProvider_configuration_update(JNIEnv* env, jobject obj, +static void android_location_GnssLocationProvider_configuration_update(JNIEnv* env, jobject obj, jstring config_content) { if (!sGnssConfigurationInterface) { @@ -1436,105 +1550,105 @@ static void android_location_GpsLocationProvider_configuration_update(JNIEnv* en static const JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ - {"class_init_native", "()V", (void *)android_location_GpsLocationProvider_class_init_native}, - {"native_is_supported", "()Z", (void*)android_location_GpsLocationProvider_is_supported}, + {"class_init_native", "()V", (void *)android_location_GnssLocationProvider_class_init_native}, + {"native_is_supported", "()Z", (void*)android_location_GnssLocationProvider_is_supported}, {"native_is_agps_ril_supported", "()Z", - (void*)android_location_GpsLocationProvider_is_agps_ril_supported}, + (void*)android_location_GnssLocationProvider_is_agps_ril_supported}, {"native_is_gnss_configuration_supported", "()Z", (void*)android_location_gpsLocationProvider_is_gnss_configuration_supported}, - {"native_init", "()Z", (void*)android_location_GpsLocationProvider_init}, - {"native_cleanup", "()V", (void*)android_location_GpsLocationProvider_cleanup}, + {"native_init", "()Z", (void*)android_location_GnssLocationProvider_init}, + {"native_cleanup", "()V", (void*)android_location_GnssLocationProvider_cleanup}, {"native_set_position_mode", "(IIIII)Z", - (void*)android_location_GpsLocationProvider_set_position_mode}, - {"native_start", "()Z", (void*)android_location_GpsLocationProvider_start}, - {"native_stop", "()Z", (void*)android_location_GpsLocationProvider_stop}, + (void*)android_location_GnssLocationProvider_set_position_mode}, + {"native_start", "()Z", (void*)android_location_GnssLocationProvider_start}, + {"native_stop", "()Z", (void*)android_location_GnssLocationProvider_stop}, {"native_delete_aiding_data", "(I)V", - (void*)android_location_GpsLocationProvider_delete_aiding_data}, + (void*)android_location_GnssLocationProvider_delete_aiding_data}, {"native_read_sv_status", "([I[F[F[F[I)I", - (void*)android_location_GpsLocationProvider_read_sv_status}, - {"native_read_nmea", "([BI)I", (void*)android_location_GpsLocationProvider_read_nmea}, - {"native_inject_time", "(JJI)V", (void*)android_location_GpsLocationProvider_inject_time}, + (void*)android_location_GnssLocationProvider_read_sv_status}, + {"native_read_nmea", "([BI)I", (void*)android_location_GnssLocationProvider_read_nmea}, + {"native_inject_time", "(JJI)V", (void*)android_location_GnssLocationProvider_inject_time}, {"native_inject_location", "(DDF)V", - (void*)android_location_GpsLocationProvider_inject_location}, - {"native_supports_xtra", "()Z", (void*)android_location_GpsLocationProvider_supports_xtra}, + (void*)android_location_GnssLocationProvider_inject_location}, + {"native_supports_xtra", "()Z", (void*)android_location_GnssLocationProvider_supports_xtra}, {"native_inject_xtra_data", "([BI)V", - (void*)android_location_GpsLocationProvider_inject_xtra_data}, + (void*)android_location_GnssLocationProvider_inject_xtra_data}, {"native_agps_data_conn_open", "(Ljava/lang/String;I)V", - (void*)android_location_GpsLocationProvider_agps_data_conn_open}, + (void*)android_location_GnssLocationProvider_agps_data_conn_open}, {"native_agps_data_conn_closed", "()V", - (void*)android_location_GpsLocationProvider_agps_data_conn_closed}, + (void*)android_location_GnssLocationProvider_agps_data_conn_closed}, {"native_agps_data_conn_failed", "()V", - (void*)android_location_GpsLocationProvider_agps_data_conn_failed}, + (void*)android_location_GnssLocationProvider_agps_data_conn_failed}, {"native_agps_set_id", "(ILjava/lang/String;)V", - (void*)android_location_GpsLocationProvider_agps_set_id}, + (void*)android_location_GnssLocationProvider_agps_set_id}, {"native_agps_set_ref_location_cellid", "(IIIII)V", - (void*)android_location_GpsLocationProvider_agps_set_reference_location_cellid}, + (void*)android_location_GnssLocationProvider_agps_set_reference_location_cellid}, {"native_set_agps_server", "(ILjava/lang/String;I)V", - (void*)android_location_GpsLocationProvider_set_agps_server}, + (void*)android_location_GnssLocationProvider_set_agps_server}, {"native_send_ni_response", "(II)V", - (void*)android_location_GpsLocationProvider_send_ni_response}, + (void*)android_location_GnssLocationProvider_send_ni_response}, {"native_agps_ni_message", "([BI)V", - (void *)android_location_GpsLocationProvider_agps_send_ni_message}, + (void *)android_location_GnssLocationProvider_agps_send_ni_message}, {"native_get_internal_state", "()Ljava/lang/String;", - (void*)android_location_GpsLocationProvider_get_internal_state}, + (void*)android_location_GnssLocationProvider_get_internal_state}, {"native_update_network_state", "(ZIZZLjava/lang/String;Ljava/lang/String;)V", - (void*)android_location_GpsLocationProvider_update_network_state }, + (void*)android_location_GnssLocationProvider_update_network_state }, {"native_is_geofence_supported", "()Z", - (void*) android_location_GpsLocationProvider_is_geofence_supported}, + (void*) android_location_GnssLocationProvider_is_geofence_supported}, {"native_add_geofence", "(IDDDIIII)Z", - (void *)android_location_GpsLocationProvider_add_geofence}, + (void *)android_location_GnssLocationProvider_add_geofence}, {"native_remove_geofence", "(I)Z", - (void *)android_location_GpsLocationProvider_remove_geofence}, - {"native_pause_geofence", "(I)Z", (void *)android_location_GpsLocationProvider_pause_geofence}, + (void *)android_location_GnssLocationProvider_remove_geofence}, + {"native_pause_geofence", "(I)Z", (void *)android_location_GnssLocationProvider_pause_geofence}, {"native_resume_geofence", "(II)Z", - (void *)android_location_GpsLocationProvider_resume_geofence}, + (void *)android_location_GnssLocationProvider_resume_geofence}, {"native_is_measurement_supported", "()Z", - (void*) android_location_GpsLocationProvider_is_measurement_supported}, + (void*) android_location_GnssLocationProvider_is_measurement_supported}, {"native_start_measurement_collection", "()Z", - (void*) android_location_GpsLocationProvider_start_measurement_collection}, + (void*) android_location_GnssLocationProvider_start_measurement_collection}, {"native_stop_measurement_collection", "()Z", - (void*) android_location_GpsLocationProvider_stop_measurement_collection}, + (void*) android_location_GnssLocationProvider_stop_measurement_collection}, {"native_is_navigation_message_supported", "()Z", - (void*) android_location_GpsLocationProvider_is_navigation_message_supported}, + (void*) android_location_GnssLocationProvider_is_navigation_message_supported}, {"native_start_navigation_message_collection", "()Z", - (void*) android_location_GpsLocationProvider_start_navigation_message_collection}, + (void*) android_location_GnssLocationProvider_start_navigation_message_collection}, {"native_stop_navigation_message_collection", "()Z", - (void*) android_location_GpsLocationProvider_stop_navigation_message_collection}, + (void*) android_location_GnssLocationProvider_stop_navigation_message_collection}, {"native_configuration_update", "(Ljava/lang/String;)V", - (void*)android_location_GpsLocationProvider_configuration_update}, + (void*)android_location_GnssLocationProvider_configuration_update}, }; -int register_android_server_location_GpsLocationProvider(JNIEnv* env) +int register_android_server_location_GnssLocationProvider(JNIEnv* env) { return jniRegisterNativeMethods( env, - "com/android/server/location/GpsLocationProvider", + "com/android/server/location/GnssLocationProvider", sMethods, NELEM(sMethods)); } diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp index 1f3fde63e335f..a7010bcba5dd8 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -36,7 +36,7 @@ int register_android_server_UsbDeviceManager(JNIEnv* env); int register_android_server_UsbMidiDevice(JNIEnv* env); int register_android_server_UsbHostManager(JNIEnv* env); int register_android_server_VibratorService(JNIEnv* env); -int register_android_server_location_GpsLocationProvider(JNIEnv* env); +int register_android_server_location_GnssLocationProvider(JNIEnv* env); int register_android_server_location_FlpHardwareProvider(JNIEnv* env); int register_android_server_connectivity_Vpn(JNIEnv* env); int register_android_server_hdmi_HdmiCecController(JNIEnv* env); @@ -71,7 +71,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_android_server_UsbHostManager(env); register_android_server_VibratorService(env); register_android_server_SystemServer(env); - register_android_server_location_GpsLocationProvider(env); + register_android_server_location_GnssLocationProvider(env); register_android_server_location_FlpHardwareProvider(env); register_android_server_connectivity_Vpn(env); register_android_server_AssetAtlasService(env);