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