• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.FlaggedApi;
20 import android.annotation.FloatRange;
21 import android.annotation.IntRange;
22 import android.annotation.NonNull;
23 import android.annotation.SystemApi;
24 import android.location.GlonassSatelliteEphemeris.GlonassHealthStatus;
25 import android.location.flags.Flags;
26 import android.os.Parcel;
27 import android.os.Parcelable;
28 
29 import com.android.internal.util.Preconditions;
30 
31 import java.util.ArrayList;
32 import java.util.Collections;
33 import java.util.List;
34 
35 /**
36  * A class contains Glonass almanac data.
37  *
38  * <p>This is defined in Glonass ICD v5.1 section 4.5.
39  *
40  * @hide
41  */
42 @FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
43 @SystemApi
44 public final class GlonassAlmanac implements Parcelable {
45 
46     /** Almanac issue date in milliseconds (UTC) */
47     private final long mIssueDateMillis;
48 
49     /** List of GlonassSatelliteAlmanacs. */
50     @NonNull private final List<GlonassSatelliteAlmanac> mSatelliteAlmanacs;
51 
52     /**
53      * Constructor for GlonassAlmanac.
54      *
55      * @param issueDateMillis The almanac issue date in milliseconds (UTC).
56      * @param satelliteAlmanacs The list of GlonassSatelliteAlmanac.
57      */
GlonassAlmanac( @ntRangefrom = 0) long issueDateMillis, @NonNull List<GlonassSatelliteAlmanac> satelliteAlmanacs)58     public GlonassAlmanac(
59             @IntRange(from = 0) long issueDateMillis,
60             @NonNull List<GlonassSatelliteAlmanac> satelliteAlmanacs) {
61         Preconditions.checkArgument(issueDateMillis >= 0);
62         Preconditions.checkNotNull(satelliteAlmanacs, "satelliteAlmanacs cannot be null");
63         mIssueDateMillis = issueDateMillis;
64         mSatelliteAlmanacs = Collections.unmodifiableList(new ArrayList<>(satelliteAlmanacs));
65     }
66 
67     /** Returns the almanac issue date in milliseconds (UTC). */
68     @IntRange(from = 0)
getIssueDateMillis()69     public long getIssueDateMillis() {
70         return mIssueDateMillis;
71     }
72 
73     /** Returns the list of GlonassSatelliteAlmanacs. */
74     @NonNull
getSatelliteAlmanacs()75     public List<GlonassSatelliteAlmanac> getSatelliteAlmanacs() {
76         return mSatelliteAlmanacs;
77     }
78 
79     @Override
describeContents()80     public int describeContents() {
81         return 0;
82     }
83 
84     @Override
writeToParcel(@onNull Parcel dest, int flags)85     public void writeToParcel(@NonNull Parcel dest, int flags) {
86         dest.writeLong(mIssueDateMillis);
87         dest.writeTypedList(mSatelliteAlmanacs);
88     }
89 
90     public static final @NonNull Parcelable.Creator<GlonassAlmanac> CREATOR =
91             new Parcelable.Creator<GlonassAlmanac>() {
92                 @Override
93                 public GlonassAlmanac createFromParcel(@NonNull Parcel in) {
94                     long issueDateMillis = in.readLong();
95                     List<GlonassSatelliteAlmanac> satelliteAlmanacs = new ArrayList<>();
96                     in.readTypedList(satelliteAlmanacs, GlonassSatelliteAlmanac.CREATOR);
97                     return new GlonassAlmanac(issueDateMillis, satelliteAlmanacs);
98                 }
99 
100                 @Override
101                 public GlonassAlmanac[] newArray(int size) {
102                     return new GlonassAlmanac[size];
103                 }
104             };
105 
106     @Override
107     @NonNull
toString()108     public String toString() {
109         StringBuilder builder = new StringBuilder("GlonassAlmanac[");
110         builder.append("issueDateMillis = ").append(mIssueDateMillis);
111         builder.append(", satelliteAlmanacs = ").append(mSatelliteAlmanacs);
112         builder.append("]");
113         return builder.toString();
114     }
115 
116     /**
117      * A class contains Glonass satellite almanac data.
118      *
119      * <p>This is defined in Glonass ICD v5.1 section 4.5.
120      */
121     public static final class GlonassSatelliteAlmanac implements Parcelable {
122         /** Slot number. */
123         private final int mSlotNumber;
124 
125         /** Satellite health status. */
126         private final @GlonassHealthStatus int mHealthState;
127 
128         /** Frequency channel number. */
129         private final int mFrequencyChannelNumber;
130 
131         /** Calendar day number within the four-year period beginning since the leap year. */
132         private final int mCalendarDayNumber;
133 
134         /** Flag to indicates if the satellite is a GLONASS-M satellitee. */
135         private final boolean mGlonassM;
136 
137         /** Coarse value of satellite time correction to GLONASS time in seconds. */
138         private final double mTau;
139 
140         /** Time of first ascending node passage of satellite in seconds. */
141         private final double mTLambda;
142 
143         /** Longitude of the first ascending node in semi-circles. */
144         private final double mLambda;
145 
146         /** Correction to the mean value of inclination in semi-circles. */
147         private final double mDeltaI;
148 
149         /** Correction to the mean value of the draconian period in seconds per orbital period */
150         private final double mDeltaT;
151 
152         /** Rate of change of draconian period in seconds per orbital period squared. */
153         private final double mDeltaTDot;
154 
155         /** Eccentricity. */
156         private final double mEccentricity;
157 
158         /** Argument of perigee in semi-circles. */
159         private final double mOmega;
160 
GlonassSatelliteAlmanac(Builder builder)161         private GlonassSatelliteAlmanac(Builder builder) {
162             // Allow slotNumber beyond the range to support potential future extensibility.
163             Preconditions.checkArgument(builder.mSlotNumber >= 1);
164             // Allow healthState beyond the range to support potential future extensibility.
165             Preconditions.checkArgument(builder.mHealthState >= 0);
166             Preconditions.checkArgumentInRange(
167                     builder.mFrequencyChannelNumber, 0, 31, "FrequencyChannelNumber");
168             Preconditions.checkArgumentInRange(
169                     builder.mCalendarDayNumber, 1, 1461, "CalendarDayNumber");
170             Preconditions.checkArgumentInRange(builder.mTau, -1.9e-3f, 1.9e-3f, "Tau");
171             Preconditions.checkArgumentInRange(builder.mTLambda, 0.0f, 44100.0f, "TLambda");
172             Preconditions.checkArgumentInRange(builder.mLambda, -1.0f, 1.0f, "Lambda");
173             Preconditions.checkArgumentInRange(builder.mDeltaI, -0.067f, 0.067f, "DeltaI");
174             Preconditions.checkArgumentInRange(builder.mDeltaT, -3600.0f, 3600.0f, "DeltaT");
175             Preconditions.checkArgumentInRange(builder.mDeltaTDot, -0.004f, 0.004f, "DeltaTDot");
176             Preconditions.checkArgumentInRange(builder.mEccentricity, 0.0f, 0.03f, "Eccentricity");
177             Preconditions.checkArgumentInRange(builder.mOmega, -1.0f, 1.0f, "Omega");
178             mSlotNumber = builder.mSlotNumber;
179             mHealthState = builder.mHealthState;
180             mFrequencyChannelNumber = builder.mFrequencyChannelNumber;
181             mCalendarDayNumber = builder.mCalendarDayNumber;
182             mGlonassM = builder.mGlonassM;
183             mTau = builder.mTau;
184             mTLambda = builder.mTLambda;
185             mLambda = builder.mLambda;
186             mDeltaI = builder.mDeltaI;
187             mDeltaT = builder.mDeltaT;
188             mDeltaTDot = builder.mDeltaTDot;
189             mEccentricity = builder.mEccentricity;
190             mOmega = builder.mOmega;
191         }
192 
193         /** Returns the slot number. */
194         @IntRange(from = 1, to = 25)
getSlotNumber()195         public int getSlotNumber() {
196             return mSlotNumber;
197         }
198 
199         /** Returns the satellite health status. */
getHealthState()200         public @GlonassHealthStatus int getHealthState() {
201             return mHealthState;
202         }
203 
204         /** Returns the frequency channel number. */
205         @IntRange(from = 0, to = 31)
getFrequencyChannelNumber()206         public int getFrequencyChannelNumber() {
207             return mFrequencyChannelNumber;
208         }
209 
210         /**
211          * Returns the calendar day number within the four-year period beginning since the leap
212          * year.
213          */
214         @IntRange(from = 1, to = 1461)
getCalendarDayNumber()215         public int getCalendarDayNumber() {
216             return mCalendarDayNumber;
217         }
218 
219         /** Returns true if the satellite is a GLONASS-M satellitee, false otherwise. */
isGlonassM()220         public boolean isGlonassM() {
221             return mGlonassM;
222         }
223 
224         /** Returns the coarse value of satellite time correction to GLONASS time in seconds. */
225         @FloatRange(from = -1.9e-3f, to = 1.9e-3f)
getTau()226         public double getTau() {
227             return mTau;
228         }
229 
230         /** Returns the time of first ascending node passage of satellite in seconds. */
231         @FloatRange(from = 0.0f, to = 44100.0f)
getTLambda()232         public double getTLambda() {
233             return mTLambda;
234         }
235 
236         /** Returns the longitude of the first ascending node in semi-circles. */
237         @FloatRange(from = -1.0f, to = 1.0f)
getLambda()238         public double getLambda() {
239             return mLambda;
240         }
241 
242         /** Returns the correction to the mean value of inclination in semi-circles. */
243         @FloatRange(from = -0.067f, to = 0.067f)
getDeltaI()244         public double getDeltaI() {
245             return mDeltaI;
246         }
247 
248         /**
249          * Returns the correction to the mean value of the draconian period in seconds per orbital
250          * period
251          */
252         @FloatRange(from = -3600.0f, to = 3600.0f)
getDeltaT()253         public double getDeltaT() {
254             return mDeltaT;
255         }
256 
257         /** Returns the rate of change of draconian period in seconds per orbital period squared. */
258         @FloatRange(from = -0.004f, to = 0.004f)
getDeltaTDot()259         public double getDeltaTDot() {
260             return mDeltaTDot;
261         }
262 
263         /** Returns the eccentricity. */
264         @FloatRange(from = 0.0f, to = 0.03f)
getEccentricity()265         public double getEccentricity() {
266             return mEccentricity;
267         }
268 
269         /** Returns the Argument of perigee in semi-circles. */
270         @FloatRange(from = -1.0f, to = 1.0f)
getOmega()271         public double getOmega() {
272             return mOmega;
273         }
274 
275         @Override
describeContents()276         public int describeContents() {
277             return 0;
278         }
279 
280         @Override
writeToParcel(@onNull Parcel dest, int flags)281         public void writeToParcel(@NonNull Parcel dest, int flags) {
282             dest.writeInt(mSlotNumber);
283             dest.writeInt(mHealthState);
284             dest.writeInt(mFrequencyChannelNumber);
285             dest.writeInt(mCalendarDayNumber);
286             dest.writeBoolean(mGlonassM);
287             dest.writeDouble(mTau);
288             dest.writeDouble(mTLambda);
289             dest.writeDouble(mLambda);
290             dest.writeDouble(mDeltaI);
291             dest.writeDouble(mDeltaT);
292             dest.writeDouble(mDeltaTDot);
293             dest.writeDouble(mEccentricity);
294             dest.writeDouble(mOmega);
295         }
296 
297         public static final @NonNull Parcelable.Creator<GlonassSatelliteAlmanac> CREATOR =
298                 new Parcelable.Creator<GlonassSatelliteAlmanac>() {
299                     @Override
300                     public GlonassSatelliteAlmanac createFromParcel(@NonNull Parcel source) {
301                         return new GlonassSatelliteAlmanac.Builder()
302                                 .setSlotNumber(source.readInt())
303                                 .setHealthState(source.readInt())
304                                 .setFrequencyChannelNumber(source.readInt())
305                                 .setCalendarDayNumber(source.readInt())
306                                 .setGlonassM(source.readBoolean())
307                                 .setTau(source.readDouble())
308                                 .setTLambda(source.readDouble())
309                                 .setLambda(source.readDouble())
310                                 .setDeltaI(source.readDouble())
311                                 .setDeltaT(source.readDouble())
312                                 .setDeltaTDot(source.readDouble())
313                                 .setEccentricity(source.readDouble())
314                                 .setOmega(source.readDouble())
315                                 .build();
316                     }
317 
318                     @Override
319                     public GlonassSatelliteAlmanac[] newArray(int size) {
320                         return new GlonassSatelliteAlmanac[size];
321                     }
322                 };
323 
324         @Override
325         @NonNull
toString()326         public String toString() {
327             StringBuilder builder = new StringBuilder("GlonassSatelliteAlmanac[");
328             builder.append("slotNumber = ").append(mSlotNumber);
329             builder.append(", healthState = ").append(mHealthState);
330             builder.append(", frequencyChannelNumber = ").append(mFrequencyChannelNumber);
331             builder.append(", calendarDayNumber = ").append(mCalendarDayNumber);
332             builder.append(", glonassM = ").append(mGlonassM);
333             builder.append(", tau = ").append(mTau);
334             builder.append(", tLambda = ").append(mTLambda);
335             builder.append(", lambda = ").append(mLambda);
336             builder.append(", deltaI = ").append(mDeltaI);
337             builder.append(", deltaT = ").append(mDeltaT);
338             builder.append(", deltaTDot = ").append(mDeltaTDot);
339             builder.append(", eccentricity = ").append(mEccentricity);
340             builder.append(", omega = ").append(mOmega);
341             builder.append("]");
342             return builder.toString();
343         }
344 
345         /** Builder for {@link GlonassSatelliteAlmanac}. */
346         public static final class Builder {
347             private int mSlotNumber;
348             private int mHealthState;
349             private int mFrequencyChannelNumber;
350             private int mCalendarDayNumber;
351             private boolean mGlonassM;
352             private double mTau;
353             private double mTLambda;
354             private double mLambda;
355             private double mDeltaI;
356             private double mDeltaT;
357             private double mDeltaTDot;
358             private double mEccentricity;
359             private double mOmega;
360 
361             /** Sets the slot number. */
362             @NonNull
setSlotNumber(@ntRangefrom = 1, to = 25) int slotNumber)363             public Builder setSlotNumber(@IntRange(from = 1, to = 25) int slotNumber) {
364                 mSlotNumber = slotNumber;
365                 return this;
366             }
367 
368             /** Sets the satellite health status. */
369             @NonNull
setHealthState(@lonassHealthStatus int healthState)370             public Builder setHealthState(@GlonassHealthStatus int healthState) {
371                 mHealthState = healthState;
372                 return this;
373             }
374 
375             /** Sets the frequency channel number. */
376             @NonNull
setFrequencyChannelNumber( @ntRangefrom = 0, to = 31) int frequencyChannelNumber)377             public Builder setFrequencyChannelNumber(
378                     @IntRange(from = 0, to = 31) int frequencyChannelNumber) {
379                 mFrequencyChannelNumber = frequencyChannelNumber;
380                 return this;
381             }
382 
383             /**
384              * Sets the calendar day number within the four-year period beginning since the leap
385              * year.
386              */
387             @NonNull
setCalendarDayNumber( @ntRangefrom = 1, to = 1461) int calendarDayNumber)388             public Builder setCalendarDayNumber(
389                     @IntRange(from = 1, to = 1461) int calendarDayNumber) {
390                 mCalendarDayNumber = calendarDayNumber;
391                 return this;
392             }
393 
394             /** Sets to true if the satellite is a GLONASS-M satellitee, false otherwise. */
395             @NonNull
setGlonassM(boolean isGlonassM)396             public Builder setGlonassM(boolean isGlonassM) {
397                 this.mGlonassM = isGlonassM;
398                 return this;
399             }
400 
401             /** Sets the coarse value of satellite time correction to GLONASS time in seconds. */
402             @NonNull
setTau(@loatRangefrom = -1.9e-3f, to = 1.9e-3f) double tau)403             public Builder setTau(@FloatRange(from = -1.9e-3f, to = 1.9e-3f) double tau) {
404                 mTau = tau;
405                 return this;
406             }
407 
408             /** Sets the time of first ascending node passage of satellite in seconds. */
409             @NonNull
setTLambda(@loatRangefrom = 0.0f, to = 44100.0f) double tLambda)410             public Builder setTLambda(@FloatRange(from = 0.0f, to = 44100.0f) double tLambda) {
411                 mTLambda = tLambda;
412                 return this;
413             }
414 
415             /** Sets the longitude of the first ascending node in semi-circles. */
416             @NonNull
setLambda(@loatRangefrom = -1.0f, to = 1.0f) double lambda)417             public Builder setLambda(@FloatRange(from = -1.0f, to = 1.0f) double lambda) {
418                 mLambda = lambda;
419                 return this;
420             }
421 
422             /** Sets the correction to the mean value of inclination in semi-circles. */
423             @NonNull
setDeltaI(@loatRangefrom = -0.067f, to = 0.067f) double deltaI)424             public Builder setDeltaI(@FloatRange(from = -0.067f, to = 0.067f) double deltaI) {
425                 mDeltaI = deltaI;
426                 return this;
427             }
428 
429             /**
430              * Sets the correction to the mean value of the draconian period in seconds per orbital
431              * period.
432              */
433             @NonNull
setDeltaT(@loatRangefrom = -3600.0f, to = 3600.0f) double deltaT)434             public Builder setDeltaT(@FloatRange(from = -3600.0f, to = 3600.0f) double deltaT) {
435                 mDeltaT = deltaT;
436                 return this;
437             }
438 
439             /**
440              * Sets the rate of change of draconian period in seconds per orbital period squared.
441              */
442             @NonNull
setDeltaTDot(@loatRangefrom = -0.004f, to = 0.004f) double deltaTDot)443             public Builder setDeltaTDot(@FloatRange(from = -0.004f, to = 0.004f) double deltaTDot) {
444                 mDeltaTDot = deltaTDot;
445                 return this;
446             }
447 
448             /** Sets the eccentricity. */
449             @NonNull
setEccentricity( @loatRangefrom = 0.0f, to = 0.03f) double eccentricity)450             public Builder setEccentricity(
451                     @FloatRange(from = 0.0f, to = 0.03f) double eccentricity) {
452                 mEccentricity = eccentricity;
453                 return this;
454             }
455 
456             /** Sets the Argument of perigee in semi-circles. */
457             @NonNull
setOmega(@loatRangefrom = -1.0f, to = 1.0f) double omega)458             public Builder setOmega(@FloatRange(from = -1.0f, to = 1.0f) double omega) {
459                 mOmega = omega;
460                 return this;
461             }
462 
463             /** Builds a {@link GlonassSatelliteAlmanac}. */
464             @NonNull
build()465             public GlonassSatelliteAlmanac build() {
466                 return new GlonassSatelliteAlmanac(this);
467             }
468         }
469     }
470 }
471