Merge "Support batched requests < GNSS batched size" into sc-qpr1-dev am: f4e2f279b1 am: 63aba941b2 am: 858af30f58

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15687541

Change-Id: I11e95714c204437dcb82e22756d986be74025e95
This commit is contained in:
Soonil Nagarkar
2021-09-09 17:41:09 +00:00
committed by Automerger Merge Worker

View File

@@ -16,6 +16,7 @@
package com.android.server.location.gnss;
import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP;
import static android.location.provider.ProviderProperties.ACCURACY_FINE;
import static android.location.provider.ProviderProperties.POWER_USAGE_HIGH;
@@ -43,6 +44,8 @@ import static com.android.server.location.gnss.hal.GnssNative.GNSS_POSITION_MODE
import static com.android.server.location.gnss.hal.GnssNative.GNSS_POSITION_MODE_STANDALONE;
import static com.android.server.location.gnss.hal.GnssNative.GNSS_POSITION_RECURRENCE_PERIODIC;
import static java.lang.Math.abs;
import static java.lang.Math.max;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import android.app.AlarmManager;
@@ -83,6 +86,7 @@ import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.util.TimeUtils;
@@ -101,7 +105,9 @@ import com.android.server.location.provider.AbstractLocationProvider;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
@@ -147,6 +153,10 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
private static final long LOCATION_UPDATE_DURATION_MILLIS = 10 * 1000;
// Update duration extension multiplier for emergency REQUEST_LOCATION.
private static final int EMERGENCY_LOCATION_UPDATE_DURATION_MULTIPLIER = 3;
// maximum length gnss batching may go for (1 day)
private static final int MIN_BATCH_INTERVAL_MS = (int) DateUtils.SECOND_IN_MILLIS;
private static final long MAX_BATCH_LENGTH_MS = DateUtils.DAY_IN_MILLIS;
private static final long MAX_BATCH_TIMESTAMP_DELTA_MS = 500;
// Threadsafe class to hold stats reported in the Extras Bundle
private static class LocationExtras {
@@ -236,6 +246,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
private boolean mShutdown;
private boolean mStarted;
private boolean mBatchingStarted;
private AlarmManager.OnAlarmListener mBatchingAlarm;
private long mStartedChangedElapsedRealtime;
private int mFixInterval = 1000;
@@ -834,18 +845,15 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
mFixInterval = Integer.MAX_VALUE;
}
// requested batch size, or zero to disable batching
long batchSize =
mBatchingEnabled ? mProviderRequest.getMaxUpdateDelayMillis() / Math.max(
mFixInterval, 1) : 0;
if (batchSize < getBatchSize()) {
batchSize = 0;
}
int batchIntervalMs = max(mFixInterval, MIN_BATCH_INTERVAL_MS);
long batchLengthMs = Math.min(mProviderRequest.getMaxUpdateDelayMillis(),
MAX_BATCH_LENGTH_MS);
// apply request to GPS engine
if (batchSize > 0) {
if (mBatchingEnabled && batchLengthMs / 2 >= batchIntervalMs) {
stopNavigating();
startBatching();
mFixInterval = batchIntervalMs;
startBatching(batchLengthMs);
} else {
stopBatching();
@@ -864,7 +872,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
if (mFixInterval >= NO_FIX_TIMEOUT) {
// set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
// and our fix interval is not short
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
mAlarmManager.set(ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, TAG,
mTimeoutListener, mHandler);
}
@@ -1055,7 +1063,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
// set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
// and our fix interval is not short
if (mFixInterval >= NO_FIX_TIMEOUT) {
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
mAlarmManager.set(ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, TAG, mTimeoutListener,
mHandler);
}
@@ -1079,12 +1087,37 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
mAlarmManager.cancel(mWakeupListener);
}
private void startBatching() {
private void startBatching(long batchLengthMs) {
long batchSize = batchLengthMs / mFixInterval;
if (DEBUG) {
Log.d(TAG, "startBatching " + mFixInterval);
Log.d(TAG, "startBatching " + mFixInterval + " " + batchLengthMs);
}
if (mGnssNative.startBatch(MILLISECONDS.toNanos(mFixInterval), true)) {
mBatchingStarted = true;
if (batchSize < getBatchSize()) {
// if the batch size is smaller than the hardware batch size, use an alarm to flush
// locations as appropriate
mBatchingAlarm = () -> {
boolean flush = false;
synchronized (mLock) {
if (mBatchingAlarm != null) {
flush = true;
mAlarmManager.setExact(ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + batchLengthMs, TAG,
mBatchingAlarm, FgThread.getHandler());
}
}
if (flush) {
mGnssNative.flushBatch();
}
};
mAlarmManager.setExact(ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + batchLengthMs, TAG,
mBatchingAlarm, FgThread.getHandler());
}
} else {
Log.e(TAG, "native_start_batch failed in startBatching()");
}
@@ -1093,6 +1126,10 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
private void stopBatching() {
if (DEBUG) Log.d(TAG, "stopBatching");
if (mBatchingStarted) {
if (mBatchingAlarm != null) {
mAlarmManager.cancel(mBatchingAlarm);
mBatchingAlarm = null;
}
mGnssNative.stopBatch();
mBatchingStarted = false;
}
@@ -1109,7 +1146,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
// stop GPS until our next fix interval arrives
stopNavigating();
long now = SystemClock.elapsedRealtime();
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, TAG,
mAlarmManager.set(ELAPSED_REALTIME_WAKEUP, now + mFixInterval, TAG,
mWakeupListener, mHandler);
}
@@ -1419,16 +1456,50 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
Log.d(TAG, "Location batch of size " + locations.length + " reported");
}
if (locations.length > 0) {
// attempt to fix up timestamps if necessary
if (locations.length > 1) {
// check any realtimes outside of expected bounds
boolean fixRealtime = false;
for (int i = locations.length - 2; i >= 0; i--) {
long timeDeltaMs = locations[i + 1].getTime() - locations[i].getTime();
long realtimeDeltaMs = locations[i + 1].getElapsedRealtimeMillis()
- locations[i].getElapsedRealtimeMillis();
if (abs(timeDeltaMs - realtimeDeltaMs) > MAX_BATCH_TIMESTAMP_DELTA_MS) {
fixRealtime = true;
break;
}
}
if (fixRealtime) {
// sort for monotonically increasing time before fixing realtime - realtime will
// thus also be monotonically increasing
Arrays.sort(locations,
Comparator.comparingLong(Location::getTime));
long expectedDeltaMs =
locations[locations.length - 1].getTime()
- locations[locations.length - 1].getElapsedRealtimeMillis();
for (int i = locations.length - 2; i >= 0; i--) {
locations[i].setElapsedRealtimeNanos(
MILLISECONDS.toNanos(
max(locations[i].getTime() - expectedDeltaMs, 0)));
}
} else {
// sort for monotonically increasing realttime
Arrays.sort(locations,
Comparator.comparingLong(Location::getElapsedRealtimeNanos));
}
}
reportLocation(LocationResult.wrap(locations).validate());
}
Runnable[] listeners;
synchronized (mLock) {
listeners = mFlushListeners.toArray(new Runnable[0]);
mFlushListeners.clear();
}
if (locations.length > 0) {
reportLocation(LocationResult.wrap(locations).validate());
}
for (Runnable listener : listeners) {
listener.run();
}