blob: 37657435b98a68513f93bc3a6f04a0a81fff74ea [file]
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.location;
import android.annotation.FlaggedApi;
import android.annotation.FloatRange;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.location.GlonassSatelliteEphemeris.GlonassHealthStatus;
import android.location.flags.Flags;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.Preconditions;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* A class contains Glonass almanac data.
*
* <p>This is defined in Glonass ICD v5.1 section 4.5.
*
* @hide
*/
@FlaggedApi(Flags.FLAG_GNSS_ASSISTANCE_INTERFACE)
@SystemApi
public final class GlonassAlmanac implements Parcelable {
/** Almanac issue date in milliseconds (UTC) */
private final long mIssueDateMillis;
/** List of GlonassSatelliteAlmanacs. */
@NonNull private final List<GlonassSatelliteAlmanac> mSatelliteAlmanacs;
/**
* Constructor for GlonassAlmanac.
*
* @param issueDateMillis The almanac issue date in milliseconds (UTC).
* @param satelliteAlmanacs The list of GlonassSatelliteAlmanac.
*/
public GlonassAlmanac(
@IntRange(from = 0) long issueDateMillis,
@NonNull List<GlonassSatelliteAlmanac> satelliteAlmanacs) {
Preconditions.checkArgument(issueDateMillis >= 0);
Preconditions.checkNotNull(satelliteAlmanacs, "satelliteAlmanacs cannot be null");
mIssueDateMillis = issueDateMillis;
mSatelliteAlmanacs = Collections.unmodifiableList(new ArrayList<>(satelliteAlmanacs));
}
/** Returns the almanac issue date in milliseconds (UTC). */
@IntRange(from = 0)
public long getIssueDateMillis() {
return mIssueDateMillis;
}
/** Returns the list of GlonassSatelliteAlmanacs. */
@NonNull
public List<GlonassSatelliteAlmanac> getSatelliteAlmanacs() {
return mSatelliteAlmanacs;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeLong(mIssueDateMillis);
dest.writeTypedList(mSatelliteAlmanacs);
}
public static final @NonNull Parcelable.Creator<GlonassAlmanac> CREATOR =
new Parcelable.Creator<GlonassAlmanac>() {
@Override
public GlonassAlmanac createFromParcel(@NonNull Parcel in) {
long issueDateMillis = in.readLong();
List<GlonassSatelliteAlmanac> satelliteAlmanacs = new ArrayList<>();
in.readTypedList(satelliteAlmanacs, GlonassSatelliteAlmanac.CREATOR);
return new GlonassAlmanac(issueDateMillis, satelliteAlmanacs);
}
@Override
public GlonassAlmanac[] newArray(int size) {
return new GlonassAlmanac[size];
}
};
@Override
@NonNull
public String toString() {
StringBuilder builder = new StringBuilder("GlonassAlmanac[");
builder.append("issueDateMillis = ").append(mIssueDateMillis);
builder.append(", satelliteAlmanacs = ").append(mSatelliteAlmanacs);
builder.append("]");
return builder.toString();
}
/**
* A class contains Glonass satellite almanac data.
*
* <p>This is defined in Glonass ICD v5.1 section 4.5.
*/
public static final class GlonassSatelliteAlmanac implements Parcelable {
/** Slot number. */
private final int mSlotNumber;
/** Satellite health status. */
private final @GlonassHealthStatus int mHealthState;
/** Frequency channel number. */
private final int mFrequencyChannelNumber;
/** Calendar day number within the four-year period beginning since the leap year. */
private final int mCalendarDayNumber;
/** Flag to indicates if the satellite is a GLONASS-M satellitee. */
private final boolean mGlonassM;
/** Coarse value of satellite time correction to GLONASS time in seconds. */
private final double mTau;
/** Time of first ascending node passage of satellite in seconds. */
private final double mTLambda;
/** Longitude of the first ascending node in semi-circles. */
private final double mLambda;
/** Correction to the mean value of inclination in semi-circles. */
private final double mDeltaI;
/** Correction to the mean value of the draconian period in seconds per orbital period */
private final double mDeltaT;
/** Rate of change of draconian period in seconds per orbital period squared. */
private final double mDeltaTDot;
/** Eccentricity. */
private final double mEccentricity;
/** Argument of perigee in semi-circles. */
private final double mOmega;
private GlonassSatelliteAlmanac(Builder builder) {
// Allow slotNumber beyond the range to support potential future extensibility.
Preconditions.checkArgument(builder.mSlotNumber >= 1);
// Allow healthState beyond the range to support potential future extensibility.
Preconditions.checkArgument(builder.mHealthState >= 0);
Preconditions.checkArgumentInRange(
builder.mFrequencyChannelNumber, 0, 31, "FrequencyChannelNumber");
Preconditions.checkArgumentInRange(
builder.mCalendarDayNumber, 1, 1461, "CalendarDayNumber");
Preconditions.checkArgumentInRange(builder.mTau, -1.9e-3f, 1.9e-3f, "Tau");
Preconditions.checkArgumentInRange(builder.mTLambda, 0.0f, 44100.0f, "TLambda");
Preconditions.checkArgumentInRange(builder.mLambda, -1.0f, 1.0f, "Lambda");
Preconditions.checkArgumentInRange(builder.mDeltaI, -0.067f, 0.067f, "DeltaI");
Preconditions.checkArgumentInRange(builder.mDeltaT, -3600.0f, 3600.0f, "DeltaT");
Preconditions.checkArgumentInRange(builder.mDeltaTDot, -0.004f, 0.004f, "DeltaTDot");
Preconditions.checkArgumentInRange(builder.mEccentricity, 0.0f, 0.03f, "Eccentricity");
Preconditions.checkArgumentInRange(builder.mOmega, -1.0f, 1.0f, "Omega");
mSlotNumber = builder.mSlotNumber;
mHealthState = builder.mHealthState;
mFrequencyChannelNumber = builder.mFrequencyChannelNumber;
mCalendarDayNumber = builder.mCalendarDayNumber;
mGlonassM = builder.mGlonassM;
mTau = builder.mTau;
mTLambda = builder.mTLambda;
mLambda = builder.mLambda;
mDeltaI = builder.mDeltaI;
mDeltaT = builder.mDeltaT;
mDeltaTDot = builder.mDeltaTDot;
mEccentricity = builder.mEccentricity;
mOmega = builder.mOmega;
}
/** Returns the slot number. */
@IntRange(from = 1, to = 25)
public int getSlotNumber() {
return mSlotNumber;
}
/** Returns the satellite health status. */
public @GlonassHealthStatus int getHealthState() {
return mHealthState;
}
/** Returns the frequency channel number. */
@IntRange(from = 0, to = 31)
public int getFrequencyChannelNumber() {
return mFrequencyChannelNumber;
}
/**
* Returns the calendar day number within the four-year period beginning since the leap
* year.
*/
@IntRange(from = 1, to = 1461)
public int getCalendarDayNumber() {
return mCalendarDayNumber;
}
/** Returns true if the satellite is a GLONASS-M satellitee, false otherwise. */
public boolean isGlonassM() {
return mGlonassM;
}
/** Returns the coarse value of satellite time correction to GLONASS time in seconds. */
@FloatRange(from = -1.9e-3f, to = 1.9e-3f)
public double getTau() {
return mTau;
}
/** Returns the time of first ascending node passage of satellite in seconds. */
@FloatRange(from = 0.0f, to = 44100.0f)
public double getTLambda() {
return mTLambda;
}
/** Returns the longitude of the first ascending node in semi-circles. */
@FloatRange(from = -1.0f, to = 1.0f)
public double getLambda() {
return mLambda;
}
/** Returns the correction to the mean value of inclination in semi-circles. */
@FloatRange(from = -0.067f, to = 0.067f)
public double getDeltaI() {
return mDeltaI;
}
/**
* Returns the correction to the mean value of the draconian period in seconds per orbital
* period
*/
@FloatRange(from = -3600.0f, to = 3600.0f)
public double getDeltaT() {
return mDeltaT;
}
/** Returns the rate of change of draconian period in seconds per orbital period squared. */
@FloatRange(from = -0.004f, to = 0.004f)
public double getDeltaTDot() {
return mDeltaTDot;
}
/** Returns the eccentricity. */
@FloatRange(from = 0.0f, to = 0.03f)
public double getEccentricity() {
return mEccentricity;
}
/** Returns the Argument of perigee in semi-circles. */
@FloatRange(from = -1.0f, to = 1.0f)
public double getOmega() {
return mOmega;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mSlotNumber);
dest.writeInt(mHealthState);
dest.writeInt(mFrequencyChannelNumber);
dest.writeInt(mCalendarDayNumber);
dest.writeBoolean(mGlonassM);
dest.writeDouble(mTau);
dest.writeDouble(mTLambda);
dest.writeDouble(mLambda);
dest.writeDouble(mDeltaI);
dest.writeDouble(mDeltaT);
dest.writeDouble(mDeltaTDot);
dest.writeDouble(mEccentricity);
dest.writeDouble(mOmega);
}
public static final @NonNull Parcelable.Creator<GlonassSatelliteAlmanac> CREATOR =
new Parcelable.Creator<GlonassSatelliteAlmanac>() {
@Override
public GlonassSatelliteAlmanac createFromParcel(@NonNull Parcel source) {
return new GlonassSatelliteAlmanac.Builder()
.setSlotNumber(source.readInt())
.setHealthState(source.readInt())
.setFrequencyChannelNumber(source.readInt())
.setCalendarDayNumber(source.readInt())
.setGlonassM(source.readBoolean())
.setTau(source.readDouble())
.setTLambda(source.readDouble())
.setLambda(source.readDouble())
.setDeltaI(source.readDouble())
.setDeltaT(source.readDouble())
.setDeltaTDot(source.readDouble())
.setEccentricity(source.readDouble())
.setOmega(source.readDouble())
.build();
}
@Override
public GlonassSatelliteAlmanac[] newArray(int size) {
return new GlonassSatelliteAlmanac[size];
}
};
@Override
@NonNull
public String toString() {
StringBuilder builder = new StringBuilder("GlonassSatelliteAlmanac[");
builder.append("slotNumber = ").append(mSlotNumber);
builder.append(", healthState = ").append(mHealthState);
builder.append(", frequencyChannelNumber = ").append(mFrequencyChannelNumber);
builder.append(", calendarDayNumber = ").append(mCalendarDayNumber);
builder.append(", glonassM = ").append(mGlonassM);
builder.append(", tau = ").append(mTau);
builder.append(", tLambda = ").append(mTLambda);
builder.append(", lambda = ").append(mLambda);
builder.append(", deltaI = ").append(mDeltaI);
builder.append(", deltaT = ").append(mDeltaT);
builder.append(", deltaTDot = ").append(mDeltaTDot);
builder.append(", eccentricity = ").append(mEccentricity);
builder.append(", omega = ").append(mOmega);
builder.append("]");
return builder.toString();
}
/** Builder for {@link GlonassSatelliteAlmanac}. */
public static final class Builder {
private int mSlotNumber;
private int mHealthState;
private int mFrequencyChannelNumber;
private int mCalendarDayNumber;
private boolean mGlonassM;
private double mTau;
private double mTLambda;
private double mLambda;
private double mDeltaI;
private double mDeltaT;
private double mDeltaTDot;
private double mEccentricity;
private double mOmega;
/** Sets the slot number. */
@NonNull
public Builder setSlotNumber(@IntRange(from = 1, to = 25) int slotNumber) {
mSlotNumber = slotNumber;
return this;
}
/** Sets the satellite health status. */
@NonNull
public Builder setHealthState(@GlonassHealthStatus int healthState) {
mHealthState = healthState;
return this;
}
/** Sets the frequency channel number. */
@NonNull
public Builder setFrequencyChannelNumber(
@IntRange(from = 0, to = 31) int frequencyChannelNumber) {
mFrequencyChannelNumber = frequencyChannelNumber;
return this;
}
/**
* Sets the calendar day number within the four-year period beginning since the leap
* year.
*/
@NonNull
public Builder setCalendarDayNumber(
@IntRange(from = 1, to = 1461) int calendarDayNumber) {
mCalendarDayNumber = calendarDayNumber;
return this;
}
/** Sets to true if the satellite is a GLONASS-M satellitee, false otherwise. */
@NonNull
public Builder setGlonassM(boolean isGlonassM) {
this.mGlonassM = isGlonassM;
return this;
}
/** Sets the coarse value of satellite time correction to GLONASS time in seconds. */
@NonNull
public Builder setTau(@FloatRange(from = -1.9e-3f, to = 1.9e-3f) double tau) {
mTau = tau;
return this;
}
/** Sets the time of first ascending node passage of satellite in seconds. */
@NonNull
public Builder setTLambda(@FloatRange(from = 0.0f, to = 44100.0f) double tLambda) {
mTLambda = tLambda;
return this;
}
/** Sets the longitude of the first ascending node in semi-circles. */
@NonNull
public Builder setLambda(@FloatRange(from = -1.0f, to = 1.0f) double lambda) {
mLambda = lambda;
return this;
}
/** Sets the correction to the mean value of inclination in semi-circles. */
@NonNull
public Builder setDeltaI(@FloatRange(from = -0.067f, to = 0.067f) double deltaI) {
mDeltaI = deltaI;
return this;
}
/**
* Sets the correction to the mean value of the draconian period in seconds per orbital
* period.
*/
@NonNull
public Builder setDeltaT(@FloatRange(from = -3600.0f, to = 3600.0f) double deltaT) {
mDeltaT = deltaT;
return this;
}
/**
* Sets the rate of change of draconian period in seconds per orbital period squared.
*/
@NonNull
public Builder setDeltaTDot(@FloatRange(from = -0.004f, to = 0.004f) double deltaTDot) {
mDeltaTDot = deltaTDot;
return this;
}
/** Sets the eccentricity. */
@NonNull
public Builder setEccentricity(
@FloatRange(from = 0.0f, to = 0.03f) double eccentricity) {
mEccentricity = eccentricity;
return this;
}
/** Sets the Argument of perigee in semi-circles. */
@NonNull
public Builder setOmega(@FloatRange(from = -1.0f, to = 1.0f) double omega) {
mOmega = omega;
return this;
}
/** Builds a {@link GlonassSatelliteAlmanac}. */
@NonNull
public GlonassSatelliteAlmanac build() {
return new GlonassSatelliteAlmanac(this);
}
}
}
}