From 1679ed09011e7756e415be9086a9f0ca5dff816b Mon Sep 17 00:00:00 2001 From: Soonil Nagarkar Date: Thu, 13 Jan 2022 10:39:11 -0800 Subject: [PATCH] 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 --- .../location/fused/FusedLocationProvider.java | 50 ++++++++++++++----- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java b/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java index 7a239af987554..068074ae1b897 100644 --- a/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java +++ b/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java @@ -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);