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

Commit 40e1bafc authored by Kevin Tang's avatar Kevin Tang Committed by Brian Muramatsu
Browse files

Fix GPS provider thread blocked by NTP and XTRA

Currently, the NTP and XTRA downloads block on the GPS provider thread.
This could potentially block the next tasks for over a minute of time.
If the upcoming task happens to be AGPS, AGPS will time out.

Placed the NTP and XTRA downloads in separate threads.

Bug: 6980618

Change-Id: I57a6aaf5348212bc1246813f6d941da7d5b19136
parent e370c468
Loading
Loading
Loading
Loading
+89 −51
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.location.LocationProvider;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
@@ -164,6 +165,8 @@ public class GpsLocationProvider implements LocationProviderInterface {
    private static final int UPDATE_LOCATION = 7;
    private static final int ADD_LISTENER = 8;
    private static final int REMOVE_LISTENER = 9;
    private static final int INJECT_NTP_TIME_FINISHED = 10;
    private static final int DOWNLOAD_XTRA_DATA_FINISHED = 11;

    // Request setid
    private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
@@ -229,10 +232,15 @@ public class GpsLocationProvider implements LocationProviderInterface {
    // true if we have network connectivity
    private boolean mNetworkAvailable;

    // states for injecting ntp and downloading xtra data
    private static final int STATE_PENDING_NETWORK = 0;
    private static final int STATE_DOWNLOADING = 1;
    private static final int STATE_IDLE = 2;

    // flags to trigger NTP or XTRA data download when network becomes available
    // initialized to true so we do NTP and XTRA when the network comes up after booting
    private boolean mInjectNtpTimePending = true;
    private boolean mDownloadXtraDataPending = true;
    private int mInjectNtpTimePending = STATE_PENDING_NETWORK;
    private int mDownloadXtraDataPending = STATE_PENDING_NETWORK;

    // set to true if the GPS engine does not do on-demand NTP time requests
    private boolean mPeriodicTimeInjection;
@@ -569,23 +577,30 @@ public class GpsLocationProvider implements LocationProviderInterface {
        }

        if (mNetworkAvailable) {
            if (mInjectNtpTimePending) {
            if (mInjectNtpTimePending == STATE_PENDING_NETWORK) {
                sendMessage(INJECT_NTP_TIME, 0, null);
            }
            if (mDownloadXtraDataPending) {
            if (mDownloadXtraDataPending == STATE_PENDING_NETWORK) {
                sendMessage(DOWNLOAD_XTRA_DATA, 0, null);
            }
        }
    }

    private void handleInjectNtpTime() {
        if (mInjectNtpTimePending == STATE_DOWNLOADING) {
            // already downloading data
            return;
        }
        if (!mNetworkAvailable) {
            // try again when network is up
            mInjectNtpTimePending = true;
            mInjectNtpTimePending = STATE_PENDING_NETWORK;
            return;
        }
        mInjectNtpTimePending = false;
        mInjectNtpTimePending = STATE_DOWNLOADING;

        AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
            @Override
            public void run() {
                long delay;

                // force refresh NTP cache when outdated
@@ -613,6 +628,8 @@ public class GpsLocationProvider implements LocationProviderInterface {
                    delay = RETRY_INTERVAL;
                }

                mHandler.sendMessage(Message.obtain(mHandler, INJECT_NTP_TIME_FINISHED));

                if (mPeriodicTimeInjection) {
                    // send delayed message for next NTP injection
                    // since this is delayed and not urgent we do not hold a wake lock here
@@ -620,16 +637,24 @@ public class GpsLocationProvider implements LocationProviderInterface {
                    mHandler.sendMessageDelayed(Message.obtain(mHandler, INJECT_NTP_TIME), delay);
                }
            }
        });
    }

    private void handleDownloadXtraData() {
        if (mDownloadXtraDataPending == STATE_DOWNLOADING) {
            // already downloading data
            return;
        }
        if (!mNetworkAvailable) {
            // try again when network is up
            mDownloadXtraDataPending = true;
            mDownloadXtraDataPending = STATE_PENDING_NETWORK;
            return;
        }
        mDownloadXtraDataPending = false;

        mDownloadXtraDataPending = STATE_DOWNLOADING;

        AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
            @Override
            public void run() {
                GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mContext, mProperties);
                byte[] data = xtraDownloader.downloadXtraData();
                if (data != null) {
@@ -637,7 +662,11 @@ public class GpsLocationProvider implements LocationProviderInterface {
                        Log.d(TAG, "calling native_inject_xtra_data");
                    }
                    native_inject_xtra_data(data, data.length);
        } else {
                }

                mHandler.sendMessage(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA_FINISHED));

                if (data == null) {
                    // try again later
                    // since this is delayed and not urgent we do not hold a wake lock here
                    mHandler.removeMessages(DOWNLOAD_XTRA_DATA);
@@ -646,6 +675,9 @@ public class GpsLocationProvider implements LocationProviderInterface {
                }
            }

        });
    }

    private void handleUpdateLocation(Location location) {
        if (location.hasAccuracy()) {
            native_inject_location(location.getLatitude(), location.getLongitude(),
@@ -1474,6 +1506,12 @@ public class GpsLocationProvider implements LocationProviderInterface {
                        handleDownloadXtraData();
                    }
                    break;
                case INJECT_NTP_TIME_FINISHED:
                    mInjectNtpTimePending = STATE_IDLE;
                    break;
                case DOWNLOAD_XTRA_DATA_FINISHED:
                    mDownloadXtraDataPending = STATE_IDLE;
                    break;
                case UPDATE_LOCATION:
                    handleUpdateLocation((Location)msg.obj);
                    break;