From a52510eff0ae0a37a3cde3f4ac7dc2d6790cbcba Mon Sep 17 00:00:00 2001 From: Yu-Han Yang Date: Mon, 8 Jun 2020 16:50:08 -0700 Subject: [PATCH] Add GNSS HAL v3.0 (framework/base) - renames GpsPsdsDownloader to GnssPsdsDownloader - adds psdsType support to GnssPsdsDownloader Bug: 158518085 Test: on cuttlefish Change-Id: Ic21c144e0c77fcb3ff381b71dfca1392a8a0c1ca --- .../location/gnss/GnssLocationProvider.java | 24 ++-- .../location/gnss/GnssManagerService.java | 4 +- .../server/location/gnss/GnssNative.java | 6 +- ...ownloader.java => GnssPsdsDownloader.java} | 103 +++++++++++------- services/core/jni/Android.bp | 1 + ...d_server_location_GnssLocationProvider.cpp | 78 +++++++++---- 6 files changed, 143 insertions(+), 73 deletions(-) rename services/core/java/com/android/server/location/gnss/{GpsPsdsDownloader.java => GnssPsdsDownloader.java} (53%) diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java index ba60e859f7bdb..335fe25779fee 100644 --- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java @@ -698,7 +698,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); } } } @@ -818,7 +818,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"); @@ -841,9 +841,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); @@ -854,8 +854,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()); } @@ -1151,7 +1152,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); @@ -1603,9 +1605,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); } /** @@ -1916,7 +1918,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; diff --git a/services/core/java/com/android/server/location/gnss/GnssManagerService.java b/services/core/java/com/android/server/location/gnss/GnssManagerService.java index 457ba34763d0b..8689be01a7d64 100644 --- a/services/core/java/com/android/server/location/gnss/GnssManagerService.java +++ b/services/core/java/com/android/server/location/gnss/GnssManagerService.java @@ -539,8 +539,8 @@ public class GnssManagerService implements GnssNative.Callbacks { } @Override - public void psdsDownloadRequest() { - mGnssLocationProvider.psdsDownloadRequest(); + public void psdsDownloadRequest(int psdsType) { + mGnssLocationProvider.psdsDownloadRequest(psdsType); } @Override diff --git a/services/core/java/com/android/server/location/gnss/GnssNative.java b/services/core/java/com/android/server/location/gnss/GnssNative.java index 7c4f47eafacc0..3933f9a6cbd02 100644 --- a/services/core/java/com/android/server/location/gnss/GnssNative.java +++ b/services/core/java/com/android/server/location/gnss/GnssNative.java @@ -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 diff --git a/services/core/java/com/android/server/location/gnss/GpsPsdsDownloader.java b/services/core/java/com/android/server/location/gnss/GnssPsdsDownloader.java similarity index 53% rename from services/core/java/com/android/server/location/gnss/GpsPsdsDownloader.java rename to services/core/java/com/android/server/location/gnss/GnssPsdsDownloader.java index 273f9cb13a1ba..4a062d81d3b74 100644 --- a/services/core/java/com/android/server/location/gnss/GpsPsdsDownloader.java +++ b/services/core/java/com/android/server/location/gnss/GnssPsdsDownloader.java @@ -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; } - } - diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 64e3c3fbd9503..7d23f74f038bc 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -143,6 +143,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", diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 60215d76e343a..2a65b2cfc1e21 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -22,12 +22,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -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 gnssHal = nullptr; sp gnssHal_V1_1 = nullptr; sp gnssHal_V2_0 = nullptr; sp gnssHal_V2_1 = nullptr; +sp gnssHal_V3_0 = nullptr; +sp gnssPsdsIface = nullptr; sp gnssXtraIface = nullptr; sp agnssRilIface = nullptr; sp agnssRilIface_V2_0 = nullptr; @@ -918,17 +924,26 @@ Return GnssCallback::gnssSetSystemInfoCb(const IGnssCallback_V2_0::GnssSys return Void(); } -class GnssXtraCallback : public IGnssXtraCallback { - Return downloadRequestCb() override; -}; - /* - * GnssXtraCallback class implements the callback methods for the IGnssXtra + * GnssPsdsCallback class implements the callback methods for the IGnssPsds * interface. */ -Return GnssXtraCallback::downloadRequestCb() { +class GnssPsdsCallback : public IGnssPsdsCallback { + Return downloadRequestCb() override; + Return downloadRequestCb_3_0(int32_t psdsType) override; +}; + +Return GnssPsdsCallback::downloadRequestCb() { JNIEnv* env = getJniEnv(); - env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest); + env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest, /* psdsType= */ 1); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Void(); +} + +Return 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 gnssXtraCbIface = new GnssXtraCallback(); - result = gnssXtraIface->setCallback(gnssXtraCbIface); + // Set IGnssPsds or IGnssXtra callback. + sp 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.