Fix newly discovered crashes in FusedLocationProvider

We recently discovered the FusedLocationProvider doesn't function well
when the gps or network provider is missing, but these errors were
previously hidden. Now that the crashes are apparent, deal with cases
where these providers may not be present.

Bug: 214358333
Test: presubmits
Change-Id: I660592bee4897fc335f5fe1d2f2499c047b62e66
This commit is contained in:
Soonil Nagarkar
2022-01-13 10:39:11 -08:00
parent 6f01f95a53
commit 1679ed0901

View File

@@ -44,6 +44,7 @@ import com.android.internal.annotations.GuardedBy;
import java.io.PrintWriter;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
/** Basic fused location provider implementation. */
public class FusedLocationProvider extends LocationProviderBase {
@@ -68,6 +69,12 @@ public class FusedLocationProvider extends LocationProviderBase {
private final ChildLocationListener mNetworkListener;
private final BroadcastReceiver mUserChangeReceiver;
@GuardedBy("mLock")
boolean mGpsPresent;
@GuardedBy("mLock")
boolean mNlpPresent;
@GuardedBy("mLock")
private ProviderRequest mRequest;
@@ -119,19 +126,28 @@ public class FusedLocationProvider extends LocationProviderBase {
@Override
public void onFlush(OnFlushCompleteCallback callback) {
OnFlushCompleteCallback wrapper = new OnFlushCompleteCallback() {
private int mFlushCount = 2;
synchronized (mLock) {
AtomicInteger flushCount = new AtomicInteger(0);
if (mGpsPresent) {
flushCount.incrementAndGet();
}
if (mNlpPresent) {
flushCount.incrementAndGet();
}
@Override
public void onFlushComplete() {
if (--mFlushCount == 0) {
OnFlushCompleteCallback wrapper = () -> {
if (flushCount.decrementAndGet() == 0) {
callback.onFlushComplete();
}
}
};
};
mGpsListener.flush(wrapper);
mNetworkListener.flush(wrapper);
if (mGpsPresent) {
mGpsListener.flush(wrapper);
}
if (mNlpPresent) {
mNetworkListener.flush(wrapper);
}
}
}
@Override
@@ -139,9 +155,19 @@ public class FusedLocationProvider extends LocationProviderBase {
@GuardedBy("mLock")
private void updateRequirementsLocked() {
long gpsInterval = mRequest.getQuality() < QUALITY_LOW_POWER ? mRequest.getIntervalMillis()
: INTERVAL_DISABLED;
long networkInterval = mRequest.getIntervalMillis();
// it's possible there might be race conditions on device start where a provider doesn't
// appear to be present yet, but once a provider is present it shouldn't go away.
if (!mGpsPresent) {
mGpsPresent = mLocationManager.hasProvider(GPS_PROVIDER);
}
if (!mNlpPresent) {
mNlpPresent = mLocationManager.hasProvider(NETWORK_PROVIDER);
}
long gpsInterval =
mGpsPresent && (!mNlpPresent || mRequest.getQuality() < QUALITY_LOW_POWER)
? mRequest.getIntervalMillis() : INTERVAL_DISABLED;
long networkInterval = mNlpPresent ? mRequest.getIntervalMillis() : INTERVAL_DISABLED;
mGpsListener.resetProviderRequest(gpsInterval);
mNetworkListener.resetProviderRequest(networkInterval);