Skip to content

Commit 40e1baf

Browse files
Kevin TangBrian Muramatsu
authored andcommitted
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
1 parent e370c46 commit 40e1baf

File tree

1 file changed

+89
-51
lines changed

1 file changed

+89
-51
lines changed

services/java/com/android/server/location/GpsLocationProvider.java

Lines changed: 89 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import android.net.ConnectivityManager;
3636
import android.net.NetworkInfo;
3737
import android.net.Uri;
38+
import android.os.AsyncTask;
3839
import android.os.Binder;
3940
import android.os.Bundle;
4041
import android.os.Handler;
@@ -164,6 +165,8 @@ public class GpsLocationProvider implements LocationProviderInterface {
164165
private static final int UPDATE_LOCATION = 7;
165166
private static final int ADD_LISTENER = 8;
166167
private static final int REMOVE_LISTENER = 9;
168+
private static final int INJECT_NTP_TIME_FINISHED = 10;
169+
private static final int DOWNLOAD_XTRA_DATA_FINISHED = 11;
167170

168171
// Request setid
169172
private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
@@ -229,10 +232,15 @@ public GpsRequest(ProviderRequest request, WorkSource source) {
229232
// true if we have network connectivity
230233
private boolean mNetworkAvailable;
231234

235+
// states for injecting ntp and downloading xtra data
236+
private static final int STATE_PENDING_NETWORK = 0;
237+
private static final int STATE_DOWNLOADING = 1;
238+
private static final int STATE_IDLE = 2;
239+
232240
// flags to trigger NTP or XTRA data download when network becomes available
233241
// initialized to true so we do NTP and XTRA when the network comes up after booting
234-
private boolean mInjectNtpTimePending = true;
235-
private boolean mDownloadXtraDataPending = true;
242+
private int mInjectNtpTimePending = STATE_PENDING_NETWORK;
243+
private int mDownloadXtraDataPending = STATE_PENDING_NETWORK;
236244

237245
// set to true if the GPS engine does not do on-demand NTP time requests
238246
private boolean mPeriodicTimeInjection;
@@ -569,81 +577,105 @@ private void handleUpdateNetworkState(int state, NetworkInfo info) {
569577
}
570578

571579
if (mNetworkAvailable) {
572-
if (mInjectNtpTimePending) {
580+
if (mInjectNtpTimePending == STATE_PENDING_NETWORK) {
573581
sendMessage(INJECT_NTP_TIME, 0, null);
574582
}
575-
if (mDownloadXtraDataPending) {
583+
if (mDownloadXtraDataPending == STATE_PENDING_NETWORK) {
576584
sendMessage(DOWNLOAD_XTRA_DATA, 0, null);
577585
}
578586
}
579587
}
580588

581589
private void handleInjectNtpTime() {
590+
if (mInjectNtpTimePending == STATE_DOWNLOADING) {
591+
// already downloading data
592+
return;
593+
}
582594
if (!mNetworkAvailable) {
583595
// try again when network is up
584-
mInjectNtpTimePending = true;
596+
mInjectNtpTimePending = STATE_PENDING_NETWORK;
585597
return;
586598
}
587-
mInjectNtpTimePending = false;
599+
mInjectNtpTimePending = STATE_DOWNLOADING;
588600

589-
long delay;
601+
AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
602+
@Override
603+
public void run() {
604+
long delay;
590605

591-
// force refresh NTP cache when outdated
592-
if (mNtpTime.getCacheAge() >= NTP_INTERVAL) {
593-
mNtpTime.forceRefresh();
594-
}
606+
// force refresh NTP cache when outdated
607+
if (mNtpTime.getCacheAge() >= NTP_INTERVAL) {
608+
mNtpTime.forceRefresh();
609+
}
595610

596-
// only update when NTP time is fresh
597-
if (mNtpTime.getCacheAge() < NTP_INTERVAL) {
598-
long time = mNtpTime.getCachedNtpTime();
599-
long timeReference = mNtpTime.getCachedNtpTimeReference();
600-
long certainty = mNtpTime.getCacheCertainty();
601-
long now = System.currentTimeMillis();
602-
603-
Log.d(TAG, "NTP server returned: "
604-
+ time + " (" + new Date(time)
605-
+ ") reference: " + timeReference
606-
+ " certainty: " + certainty
607-
+ " system time offset: " + (time - now));
608-
609-
native_inject_time(time, timeReference, (int) certainty);
610-
delay = NTP_INTERVAL;
611-
} else {
612-
if (DEBUG) Log.d(TAG, "requestTime failed");
613-
delay = RETRY_INTERVAL;
614-
}
611+
// only update when NTP time is fresh
612+
if (mNtpTime.getCacheAge() < NTP_INTERVAL) {
613+
long time = mNtpTime.getCachedNtpTime();
614+
long timeReference = mNtpTime.getCachedNtpTimeReference();
615+
long certainty = mNtpTime.getCacheCertainty();
616+
long now = System.currentTimeMillis();
617+
618+
Log.d(TAG, "NTP server returned: "
619+
+ time + " (" + new Date(time)
620+
+ ") reference: " + timeReference
621+
+ " certainty: " + certainty
622+
+ " system time offset: " + (time - now));
623+
624+
native_inject_time(time, timeReference, (int) certainty);
625+
delay = NTP_INTERVAL;
626+
} else {
627+
if (DEBUG) Log.d(TAG, "requestTime failed");
628+
delay = RETRY_INTERVAL;
629+
}
615630

616-
if (mPeriodicTimeInjection) {
617-
// send delayed message for next NTP injection
618-
// since this is delayed and not urgent we do not hold a wake lock here
619-
mHandler.removeMessages(INJECT_NTP_TIME);
620-
mHandler.sendMessageDelayed(Message.obtain(mHandler, INJECT_NTP_TIME), delay);
621-
}
631+
mHandler.sendMessage(Message.obtain(mHandler, INJECT_NTP_TIME_FINISHED));
632+
633+
if (mPeriodicTimeInjection) {
634+
// send delayed message for next NTP injection
635+
// since this is delayed and not urgent we do not hold a wake lock here
636+
mHandler.removeMessages(INJECT_NTP_TIME);
637+
mHandler.sendMessageDelayed(Message.obtain(mHandler, INJECT_NTP_TIME), delay);
638+
}
639+
}
640+
});
622641
}
623642

624643
private void handleDownloadXtraData() {
644+
if (mDownloadXtraDataPending == STATE_DOWNLOADING) {
645+
// already downloading data
646+
return;
647+
}
625648
if (!mNetworkAvailable) {
626649
// try again when network is up
627-
mDownloadXtraDataPending = true;
650+
mDownloadXtraDataPending = STATE_PENDING_NETWORK;
628651
return;
629652
}
630-
mDownloadXtraDataPending = false;
653+
mDownloadXtraDataPending = STATE_DOWNLOADING;
654+
655+
AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
656+
@Override
657+
public void run() {
658+
GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mContext, mProperties);
659+
byte[] data = xtraDownloader.downloadXtraData();
660+
if (data != null) {
661+
if (DEBUG) {
662+
Log.d(TAG, "calling native_inject_xtra_data");
663+
}
664+
native_inject_xtra_data(data, data.length);
665+
}
631666

667+
mHandler.sendMessage(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA_FINISHED));
632668

633-
GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mContext, mProperties);
634-
byte[] data = xtraDownloader.downloadXtraData();
635-
if (data != null) {
636-
if (DEBUG) {
637-
Log.d(TAG, "calling native_inject_xtra_data");
669+
if (data == null) {
670+
// try again later
671+
// since this is delayed and not urgent we do not hold a wake lock here
672+
mHandler.removeMessages(DOWNLOAD_XTRA_DATA);
673+
mHandler.sendMessageDelayed(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA),
674+
RETRY_INTERVAL);
675+
}
638676
}
639-
native_inject_xtra_data(data, data.length);
640-
} else {
641-
// try again later
642-
// since this is delayed and not urgent we do not hold a wake lock here
643-
mHandler.removeMessages(DOWNLOAD_XTRA_DATA);
644-
mHandler.sendMessageDelayed(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA),
645-
RETRY_INTERVAL);
646-
}
677+
678+
});
647679
}
648680

649681
private void handleUpdateLocation(Location location) {
@@ -1474,6 +1506,12 @@ public void handleMessage(Message msg) {
14741506
handleDownloadXtraData();
14751507
}
14761508
break;
1509+
case INJECT_NTP_TIME_FINISHED:
1510+
mInjectNtpTimePending = STATE_IDLE;
1511+
break;
1512+
case DOWNLOAD_XTRA_DATA_FINISHED:
1513+
mDownloadXtraDataPending = STATE_IDLE;
1514+
break;
14771515
case UPDATE_LOCATION:
14781516
handleUpdateLocation((Location)msg.obj);
14791517
break;

0 commit comments

Comments
 (0)