[go: nahoru, domu]

blob: 3ac9610ff046dcc0c5098f88de80e35f68fb0d69 [file] [log] [blame]
/*
* Copyright 2019 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 androidx.core.location;
import static androidx.annotation.RestrictTo.Scope.LIBRARY;
import android.location.GpsSatellite;
import android.location.GpsStatus;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import androidx.annotation.GuardedBy;
import androidx.annotation.RestrictTo;
import androidx.core.util.Preconditions;
import java.util.Iterator;
/** @hide */
@RestrictTo(LIBRARY)
class GpsStatusWrapper extends GnssStatusCompat {
private static final int GPS_PRN_OFFSET = 0;
private static final int GPS_PRN_COUNT = 32;
private static final int SBAS_PRN_MIN = 33;
private static final int SBAS_PRN_MAX = 64;
private static final int SBAS_PRN_OFFSET = -87;
private static final int GLONASS_PRN_OFFSET = 64;
private static final int GLONASS_PRN_COUNT = 24;
private static final int QZSS_SVID_MIN = 193;
private static final int QZSS_SVID_MAX = 200;
private static final int BEIDOU_PRN_OFFSET = 200;
private static final int BEIDOU_PRN_COUNT = 35;
private final GpsStatus mWrapped;
@GuardedBy("mWrapped")
private int mCachedSatelliteCount;
@GuardedBy("mWrapped")
private Iterator<GpsSatellite> mCachedIterator;
@GuardedBy("mWrapped")
private int mCachedIteratorPosition;
@GuardedBy("mWrapped")
private GpsSatellite mCachedSatellite;
GpsStatusWrapper(GpsStatus gpsStatus) {
mWrapped = Preconditions.checkNotNull(gpsStatus);
mCachedSatelliteCount = -1;
mCachedIterator = mWrapped.getSatellites().iterator();
mCachedIteratorPosition = -1;
mCachedSatellite = null;
}
@Override
public int getSatelliteCount() {
synchronized (mWrapped) {
if (mCachedSatelliteCount == -1) {
for (@SuppressWarnings("unused") GpsSatellite ignored : mWrapped.getSatellites()) {
mCachedSatelliteCount++;
}
mCachedSatelliteCount++;
}
return mCachedSatelliteCount;
}
}
@Override
public int getConstellationType(int satelliteIndex) {
if (VERSION.SDK_INT < VERSION_CODES.N) {
return CONSTELLATION_GPS;
} else {
return getConstellationFromPrn(getSatellite(satelliteIndex).getPrn());
}
}
@Override
public int getSvid(int satelliteIndex) {
if (VERSION.SDK_INT < VERSION_CODES.N) {
return getSatellite(satelliteIndex).getPrn();
} else {
return getSvidFromPrn(getSatellite(satelliteIndex).getPrn());
}
}
@Override
public float getCn0DbHz(int satelliteIndex) {
return getSatellite(satelliteIndex).getSnr();
}
@Override
public float getElevationDegrees(int satelliteIndex) {
return getSatellite(satelliteIndex).getElevation();
}
@Override
public float getAzimuthDegrees(int satelliteIndex) {
return getSatellite(satelliteIndex).getAzimuth();
}
@Override
public boolean hasEphemerisData(int satelliteIndex) {
return getSatellite(satelliteIndex).hasEphemeris();
}
@Override
public boolean hasAlmanacData(int satelliteIndex) {
return getSatellite(satelliteIndex).hasAlmanac();
}
@Override
public boolean usedInFix(int satelliteIndex) {
return getSatellite(satelliteIndex).usedInFix();
}
@Override
public boolean hasCarrierFrequencyHz(int satelliteIndex) {
return false;
}
@Override
public float getCarrierFrequencyHz(int satelliteIndex) {
throw new UnsupportedOperationException();
}
private GpsSatellite getSatellite(int satelliteIndex) {
GpsSatellite satellite;
synchronized (mWrapped) {
if (satelliteIndex < mCachedIteratorPosition) {
mCachedIterator = mWrapped.getSatellites().iterator();
mCachedIteratorPosition = -1;
}
while (mCachedIteratorPosition < satelliteIndex) {
mCachedIteratorPosition++;
if (!mCachedIterator.hasNext()) {
mCachedSatellite = null;
break;
} else {
mCachedSatellite = mCachedIterator.next();
}
}
satellite = mCachedSatellite;
}
return Preconditions.checkNotNull(satellite);
}
private static int getConstellationFromPrn(int prn) {
if (prn > GPS_PRN_OFFSET && prn <= GPS_PRN_OFFSET + GPS_PRN_COUNT) {
return CONSTELLATION_GPS;
} else if (prn >= SBAS_PRN_MIN && prn <= SBAS_PRN_MAX) {
return CONSTELLATION_SBAS;
} else if (prn > GLONASS_PRN_OFFSET && prn <= GLONASS_PRN_OFFSET + GLONASS_PRN_COUNT) {
return CONSTELLATION_GLONASS;
} else if (prn > BEIDOU_PRN_OFFSET && prn <= BEIDOU_PRN_OFFSET + BEIDOU_PRN_COUNT) {
return CONSTELLATION_BEIDOU;
} else if (prn >= QZSS_SVID_MIN && prn <= QZSS_SVID_MAX) {
return CONSTELLATION_QZSS;
} else {
return CONSTELLATION_UNKNOWN;
}
}
private static int getSvidFromPrn(int prn) {
switch (getConstellationFromPrn(prn)) {
case CONSTELLATION_SBAS:
prn -= SBAS_PRN_OFFSET;
break;
case CONSTELLATION_GLONASS:
prn -= GLONASS_PRN_OFFSET;
break;
case CONSTELLATION_BEIDOU:
prn -= BEIDOU_PRN_OFFSET;
break;
}
return prn;
}
}