1 /*
2  * Copyright (C) 2016 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.annotation.IntDef;
20 import android.annotation.NonNull;
21 
22 import java.lang.annotation.Retention;
23 import java.lang.annotation.RetentionPolicy;
24 
25 /**
26  * This class represents the current state of the GNSS engine.
27  * This class is used in conjunction with the {@link GnssStatus.Callback}.
28  */
29 public final class GnssStatus {
30     // these must match the definitions in gps.h
31 
32     /** Unknown constellation type. */
33     public static final int CONSTELLATION_UNKNOWN = 0;
34     /** Constellation type constant for GPS. */
35     public static final int CONSTELLATION_GPS = 1;
36     /** Constellation type constant for SBAS. */
37     public static final int CONSTELLATION_SBAS = 2;
38     /** Constellation type constant for Glonass. */
39     public static final int CONSTELLATION_GLONASS = 3;
40     /** Constellation type constant for QZSS. */
41     public static final int CONSTELLATION_QZSS = 4;
42     /** Constellation type constant for Beidou. */
43     public static final int CONSTELLATION_BEIDOU = 5;
44     /** Constellation type constant for Galileo. */
45     public static final int CONSTELLATION_GALILEO = 6;
46     /** Constellation type constant for IRNSS. */
47     public static final int CONSTELLATION_IRNSS = 7;
48     /** @hide */
49     public static final int CONSTELLATION_COUNT = 8;
50 
51     /** @hide */
52     public static final int GNSS_SV_FLAGS_NONE = 0;
53     /** @hide */
54     public static final int GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA = (1 << 0);
55     /** @hide */
56     public static final int GNSS_SV_FLAGS_HAS_ALMANAC_DATA = (1 << 1);
57     /** @hide */
58     public static final int GNSS_SV_FLAGS_USED_IN_FIX = (1 << 2);
59     /** @hide */
60     public static final int GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY = (1 << 3);
61 
62     /** @hide */
63     public static final int SVID_SHIFT_WIDTH = 8;
64     /** @hide */
65     public static final int CONSTELLATION_TYPE_SHIFT_WIDTH = 4;
66     /** @hide */
67     public static final int CONSTELLATION_TYPE_MASK = 0xf;
68 
69     /**
70      * Used for receiving notifications when GNSS events happen.
71      */
72     public static abstract class Callback {
73         /**
74          * Called when GNSS system has started.
75          */
onStarted()76         public void onStarted() {}
77 
78         /**
79          * Called when GNSS system has stopped.
80          */
onStopped()81         public void onStopped() {}
82 
83         /**
84          * Called when the GNSS system has received its first fix since starting.
85          * @param ttffMillis the time from start to first fix in milliseconds.
86          */
onFirstFix(int ttffMillis)87         public void onFirstFix(int ttffMillis) {}
88 
89         /**
90          * Called periodically to report GNSS satellite status.
91          * @param status the current status of all satellites.
92          */
onSatelliteStatusChanged(GnssStatus status)93         public void onSatelliteStatusChanged(GnssStatus status) {}
94     }
95 
96     /**
97      * Constellation type.
98      * @hide
99      */
100     @Retention(RetentionPolicy.SOURCE)
101     @IntDef({CONSTELLATION_UNKNOWN, CONSTELLATION_GPS, CONSTELLATION_SBAS, CONSTELLATION_GLONASS,
102             CONSTELLATION_QZSS, CONSTELLATION_BEIDOU, CONSTELLATION_GALILEO, CONSTELLATION_IRNSS})
103     public @interface ConstellationType {}
104 
105     final int[] mSvidWithFlags;
106     final float[] mCn0DbHz;
107     final float[] mElevations;
108     final float[] mAzimuths;
109     final int mSvCount;
110     final float[] mCarrierFrequencies;
111 
112     /**
113      * @hide
114      */
GnssStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations, float[] azimuths, float[] carrierFrequencies)115     public GnssStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations,
116             float[] azimuths, float[] carrierFrequencies) {
117         mSvCount = svCount;
118         mSvidWithFlags = svidWithFlags;
119         mCn0DbHz = cn0s;
120         mElevations = elevations;
121         mAzimuths = azimuths;
122         mCarrierFrequencies = carrierFrequencies;
123     }
124 
125     /**
126      * Gets the total number of satellites in satellite list.
127      */
getSatelliteCount()128     public int getSatelliteCount() {
129         return mSvCount;
130     }
131 
132     /**
133      * Retrieves the constellation type of the satellite at the specified index.
134      *
135      * @param satIndex the index of the satellite in the list.
136      */
137     @ConstellationType
getConstellationType(int satIndex)138     public int getConstellationType(int satIndex) {
139         return ((mSvidWithFlags[satIndex] >> CONSTELLATION_TYPE_SHIFT_WIDTH)
140                 & CONSTELLATION_TYPE_MASK);
141     }
142 
143     /**
144      * Gets the identification number for the satellite at the specific index.
145      *
146      * <p>This svid is pseudo-random number for most constellations. It is FCN &amp; OSN number for
147      * Glonass.
148      *
149      * <p>The distinction is made by looking at constellation field
150      * {@link #getConstellationType(int)} Expected values are in the range of:
151      *
152      * <ul>
153      * <li>GPS: 1-32</li>
154      * <li>SBAS: 120-151, 183-192</li>
155      * <li>GLONASS: One of: OSN, or FCN+100
156      * <ul>
157      *   <li>1-24 as the orbital slot number (OSN) (preferred, if known)</li>
158      *   <li>93-106 as the frequency channel number (FCN) (-7 to +6) plus 100.
159      *   i.e. encode FCN of -7 as 93, 0 as 100, and +6 as 106</li>
160      * </ul></li>
161      * <li>QZSS: 193-200</li>
162      * <li>Galileo: 1-36</li>
163      * <li>Beidou: 1-37</li>
164      * </ul>
165      *
166      * @param satIndex the index of the satellite in the list.
167      */
getSvid(int satIndex)168     public int getSvid(int satIndex) {
169         return mSvidWithFlags[satIndex] >> SVID_SHIFT_WIDTH;
170     }
171 
172     /**
173      * Retrieves the carrier-to-noise density at the antenna of the satellite at the specified index
174      * in dB-Hz.
175      *
176      * @param satIndex the index of the satellite in the list.
177      */
getCn0DbHz(int satIndex)178     public float getCn0DbHz(int satIndex) {
179         return mCn0DbHz[satIndex];
180     }
181 
182     /**
183      * Retrieves the elevation of the satellite at the specified index.
184      *
185      * @param satIndex the index of the satellite in the list.
186      */
getElevationDegrees(int satIndex)187     public float getElevationDegrees(int satIndex) {
188         return mElevations[satIndex];
189     }
190 
191     /**
192      * Retrieves the azimuth the satellite at the specified index.
193      *
194      * @param satIndex the index of the satellite in the list.
195      */
getAzimuthDegrees(int satIndex)196     public float getAzimuthDegrees(int satIndex) {
197         return mAzimuths[satIndex];
198     }
199 
200     /**
201      * Reports whether the satellite at the specified index has ephemeris data.
202      *
203      * @param satIndex the index of the satellite in the list.
204      */
hasEphemerisData(int satIndex)205     public boolean hasEphemerisData(int satIndex) {
206         return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0;
207     }
208 
209     /**
210      * Reports whether the satellite at the specified index has almanac data.
211      *
212      * @param satIndex the index of the satellite in the list.
213      */
hasAlmanacData(int satIndex)214     public boolean hasAlmanacData(int satIndex) {
215         return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_ALMANAC_DATA) != 0;
216     }
217 
218     /**
219      * Reports whether the satellite at the specified index was used in the calculation of the most
220      * recent position fix.
221      *
222      * @param satIndex the index of the satellite in the list.
223      */
usedInFix(int satIndex)224     public boolean usedInFix(int satIndex) {
225         return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_USED_IN_FIX) != 0;
226     }
227 
228     /**
229      * Reports whether a valid {@link #getCarrierFrequencyHz(int satIndex)} is available.
230      *
231      * @param satIndex the index of the satellite in the list.
232      */
hasCarrierFrequencyHz(int satIndex)233     public boolean hasCarrierFrequencyHz(int satIndex) {
234         return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) != 0;
235     }
236 
237     /**
238      * Gets the carrier frequency of the signal tracked.
239      *
240      * <p>For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz,
241      * L5 = 1176.45 MHz, varying GLO channels, etc. If the field is not set, it is the primary
242      * common use central frequency, e.g. L1 = 1575.45 MHz for GPS.
243      *
244      * For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two measurements
245      * will be reported for this same satellite, in one all the values related to L1 will be filled,
246      * and in the other all of the values related to L5 will be filled.
247      *
248      * <p>The value is only available if {@link #hasCarrierFrequencyHz(int satIndex)} is {@code true}.
249      *
250      * @param satIndex the index of the satellite in the list.
251      *
252      * @return the carrier frequency of the signal tracked in Hz.
253      */
getCarrierFrequencyHz(int satIndex)254     public float getCarrierFrequencyHz(int satIndex) {
255         return mCarrierFrequencies[satIndex];
256     }
257 
258     /**
259      * Returns the string representation of a constellation type. For example,
260      * {@link #CONSTELLATION_GPS} is represented by the string GPS.
261      *
262      * @param constellationType the constellation type.
263      * @return the string representation.
264      * @hide
265      */
266     @NonNull
constellationTypeToString(@onstellationType int constellationType)267     public static String constellationTypeToString(@ConstellationType int constellationType) {
268         switch (constellationType) {
269             case CONSTELLATION_UNKNOWN:
270                 return "UNKNOWN";
271             case CONSTELLATION_GPS:
272                 return "GPS";
273             case CONSTELLATION_SBAS:
274                 return "SBAS";
275             case CONSTELLATION_GLONASS:
276                 return "GLONASS";
277             case CONSTELLATION_QZSS:
278                 return "QZSS";
279             case CONSTELLATION_BEIDOU:
280                 return "BEIDOU";
281             case CONSTELLATION_GALILEO:
282                 return "GALILEO";
283             case CONSTELLATION_IRNSS:
284                 return "IRNSS";
285             default:
286                 return Integer.toString(constellationType);
287         }
288     }
289 }
290