The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2008 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package android.location; |
| 18 | |
Mathew Inwood | 735497e | 2018-08-09 16:44:32 +0100 | [diff] [blame] | 19 | import android.annotation.UnsupportedAppUsage; |
Mathew Inwood | 31755f9 | 2018-12-20 13:53:36 +0000 | [diff] [blame^] | 20 | import android.os.Build; |
destradaa | 6bde468 | 2015-01-30 16:11:20 -0800 | [diff] [blame] | 21 | import android.util.SparseArray; |
| 22 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 23 | import java.util.Iterator; |
| 24 | import java.util.NoSuchElementException; |
| 25 | |
| 26 | |
| 27 | /** |
| 28 | * This class represents the current state of the GPS engine. |
Lifu Tang | e8abe8e | 2016-04-01 10:32:05 -0700 | [diff] [blame] | 29 | * |
| 30 | * <p>This class is used in conjunction with the {@link Listener} interface. |
| 31 | * |
| 32 | * @deprecated use {@link GnssStatus} and {@link GnssStatus.Callback}. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 33 | */ |
Lifu Tang | e8abe8e | 2016-04-01 10:32:05 -0700 | [diff] [blame] | 34 | @Deprecated |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 35 | public final class GpsStatus { |
Mike Lockwood | b7c4ae9 | 2009-05-06 10:48:30 -0400 | [diff] [blame] | 36 | private static final int NUM_SATELLITES = 255; |
Wyatt Riley | 49d9891 | 2016-05-17 16:14:48 -0700 | [diff] [blame] | 37 | private static final int GLONASS_SVID_OFFSET = 64; |
| 38 | private static final int BEIDOU_SVID_OFFSET = 200; |
Wyatt Riley | f6527ae | 2016-05-23 15:23:12 -0700 | [diff] [blame] | 39 | private static final int SBAS_SVID_OFFSET = -87; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 40 | |
| 41 | /* These package private values are modified by the LocationManager class */ |
| 42 | private int mTimeToFirstFix; |
destradaa | 6bde468 | 2015-01-30 16:11:20 -0800 | [diff] [blame] | 43 | private final SparseArray<GpsSatellite> mSatellites = new SparseArray<>(); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 44 | |
| 45 | private final class SatelliteIterator implements Iterator<GpsSatellite> { |
destradaa | 6bde468 | 2015-01-30 16:11:20 -0800 | [diff] [blame] | 46 | private final int mSatellitesCount; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 47 | |
destradaa | 6bde468 | 2015-01-30 16:11:20 -0800 | [diff] [blame] | 48 | private int mIndex = 0; |
| 49 | |
Lifu Tang | 30f95a7 | 2016-01-07 23:20:38 -0800 | [diff] [blame] | 50 | SatelliteIterator() { |
| 51 | mSatellitesCount = mSatellites.size(); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 52 | } |
| 53 | |
Lifu Tang | 30f95a7 | 2016-01-07 23:20:38 -0800 | [diff] [blame] | 54 | @Override |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 55 | public boolean hasNext() { |
destradaa | 6bde468 | 2015-01-30 16:11:20 -0800 | [diff] [blame] | 56 | for (; mIndex < mSatellitesCount; ++mIndex) { |
| 57 | GpsSatellite satellite = mSatellites.valueAt(mIndex); |
| 58 | if (satellite.mValid) { |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 59 | return true; |
| 60 | } |
| 61 | } |
| 62 | return false; |
| 63 | } |
| 64 | |
Lifu Tang | 30f95a7 | 2016-01-07 23:20:38 -0800 | [diff] [blame] | 65 | @Override |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 66 | public GpsSatellite next() { |
destradaa | 6bde468 | 2015-01-30 16:11:20 -0800 | [diff] [blame] | 67 | while (mIndex < mSatellitesCount) { |
| 68 | GpsSatellite satellite = mSatellites.valueAt(mIndex); |
| 69 | ++mIndex; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 70 | if (satellite.mValid) { |
| 71 | return satellite; |
| 72 | } |
| 73 | } |
| 74 | throw new NoSuchElementException(); |
| 75 | } |
| 76 | |
Lifu Tang | 30f95a7 | 2016-01-07 23:20:38 -0800 | [diff] [blame] | 77 | @Override |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 78 | public void remove() { |
| 79 | throw new UnsupportedOperationException(); |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | private Iterable<GpsSatellite> mSatelliteList = new Iterable<GpsSatellite>() { |
Lifu Tang | 30f95a7 | 2016-01-07 23:20:38 -0800 | [diff] [blame] | 84 | @Override |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 85 | public Iterator<GpsSatellite> iterator() { |
Lifu Tang | 30f95a7 | 2016-01-07 23:20:38 -0800 | [diff] [blame] | 86 | return new SatelliteIterator(); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 87 | } |
| 88 | }; |
| 89 | |
| 90 | /** |
| 91 | * Event sent when the GPS system has started. |
| 92 | */ |
| 93 | public static final int GPS_EVENT_STARTED = 1; |
| 94 | |
| 95 | /** |
| 96 | * Event sent when the GPS system has stopped. |
| 97 | */ |
| 98 | public static final int GPS_EVENT_STOPPED = 2; |
| 99 | |
| 100 | /** |
| 101 | * Event sent when the GPS system has received its first fix since starting. |
| 102 | * Call {@link #getTimeToFirstFix()} to find the time from start to first fix. |
| 103 | */ |
| 104 | public static final int GPS_EVENT_FIRST_FIX = 3; |
| 105 | |
| 106 | /** |
| 107 | * Event sent periodically to report GPS satellite status. |
| 108 | * Call {@link #getSatellites()} to retrieve the status for each satellite. |
| 109 | */ |
| 110 | public static final int GPS_EVENT_SATELLITE_STATUS = 4; |
| 111 | |
| 112 | /** |
| 113 | * Used for receiving notifications when GPS status has changed. |
Lifu Tang | e8abe8e | 2016-04-01 10:32:05 -0700 | [diff] [blame] | 114 | * @deprecated use {@link GnssStatus.Callback} instead. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 115 | */ |
Lifu Tang | e8abe8e | 2016-04-01 10:32:05 -0700 | [diff] [blame] | 116 | @Deprecated |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 117 | public interface Listener { |
| 118 | /** |
| 119 | * Called to report changes in the GPS status. |
| 120 | * The event number is one of: |
| 121 | * <ul> |
| 122 | * <li> {@link GpsStatus#GPS_EVENT_STARTED} |
| 123 | * <li> {@link GpsStatus#GPS_EVENT_STOPPED} |
| 124 | * <li> {@link GpsStatus#GPS_EVENT_FIRST_FIX} |
| 125 | * <li> {@link GpsStatus#GPS_EVENT_SATELLITE_STATUS} |
| 126 | * </ul> |
| 127 | * |
destradaa | 6bde468 | 2015-01-30 16:11:20 -0800 | [diff] [blame] | 128 | * When this method is called, the client should call |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 129 | * {@link LocationManager#getGpsStatus} to get additional |
| 130 | * status information. |
| 131 | * |
| 132 | * @param event event number for this notification |
| 133 | */ |
| 134 | void onGpsStatusChanged(int event); |
| 135 | } |
| 136 | |
Mike Lockwood | b16e780 | 2009-08-06 09:26:02 -0400 | [diff] [blame] | 137 | /** |
Mike Lockwood | 640992d | 2009-08-06 15:52:55 -0400 | [diff] [blame] | 138 | * Used for receiving NMEA sentences from the GPS. |
| 139 | * NMEA 0183 is a standard for communicating with marine electronic devices |
| 140 | * and is a common method for receiving data from a GPS, typically over a serial port. |
| 141 | * See <a href="http://en.wikipedia.org/wiki/NMEA_0183">NMEA 0183</a> for more details. |
| 142 | * You can implement this interface and call {@link LocationManager#addNmeaListener} |
| 143 | * to receive NMEA data from the GPS engine. |
Lifu Tang | e8abe8e | 2016-04-01 10:32:05 -0700 | [diff] [blame] | 144 | * @deprecated use {@link OnNmeaMessageListener} instead. |
Mike Lockwood | b16e780 | 2009-08-06 09:26:02 -0400 | [diff] [blame] | 145 | */ |
Lifu Tang | e8abe8e | 2016-04-01 10:32:05 -0700 | [diff] [blame] | 146 | @Deprecated |
Mike Lockwood | b16e780 | 2009-08-06 09:26:02 -0400 | [diff] [blame] | 147 | public interface NmeaListener { |
| 148 | void onNmeaReceived(long timestamp, String nmea); |
| 149 | } |
| 150 | |
destradaa | 6bde468 | 2015-01-30 16:11:20 -0800 | [diff] [blame] | 151 | // For API-compat a public ctor() is not available |
| 152 | GpsStatus() {} |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 153 | |
Lifu Tang | 76a620f | 2016-02-26 19:53:01 -0800 | [diff] [blame] | 154 | private void setStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations, |
Lifu Tang | 120480f | 2016-02-07 18:08:19 -0800 | [diff] [blame] | 155 | float[] azimuths) { |
destradaa | 6bde468 | 2015-01-30 16:11:20 -0800 | [diff] [blame] | 156 | clearSatellites(); |
| 157 | for (int i = 0; i < svCount; i++) { |
Lifu Tang | 120480f | 2016-02-07 18:08:19 -0800 | [diff] [blame] | 158 | final int constellationType = |
| 159 | (svidWithFlags[i] >> GnssStatus.CONSTELLATION_TYPE_SHIFT_WIDTH) |
| 160 | & GnssStatus.CONSTELLATION_TYPE_MASK; |
Wyatt Riley | 49d9891 | 2016-05-17 16:14:48 -0700 | [diff] [blame] | 161 | int prn = svidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH; |
| 162 | // Other satellites passed through these APIs before GnssSvStatus was availble. |
| 163 | // GPS, SBAS & QZSS can pass through at their nominally |
| 164 | // assigned prn number (as long as it fits in the valid 0-255 range below.) |
| 165 | // Glonass, and Beidou are passed through with the defacto standard offsets |
| 166 | // Other future constellation reporting (e.g. Galileo) needs to use |
| 167 | // GnssSvStatus on (N level) HAL & Java layers. |
| 168 | if (constellationType == GnssStatus.CONSTELLATION_GLONASS) { |
| 169 | prn += GLONASS_SVID_OFFSET; |
| 170 | } else if (constellationType == GnssStatus.CONSTELLATION_BEIDOU) { |
| 171 | prn += BEIDOU_SVID_OFFSET; |
Wyatt Riley | f6527ae | 2016-05-23 15:23:12 -0700 | [diff] [blame] | 172 | } else if (constellationType == GnssStatus.CONSTELLATION_SBAS) { |
| 173 | prn += SBAS_SVID_OFFSET; |
Wyatt Riley | 49d9891 | 2016-05-17 16:14:48 -0700 | [diff] [blame] | 174 | } else if ((constellationType != GnssStatus.CONSTELLATION_GPS) && |
Wyatt Riley | f6527ae | 2016-05-23 15:23:12 -0700 | [diff] [blame] | 175 | (constellationType != GnssStatus.CONSTELLATION_QZSS)) { |
Lifu Tang | 30f95a7 | 2016-01-07 23:20:38 -0800 | [diff] [blame] | 176 | continue; |
| 177 | } |
destradaa | 6bde468 | 2015-01-30 16:11:20 -0800 | [diff] [blame] | 178 | if (prn > 0 && prn <= NUM_SATELLITES) { |
| 179 | GpsSatellite satellite = mSatellites.get(prn); |
| 180 | if (satellite == null) { |
| 181 | satellite = new GpsSatellite(prn); |
| 182 | mSatellites.put(prn, satellite); |
| 183 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 184 | |
Mike Lockwood | a3d2d76 | 2010-04-14 18:55:41 -0400 | [diff] [blame] | 185 | satellite.mValid = true; |
Lifu Tang | 76a620f | 2016-02-26 19:53:01 -0800 | [diff] [blame] | 186 | satellite.mSnr = cn0s[i]; |
Mike Lockwood | a3d2d76 | 2010-04-14 18:55:41 -0400 | [diff] [blame] | 187 | satellite.mElevation = elevations[i]; |
| 188 | satellite.mAzimuth = azimuths[i]; |
Lifu Tang | 30f95a7 | 2016-01-07 23:20:38 -0800 | [diff] [blame] | 189 | satellite.mHasEphemeris = |
Lifu Tang | 120480f | 2016-02-07 18:08:19 -0800 | [diff] [blame] | 190 | (svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0; |
Lifu Tang | 30f95a7 | 2016-01-07 23:20:38 -0800 | [diff] [blame] | 191 | satellite.mHasAlmanac = |
Lifu Tang | 120480f | 2016-02-07 18:08:19 -0800 | [diff] [blame] | 192 | (svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) != 0; |
Lifu Tang | 30f95a7 | 2016-01-07 23:20:38 -0800 | [diff] [blame] | 193 | satellite.mUsedInFix = |
Lifu Tang | 120480f | 2016-02-07 18:08:19 -0800 | [diff] [blame] | 194 | (svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0; |
Mike Lockwood | a3d2d76 | 2010-04-14 18:55:41 -0400 | [diff] [blame] | 195 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 196 | } |
| 197 | } |
| 198 | |
| 199 | /** |
Lifu Tang | 30f95a7 | 2016-01-07 23:20:38 -0800 | [diff] [blame] | 200 | * Copies GPS satellites information from GnssStatus object. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 201 | * Since this method is only used within {@link LocationManager#getGpsStatus}, |
| 202 | * it does not need to be synchronized. |
Lifu Tang | 30f95a7 | 2016-01-07 23:20:38 -0800 | [diff] [blame] | 203 | * @hide |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 204 | */ |
Lifu Tang | 30f95a7 | 2016-01-07 23:20:38 -0800 | [diff] [blame] | 205 | void setStatus(GnssStatus status, int timeToFirstFix) { |
| 206 | mTimeToFirstFix = timeToFirstFix; |
Lifu Tang | 76a620f | 2016-02-26 19:53:01 -0800 | [diff] [blame] | 207 | setStatus(status.mSvCount, status.mSvidWithFlags, status.mCn0DbHz, status.mElevations, |
Lifu Tang | 120480f | 2016-02-07 18:08:19 -0800 | [diff] [blame] | 208 | status.mAzimuths); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 209 | } |
| 210 | |
Mathew Inwood | 31755f9 | 2018-12-20 13:53:36 +0000 | [diff] [blame^] | 211 | @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 212 | void setTimeToFirstFix(int ttff) { |
| 213 | mTimeToFirstFix = ttff; |
| 214 | } |
| 215 | |
| 216 | /** |
destradaa | 6bde468 | 2015-01-30 16:11:20 -0800 | [diff] [blame] | 217 | * Returns the time required to receive the first fix since the most recent |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 218 | * restart of the GPS engine. |
| 219 | * |
| 220 | * @return time to first fix in milliseconds |
| 221 | */ |
| 222 | public int getTimeToFirstFix() { |
| 223 | return mTimeToFirstFix; |
| 224 | } |
| 225 | |
| 226 | /** |
| 227 | * Returns an array of {@link GpsSatellite} objects, which represent the |
| 228 | * current state of the GPS engine. |
| 229 | * |
| 230 | * @return the list of satellites |
| 231 | */ |
| 232 | public Iterable<GpsSatellite> getSatellites() { |
| 233 | return mSatelliteList; |
| 234 | } |
| 235 | |
| 236 | /** |
| 237 | * Returns the maximum number of satellites that can be in the satellite |
| 238 | * list that can be returned by {@link #getSatellites()}. |
| 239 | * |
| 240 | * @return the maximum number of satellites |
| 241 | */ |
| 242 | public int getMaxSatellites() { |
| 243 | return NUM_SATELLITES; |
| 244 | } |
destradaa | 6bde468 | 2015-01-30 16:11:20 -0800 | [diff] [blame] | 245 | |
| 246 | private void clearSatellites() { |
| 247 | int satellitesCount = mSatellites.size(); |
| 248 | for (int i = 0; i < satellitesCount; i++) { |
| 249 | GpsSatellite satellite = mSatellites.valueAt(i); |
| 250 | satellite.mValid = false; |
| 251 | } |
| 252 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 253 | } |