Merge "Add GNSS HAL v3.0 (framework/base)"

This commit is contained in:
TreeHugger Robot
2020-06-24 00:58:11 +00:00
committed by Android (Google) Code Review
6 changed files with 143 additions and 73 deletions

View File

@@ -688,7 +688,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
if (mDownloadPsdsDataPending == STATE_PENDING_NETWORK) {
if (mSupportsPsds) {
// Download only if supported, (prevents an unnecessary on-boot download)
psdsDownloadRequest();
psdsDownloadRequest(/* psdsType= */ GnssPsdsDownloader.LONG_TERM_PSDS_SERVER_INDEX);
}
}
}
@@ -808,7 +808,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
return false;
}
private void handleDownloadPsdsData() {
private void handleDownloadPsdsData(int psdsType) {
if (!mSupportsPsds) {
// native code reports psds not supported, don't try
Log.d(TAG, "handleDownloadPsdsData() called when PSDS not supported");
@@ -831,9 +831,9 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
}
Log.i(TAG, "WakeLock acquired by handleDownloadPsdsData()");
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
GpsPsdsDownloader psdsDownloader = new GpsPsdsDownloader(
GnssPsdsDownloader psdsDownloader = new GnssPsdsDownloader(
mGnssConfiguration.getProperties());
byte[] data = psdsDownloader.downloadPsdsData();
byte[] data = psdsDownloader.downloadPsdsData(psdsType);
if (data != null) {
if (DEBUG) Log.d(TAG, "calling native_inject_psds_data");
native_inject_psds_data(data, data.length);
@@ -844,8 +844,9 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
if (data == null) {
// try again later
// since this is delayed and not urgent we do not hold a wake lock here
mHandler.sendEmptyMessageDelayed(DOWNLOAD_PSDS_DATA,
// since this is delayed and not urgent we do not hold a wake lock her
mHandler.sendMessageDelayed(
mHandler.obtainMessage(DOWNLOAD_PSDS_DATA, psdsType, 1, null),
mPsdsBackOff.nextBackoffMillis());
}
@@ -1141,7 +1142,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
requestUtcTime();
} else if ("force_psds_injection".equals(command)) {
if (mSupportsPsds) {
psdsDownloadRequest();
psdsDownloadRequest(/* psdsType= */
GnssPsdsDownloader.LONG_TERM_PSDS_SERVER_INDEX);
}
} else {
Log.w(TAG, "sendExtraCommand: unknown command " + command);
@@ -1593,9 +1595,9 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
reportLocation(locations);
}
void psdsDownloadRequest() {
if (DEBUG) Log.d(TAG, "psdsDownloadRequest");
sendMessage(DOWNLOAD_PSDS_DATA, 0, null);
void psdsDownloadRequest(int psdsType) {
if (DEBUG) Log.d(TAG, "psdsDownloadRequest. psdsType: " + psdsType);
sendMessage(DOWNLOAD_PSDS_DATA, psdsType, null);
}
/**
@@ -1906,7 +1908,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
handleRequestLocation(msg.arg1 == 1, (boolean) msg.obj);
break;
case DOWNLOAD_PSDS_DATA:
handleDownloadPsdsData();
handleDownloadPsdsData(msg.arg1);
break;
case DOWNLOAD_PSDS_DATA_FINISHED:
mDownloadPsdsDataPending = STATE_IDLE;

View File

@@ -524,8 +524,8 @@ public class GnssManagerService implements GnssNative.Callbacks {
}
@Override
public void psdsDownloadRequest() {
mGnssLocationProvider.psdsDownloadRequest();
public void psdsDownloadRequest(int psdsType) {
mGnssLocationProvider.psdsDownloadRequest(psdsType);
}
@Override

View File

@@ -54,7 +54,7 @@ class GnssNative {
void setGnssHardwareModelName(String modelName);
void reportGnssServiceRestarted();
void reportLocationBatch(Location[] locationArray);
void psdsDownloadRequest();
void psdsDownloadRequest(int psdsType);
void reportGeofenceTransition(int geofenceId, Location location, int transition,
long transitionTimestamp);
void reportGeofenceStatus(int status, Location location);
@@ -212,8 +212,8 @@ class GnssNative {
}
@NativeEntryPoint
private void psdsDownloadRequest() {
mCallbacks.psdsDownloadRequest();
private void psdsDownloadRequest(int psdsType) {
mCallbacks.psdsDownloadRequest(psdsType);
}
@NativeEntryPoint

View File

@@ -16,6 +16,7 @@
package com.android.server.location.gnss;
import android.annotation.Nullable;
import android.net.TrafficStats;
import android.text.TextUtils;
import android.util.Log;
@@ -32,33 +33,39 @@ import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
* A class for downloading GPS PSDS data.
* A class for downloading GNSS PSDS data.
*
* {@hide}
*/
public class GpsPsdsDownloader {
class GnssPsdsDownloader {
private static final String TAG = "GpsPsdsDownloader";
private static final String TAG = "GnssPsdsDownloader";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final long MAXIMUM_CONTENT_LENGTH_BYTES = 1000000; // 1MB.
private static final String DEFAULT_USER_AGENT = "Android";
private static final int CONNECTION_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(30);
private static final int READ_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(60);
static final int LONG_TERM_PSDS_SERVER_INDEX = 1;
private static final int NORMAL_PSDS_SERVER_INDEX = 2;
private static final int REALTIME_PSDS_SERVER_INDEX = 3;
private static final int MAX_PSDS_TYPE_INDEX = 3;
private final String[] mLongTermPsdsServers;
private final String[] mPsdsServers;
// to load balance our server requests
private int mNextServerIndex;
private final String mUserAgent;
GpsPsdsDownloader(Properties properties) {
GnssPsdsDownloader(Properties properties) {
// read PSDS servers from the Properties object
int count = 0;
String server1 = properties.getProperty("XTRA_SERVER_1");
String server2 = properties.getProperty("XTRA_SERVER_2");
String server3 = properties.getProperty("XTRA_SERVER_3");
if (server1 != null) count++;
if (server2 != null) count++;
if (server3 != null) count++;
String longTermPsdsServer1 = properties.getProperty("XTRA_SERVER_1");
String longTermPsdsServer2 = properties.getProperty("XTRA_SERVER_2");
String longTermPsdsServer3 = properties.getProperty("XTRA_SERVER_3");
if (longTermPsdsServer1 != null) count++;
if (longTermPsdsServer2 != null) count++;
if (longTermPsdsServer3 != null) count++;
// Set User Agent from properties, if possible.
String agent = properties.getProperty("XTRA_USER_AGENT");
@@ -69,52 +76,74 @@ public class GpsPsdsDownloader {
}
if (count == 0) {
Log.e(TAG, "No PSDS servers were specified in the GPS configuration");
mPsdsServers = null;
Log.e(TAG, "No Long-Term PSDS servers were specified in the GnssConfiguration");
mLongTermPsdsServers = null;
} else {
mPsdsServers = new String[count];
mLongTermPsdsServers = new String[count];
count = 0;
if (server1 != null) mPsdsServers[count++] = server1;
if (server2 != null) mPsdsServers[count++] = server2;
if (server3 != null) mPsdsServers[count++] = server3;
if (longTermPsdsServer1 != null) mLongTermPsdsServers[count++] = longTermPsdsServer1;
if (longTermPsdsServer2 != null) mLongTermPsdsServers[count++] = longTermPsdsServer2;
if (longTermPsdsServer3 != null) mLongTermPsdsServers[count++] = longTermPsdsServer3;
// randomize first server
Random random = new Random();
mNextServerIndex = random.nextInt(count);
}
String normalPsdsServer = properties.getProperty("NORMAL_PSDS_SERVER");
String realtimePsdsServer = properties.getProperty("REALTIME_PSDS_SERVER");
mPsdsServers = new String[MAX_PSDS_TYPE_INDEX + 1];
mPsdsServers[NORMAL_PSDS_SERVER_INDEX] = normalPsdsServer;
mPsdsServers[REALTIME_PSDS_SERVER_INDEX] = realtimePsdsServer;
}
byte[] downloadPsdsData() {
@Nullable
byte[] downloadPsdsData(int psdsType) {
byte[] result = null;
int startIndex = mNextServerIndex;
if (mPsdsServers == null) {
if (psdsType == LONG_TERM_PSDS_SERVER_INDEX && mLongTermPsdsServers == null) {
return null;
} else if (psdsType > LONG_TERM_PSDS_SERVER_INDEX && psdsType <= MAX_PSDS_TYPE_INDEX
&& mPsdsServers[psdsType] == null) {
return null;
}
// load balance our requests among the available servers
while (result == null) {
final int oldTag = TrafficStats.getAndSetThreadStatsTag(
TrafficStatsConstants.TAG_SYSTEM_GPS);
try {
result = doDownload(mPsdsServers[mNextServerIndex]);
} finally {
TrafficStats.setThreadStatsTag(oldTag);
}
if (psdsType == LONG_TERM_PSDS_SERVER_INDEX) {
// load balance our requests among the available servers
while (result == null) {
result = doDownloadWithTrafficAccounted(mLongTermPsdsServers[mNextServerIndex]);
// increment mNextServerIndex and wrap around if necessary
mNextServerIndex++;
if (mNextServerIndex == mPsdsServers.length) {
mNextServerIndex = 0;
// increment mNextServerIndex and wrap around if necessary
mNextServerIndex++;
if (mNextServerIndex == mLongTermPsdsServers.length) {
mNextServerIndex = 0;
}
// break if we have tried all the servers
if (mNextServerIndex == startIndex) break;
}
// break if we have tried all the servers
if (mNextServerIndex == startIndex) break;
} else if (psdsType > LONG_TERM_PSDS_SERVER_INDEX && psdsType <= MAX_PSDS_TYPE_INDEX) {
result = doDownloadWithTrafficAccounted(mPsdsServers[psdsType]);
}
return result;
}
protected byte[] doDownload(String url) {
@Nullable
private byte[] doDownloadWithTrafficAccounted(String url) {
byte[] result;
final int oldTag = TrafficStats.getAndSetThreadStatsTag(
TrafficStatsConstants.TAG_SYSTEM_GPS);
try {
result = doDownload(url);
} finally {
TrafficStats.setThreadStatsTag(oldTag);
}
return result;
}
@Nullable
private byte[] doDownload(String url) {
if (DEBUG) Log.d(TAG, "Downloading PSDS data from " + url);
HttpURLConnection connection = null;
@@ -132,7 +161,7 @@ public class GpsPsdsDownloader {
connection.connect();
int statusCode = connection.getResponseCode();
if (statusCode != HttpURLConnection.HTTP_OK) {
if (DEBUG) Log.d(TAG, "HTTP error downloading gps PSDS: " + statusCode);
if (DEBUG) Log.d(TAG, "HTTP error downloading gnss PSDS: " + statusCode);
return null;
}
@@ -150,7 +179,7 @@ public class GpsPsdsDownloader {
return bytes.toByteArray();
}
} catch (IOException ioe) {
if (DEBUG) Log.d(TAG, "Error downloading gps PSDS: ", ioe);
if (DEBUG) Log.d(TAG, "Error downloading gnss PSDS: ", ioe);
} finally {
if (connection != null) {
connection.disconnect();
@@ -158,6 +187,4 @@ public class GpsPsdsDownloader {
}
return null;
}
}

View File

@@ -145,6 +145,7 @@ cc_defaults {
"android.hardware.gnss@1.1",
"android.hardware.gnss@2.0",
"android.hardware.gnss@2.1",
"android.hardware.gnss@3.0",
"android.hardware.gnss.measurement_corrections@1.0",
"android.hardware.gnss.visibility_control@1.0",
"android.hardware.graphics.bufferqueue@1.0",

View File

@@ -22,12 +22,14 @@
#include <android/hardware/gnss/1.1/IGnss.h>
#include <android/hardware/gnss/2.0/IGnss.h>
#include <android/hardware/gnss/2.1/IGnss.h>
#include <android/hardware/gnss/3.0/IGnss.h>
#include <android/hardware/gnss/1.0/IGnssMeasurement.h>
#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
#include <android/hardware/gnss/2.0/IGnssMeasurement.h>
#include <android/hardware/gnss/2.1/IGnssAntennaInfo.h>
#include <android/hardware/gnss/2.1/IGnssMeasurement.h>
#include <android/hardware/gnss/3.0/IGnssPsds.h>
#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
#include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.h>
#include <android/hardware/gnss/visibility_control/1.0/IGnssVisibilityControl.h>
@@ -159,7 +161,8 @@ using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
using android::hardware::gnss::V1_0::IGnssNi;
using android::hardware::gnss::V1_0::IGnssNiCallback;
using android::hardware::gnss::V1_0::IGnssXtra;
using android::hardware::gnss::V1_0::IGnssXtraCallback;
using android::hardware::gnss::V3_0::IGnssPsds;
using android::hardware::gnss::V3_0::IGnssPsdsCallback;
using android::hardware::gnss::V2_0::ElapsedRealtimeFlags;
@@ -182,6 +185,7 @@ using IGnss_V1_0 = android::hardware::gnss::V1_0::IGnss;
using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
using IGnss_V2_0 = android::hardware::gnss::V2_0::IGnss;
using IGnss_V2_1 = android::hardware::gnss::V2_1::IGnss;
using IGnss_V3_0 = android::hardware::gnss::V3_0::IGnss;
using IGnssCallback_V1_0 = android::hardware::gnss::V1_0::IGnssCallback;
using IGnssCallback_V2_0 = android::hardware::gnss::V2_0::IGnssCallback;
using IGnssCallback_V2_1 = android::hardware::gnss::V2_1::IGnssCallback;
@@ -240,6 +244,8 @@ sp<IGnss_V1_0> gnssHal = nullptr;
sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
sp<IGnss_V2_0> gnssHal_V2_0 = nullptr;
sp<IGnss_V2_1> gnssHal_V2_1 = nullptr;
sp<IGnss_V3_0> gnssHal_V3_0 = nullptr;
sp<IGnssPsds> gnssPsdsIface = nullptr;
sp<IGnssXtra> gnssXtraIface = nullptr;
sp<IAGnssRil_V1_0> agnssRilIface = nullptr;
sp<IAGnssRil_V2_0> agnssRilIface_V2_0 = nullptr;
@@ -918,17 +924,26 @@ Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback_V2_0::GnssSys
return Void();
}
class GnssXtraCallback : public IGnssXtraCallback {
Return<void> downloadRequestCb() override;
};
/*
* GnssXtraCallback class implements the callback methods for the IGnssXtra
* GnssPsdsCallback class implements the callback methods for the IGnssPsds
* interface.
*/
Return<void> GnssXtraCallback::downloadRequestCb() {
class GnssPsdsCallback : public IGnssPsdsCallback {
Return<void> downloadRequestCb() override;
Return<void> downloadRequestCb_3_0(int32_t psdsType) override;
};
Return<void> GnssPsdsCallback::downloadRequestCb() {
JNIEnv* env = getJniEnv();
env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest);
env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest, /* psdsType= */ 1);
checkAndClearExceptionFromCallback(env, __FUNCTION__);
return Void();
}
Return<void> GnssPsdsCallback::downloadRequestCb_3_0(int32_t psdsType) {
ALOGD("%s: %d", __func__, psdsType);
JNIEnv* env = getJniEnv();
env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest, psdsType);
checkAndClearExceptionFromCallback(env, __FUNCTION__);
return Void();
}
@@ -1902,6 +1917,17 @@ struct GnssBatchingCallback_V2_0 : public IGnssBatchingCallback_V2_0 {
/* Initializes the GNSS service handle. */
static void android_location_GnssLocationProvider_set_gps_service_handle() {
ALOGD("Trying IGnss_V3_0::getService()");
gnssHal_V3_0 = IGnss_V3_0::getService();
if (gnssHal_V3_0 != nullptr) {
gnssHal = gnssHal_V3_0;
gnssHal_V2_1 = gnssHal_V3_0;
gnssHal_V2_0 = gnssHal_V3_0;
gnssHal_V1_1 = gnssHal_V3_0;
gnssHal = gnssHal_V3_0;
return;
}
ALOGD("Trying IGnss_V2_1::getService()");
gnssHal_V2_1 = IGnss_V2_1::getService();
if (gnssHal_V2_1 != nullptr) {
@@ -1947,7 +1973,7 @@ static void android_location_GnssNative_class_init_once(JNIEnv* env, jclass claz
method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
"(Ljava/lang/String;)V");
method_psdsDownloadRequest = env->GetMethodID(clazz, "psdsDownloadRequest", "()V");
method_psdsDownloadRequest = env->GetMethodID(clazz, "psdsDownloadRequest", "(I)V");
method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
"(IIIIILjava/lang/String;Ljava/lang/String;II)V");
method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(ZZ)V");
@@ -2142,11 +2168,20 @@ static void android_location_GnssNative_init_once(JNIEnv* env, jobject obj,
ALOGD("Link to death notification successful");
}
auto gnssXtra = gnssHal->getExtensionXtra();
if (!gnssXtra.isOk()) {
ALOGD("Unable to get a handle to Xtra");
if (gnssHal_V3_0 != nullptr) {
auto gnssPsds = gnssHal_V3_0->getExtensionPsds();
if (!gnssPsds.isOk()) {
ALOGD("Unable to get a handle to Psds");
} else {
gnssPsdsIface = gnssPsds;
}
} else {
gnssXtraIface = gnssXtra;
auto gnssXtra = gnssHal->getExtensionXtra();
if (!gnssXtra.isOk()) {
ALOGD("Unable to get a handle to Xtra");
} else {
gnssXtraIface = gnssXtra;
}
}
if (gnssHal_V2_0 != nullptr) {
@@ -2434,15 +2469,20 @@ static jboolean android_location_GnssLocationProvider_init(JNIEnv* /* env */, jo
return JNI_FALSE;
}
// Set IGnssXtra.hal callback.
if (gnssXtraIface == nullptr) {
ALOGI("Unable to initialize IGnssXtra interface.");
} else {
sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
result = gnssXtraIface->setCallback(gnssXtraCbIface);
// Set IGnssPsds or IGnssXtra callback.
sp<IGnssPsdsCallback> gnssPsdsCbIface = new GnssPsdsCallback();
if (gnssPsdsIface != nullptr) {
result = gnssPsdsIface->setCallback_3_0(gnssPsdsCbIface);
if (!checkHidlReturn(result, "IGnssPsds setCallback() failed.")) {
gnssPsdsIface = nullptr;
}
} else if (gnssXtraIface != nullptr) {
result = gnssXtraIface->setCallback(gnssPsdsCbIface);
if (!checkHidlReturn(result, "IGnssXtra setCallback() failed.")) {
gnssXtraIface = nullptr;
}
} else {
ALOGI("Unable to initialize IGnssPsds/IGnssXtra interface.");
}
// Set IAGnss.hal callback.