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 19 import android.compat.annotation.UnsupportedAppUsage; 20 import android.os.Build; 21 import android.util.SparseArray; 22 23 import java.util.Iterator; 24 import java.util.NoSuchElementException; 25 26 27 /** 28 * This class represents the current state of the GPS engine. 29 * 30 * <p>This class is used in conjunction with the {@link Listener} interface. 31 * 32 * @deprecated use {@link GnssStatus} and {@link GnssStatus.Callback}. 33 */ 34 @Deprecated 35 public final class GpsStatus { 36 private static final int NUM_SATELLITES = 255; 37 private static final int GLONASS_SVID_OFFSET = 64; 38 private static final int BEIDOU_SVID_OFFSET = 200; 39 private static final int SBAS_SVID_OFFSET = -87; 40 41 /* These package private values are modified by the LocationManager class */ 42 private int mTimeToFirstFix; 43 private final SparseArray<GpsSatellite> mSatellites = new SparseArray<>(); 44 45 private final class SatelliteIterator implements Iterator<GpsSatellite> { 46 private final int mSatellitesCount; 47 48 private int mIndex = 0; 49 SatelliteIterator()50 SatelliteIterator() { 51 mSatellitesCount = mSatellites.size(); 52 } 53 54 @Override hasNext()55 public boolean hasNext() { 56 for (; mIndex < mSatellitesCount; ++mIndex) { 57 GpsSatellite satellite = mSatellites.valueAt(mIndex); 58 if (satellite.mValid) { 59 return true; 60 } 61 } 62 return false; 63 } 64 65 @Override next()66 public GpsSatellite next() { 67 while (mIndex < mSatellitesCount) { 68 GpsSatellite satellite = mSatellites.valueAt(mIndex); 69 ++mIndex; 70 if (satellite.mValid) { 71 return satellite; 72 } 73 } 74 throw new NoSuchElementException(); 75 } 76 77 @Override remove()78 public void remove() { 79 throw new UnsupportedOperationException(); 80 } 81 } 82 83 private Iterable<GpsSatellite> mSatelliteList = new Iterable<GpsSatellite>() { 84 @Override 85 public Iterator<GpsSatellite> iterator() { 86 return new SatelliteIterator(); 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. 114 * @deprecated use {@link GnssStatus.Callback} instead. 115 */ 116 @Deprecated 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 * 128 * When this method is called, the client should call 129 * {@link LocationManager#getGpsStatus} to get additional 130 * status information. 131 * 132 * @param event event number for this notification 133 */ onGpsStatusChanged(int event)134 void onGpsStatusChanged(int event); 135 } 136 137 /** 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. 144 * @deprecated use {@link OnNmeaMessageListener} instead. 145 */ 146 @Deprecated 147 public interface NmeaListener { onNmeaReceived(long timestamp, String nmea)148 void onNmeaReceived(long timestamp, String nmea); 149 } 150 151 // For API-compat a public ctor() is not available GpsStatus()152 GpsStatus() {} 153 setStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations, float[] azimuths)154 private void setStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations, 155 float[] azimuths) { 156 clearSatellites(); 157 for (int i = 0; i < svCount; i++) { 158 final int constellationType = 159 (svidWithFlags[i] >> GnssStatus.CONSTELLATION_TYPE_SHIFT_WIDTH) 160 & GnssStatus.CONSTELLATION_TYPE_MASK; 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; 172 } else if (constellationType == GnssStatus.CONSTELLATION_SBAS) { 173 prn += SBAS_SVID_OFFSET; 174 } else if ((constellationType != GnssStatus.CONSTELLATION_GPS) && 175 (constellationType != GnssStatus.CONSTELLATION_QZSS)) { 176 continue; 177 } 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 } 184 185 satellite.mValid = true; 186 satellite.mSnr = cn0s[i]; 187 satellite.mElevation = elevations[i]; 188 satellite.mAzimuth = azimuths[i]; 189 satellite.mHasEphemeris = 190 (svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0; 191 satellite.mHasAlmanac = 192 (svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) != 0; 193 satellite.mUsedInFix = 194 (svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0; 195 } 196 } 197 } 198 199 /** 200 * Copies GPS satellites information from GnssStatus object. 201 * Since this method is only used within {@link LocationManager#getGpsStatus}, 202 * it does not need to be synchronized. 203 * @hide 204 */ setStatus(GnssStatus status, int timeToFirstFix)205 void setStatus(GnssStatus status, int timeToFirstFix) { 206 mTimeToFirstFix = timeToFirstFix; 207 setStatus(status.mSvCount, status.mSvidWithFlags, status.mCn0DbHz, status.mElevations, 208 status.mAzimuths); 209 } 210 211 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) setTimeToFirstFix(int ttff)212 void setTimeToFirstFix(int ttff) { 213 mTimeToFirstFix = ttff; 214 } 215 216 /** 217 * Returns the time required to receive the first fix since the most recent 218 * restart of the GPS engine. 219 * 220 * @return time to first fix in milliseconds 221 */ getTimeToFirstFix()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 */ getSatellites()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 */ getMaxSatellites()242 public int getMaxSatellites() { 243 return NUM_SATELLITES; 244 } 245 clearSatellites()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 } 253 } 254