Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1679ed09 authored by Soonil Nagarkar's avatar Soonil Nagarkar
Browse files

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
parent 6f01f95a
Loading
Loading
Loading
Loading
+38 −12
Original line number Diff line number Diff line
@@ -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,29 +126,48 @@ 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();
                }
            }
            };

            if (mGpsPresent) {
                mGpsListener.flush(wrapper);
            }
            if (mNlpPresent) {
                mNetworkListener.flush(wrapper);
            }
        }
    }

    @Override
    public void onSendExtraCommand(String command, @Nullable Bundle extras) {}

    @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);