diff options
| author | 2019-01-10 02:40:41 +0000 | |
|---|---|---|
| committer | 2019-01-10 02:40:41 +0000 | |
| commit | dee34387138457263bd5a4d02c1610b5a73eda85 (patch) | |
| tree | e343d97cb101f0d07f65c91e39b7c37c6f0e9c3d | |
| parent | bc4bfd6ae1da22305988ee708fd5cc7b7498ba02 (diff) | |
| parent | d71cf1499b4def9ccb27a5224ba752a8dbba0e98 (diff) | |
Merge "Add emergency session extension duration (framework)"
4 files changed, 533 insertions, 271 deletions
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java index b5313256e4dc..866634e17513 100644 --- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java +++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java @@ -16,9 +16,6 @@ package com.android.internal.location; -import java.io.UnsupportedEncodingException; -import java.util.concurrent.TimeUnit; - import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; @@ -26,20 +23,23 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.location.LocationManager; import android.location.INetInitiatedListener; +import android.location.LocationManager; +import android.os.RemoteException; import android.os.SystemClock; -import android.telephony.TelephonyManager; +import android.os.UserHandle; import android.telephony.PhoneNumberUtils; import android.telephony.PhoneStateListener; -import android.os.RemoteException; -import android.os.UserHandle; +import android.telephony.TelephonyManager; import android.util.Log; -import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.R; +import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.telephony.GsmAlphabet; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeUnit; + /** * A GPS Network-initiated Handler class used by LocationManager. * @@ -92,9 +92,6 @@ public class GpsNetInitiatedHandler { public static final int GPS_ENC_SUPL_UCS2 = 3; public static final int GPS_ENC_UNKNOWN = -1; - // Limit on SUPL NI emergency mode time extension after emergency sessions ends - private static final int MAX_EMERGENCY_MODE_EXTENSION_SECONDS = 300; // 5 minute maximum - private final Context mContext; private final TelephonyManager mTelephonyManager; private final PhoneStateListener mPhoneStateListener; @@ -252,19 +249,9 @@ public class GpsNetInitiatedHandler { } public void setEmergencyExtensionSeconds(int emergencyExtensionSeconds) { - if (emergencyExtensionSeconds > MAX_EMERGENCY_MODE_EXTENSION_SECONDS) { - Log.w(TAG, "emergencyExtensionSeconds " + emergencyExtensionSeconds - + " too high, reset to " + MAX_EMERGENCY_MODE_EXTENSION_SECONDS); - emergencyExtensionSeconds = MAX_EMERGENCY_MODE_EXTENSION_SECONDS; - } else if (emergencyExtensionSeconds < 0) { - Log.w(TAG, "emergencyExtensionSeconds " + emergencyExtensionSeconds - + " is negative, reset to zero."); - emergencyExtensionSeconds = 0; - } mEmergencyExtensionMillis = TimeUnit.SECONDS.toMillis(emergencyExtensionSeconds); } - // Handles NI events from HAL public void handleNiNotification(GpsNiNotification notif) { if (DEBUG) Log.d(TAG, "in handleNiNotification () :" diff --git a/services/core/java/com/android/server/location/GnssConfiguration.java b/services/core/java/com/android/server/location/GnssConfiguration.java new file mode 100644 index 000000000000..29465ad366f4 --- /dev/null +++ b/services/core/java/com/android/server/location/GnssConfiguration.java @@ -0,0 +1,365 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.location; + +import android.content.Context; +import android.os.PersistableBundle; +import android.os.SystemProperties; +import android.telephony.CarrierConfigManager; +import android.telephony.SubscriptionManager; +import android.text.TextUtils; +import android.util.Log; + +import libcore.io.IoUtils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; + +/** + * A utility class to hold GNSS configuration properties. + * + * The trigger to load/reload the configuration parameters should be managed by the class + * that owns an instance of this class. + * + * Instances of this class are not thread-safe and should either be used from a single thread + * or with external synchronization when used by multiple threads. + */ +class GnssConfiguration { + private static final String TAG = "GnssConfiguration"; + + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + + //TODO(b/33112647): Create gps_debug.conf with commented career parameters. + private static final String DEBUG_PROPERTIES_FILE = "/etc/gps_debug.conf"; + + // config.xml properties + private static final String CONFIG_SUPL_HOST = "SUPL_HOST"; + private static final String CONFIG_SUPL_PORT = "SUPL_PORT"; + private static final String CONFIG_C2K_HOST = "C2K_HOST"; + private static final String CONFIG_C2K_PORT = "C2K_PORT"; + private static final String CONFIG_SUPL_VER = "SUPL_VER"; + private static final String CONFIG_SUPL_MODE = "SUPL_MODE"; + private static final String CONFIG_SUPL_ES = "SUPL_ES"; + private static final String CONFIG_LPP_PROFILE = "LPP_PROFILE"; + private static final String CONFIG_A_GLONASS_POS_PROTOCOL_SELECT = + "A_GLONASS_POS_PROTOCOL_SELECT"; + private static final String CONFIG_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL = + "USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL"; + private static final String CONFIG_GPS_LOCK = "GPS_LOCK"; + private static final String CONFIG_ES_EXTENSION_SEC = "ES_EXTENSION_SEC"; + + // Limit on NI emergency mode time extension after emergency sessions ends + private static final int MAX_EMERGENCY_MODE_EXTENSION_SECONDS = 300; // 5 minute maximum + + // Persist property for LPP_PROFILE + static final String LPP_PROFILE = "persist.sys.gps.lpp"; + + // Represents an HAL interface version. Instances of this class are created in the JNI layer + // and returned through native methods. + private static class HalInterfaceVersion { + final int mMajor; + final int mMinor; + + HalInterfaceVersion(int major, int minor) { + mMajor = major; + mMinor = minor; + } + } + + /** + * Properties loaded from PROPERTIES_FILE. + */ + private Properties mProperties; + + private int mEsExtensionSec = 0; + + private final Context mContext; + + GnssConfiguration(Context context) { + mContext = context; + mProperties = new Properties(); + } + + /** + * Returns the full set of properties loaded. + */ + Properties getProperties() { + return mProperties; + } + + /** + * Returns the value of config parameter ES_EXTENSION_SEC. The value is range checked + * and constrained to min/max limits. + */ + int getEsExtensionSec() { + return mEsExtensionSec; + } + + /** + * Returns the value of config parameter SUPL_HOST or {@code null} if no value is + * provided. + */ + String getSuplHost() { + return mProperties.getProperty(CONFIG_SUPL_HOST); + } + + /** + * Returns the value of config parameter SUPL_PORT or {@code defaultPort} if no value is + * provided or if there is an error parsing the configured value. + */ + int getSuplPort(int defaultPort) { + return getIntConfig(CONFIG_SUPL_PORT, defaultPort); + } + + /** + * Returns the value of config parameter C2K_HOST or {@code null} if no value is + * provided. + */ + String getC2KHost() { + return mProperties.getProperty(CONFIG_C2K_HOST); + } + + /** + * Returns the value of config parameter C2K_PORT or {@code defaultPort} if no value is + * provided or if there is an error parsing the configured value. + */ + int getC2KPort(int defaultPort) { + return getIntConfig(CONFIG_C2K_PORT, defaultPort); + } + + /** + * Returns the value of config parameter SUPL_MODE or {@code defaultMode} if no value is + * provided or if there is an error parsing the configured value. + */ + int getSuplMode(int defaultMode) { + return getIntConfig(CONFIG_SUPL_MODE, defaultMode); + } + + /** + * Returns the value of config parameter SUPL_ES or {@code defaultSuplEs} if no value is + * provided or if there is an error parsing the configured value. + */ + int getSuplEs(int defaulSuplEs) { + return getIntConfig(CONFIG_SUPL_ES, defaulSuplEs); + } + + /** + * Returns the value of config parameter LPP_PROFILE or {@code null} if no value is + * provided. + */ + String getLppProfile() { + return mProperties.getProperty(CONFIG_LPP_PROFILE); + } + + /** + * Updates the GNSS HAL satellite blacklist. + */ + void setSatelliteBlacklist(int[] constellations, int[] svids) { + native_set_satellite_blacklist(constellations, svids); + } + + interface SetCarrierProperty { + boolean set(int value); + } + + /** + * Loads the GNSS properties from carrier config file followed by the properties from + * gps debug config file. + */ + void reloadGpsProperties() { + if (DEBUG) Log.d(TAG, "Reset GPS properties, previous size = " + mProperties.size()); + loadPropertiesFromCarrierConfig(); + + String lpp_prof = SystemProperties.get(LPP_PROFILE); + if (!TextUtils.isEmpty(lpp_prof)) { + // override default value of this if lpp_prof is not empty + mProperties.setProperty(CONFIG_LPP_PROFILE, lpp_prof); + } + /* + * Overlay carrier properties from a debug configuration file. + */ + loadPropertiesFromGpsDebugConfig(mProperties); + + mEsExtensionSec = getRangeCheckedConfigEsExtensionSec(); + + final HalInterfaceVersion gnssConfigurationIfaceVersion = + native_get_gnss_configuration_version(); + if (gnssConfigurationIfaceVersion != null) { + // Set to a range checked value. + if (isConfigEsExtensionSecSupported(gnssConfigurationIfaceVersion) + && !native_set_es_extension_sec(mEsExtensionSec)) { + Log.e(TAG, "Unable to set " + CONFIG_ES_EXTENSION_SEC + ": " + mEsExtensionSec); + } + + Map<String, SetCarrierProperty> map = new HashMap<String, SetCarrierProperty>() { + { + put(CONFIG_SUPL_VER, GnssConfiguration::native_set_supl_version); + put(CONFIG_SUPL_MODE, GnssConfiguration::native_set_supl_mode); + + if (isConfigSuplEsSupported(gnssConfigurationIfaceVersion)) { + put(CONFIG_SUPL_ES, GnssConfiguration::native_set_supl_es); + } + + put(CONFIG_LPP_PROFILE, GnssConfiguration::native_set_lpp_profile); + put(CONFIG_A_GLONASS_POS_PROTOCOL_SELECT, + GnssConfiguration::native_set_gnss_pos_protocol_select); + put(CONFIG_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL, + GnssConfiguration::native_set_emergency_supl_pdn); + + if (isConfigGpsLockSupported(gnssConfigurationIfaceVersion)) { + put(CONFIG_GPS_LOCK, GnssConfiguration::native_set_gps_lock); + } + } + }; + + for (Entry<String, SetCarrierProperty> entry : map.entrySet()) { + String propertyName = entry.getKey(); + String propertyValueString = mProperties.getProperty(propertyName); + if (propertyValueString != null) { + try { + int propertyValueInt = Integer.decode(propertyValueString); + boolean result = entry.getValue().set(propertyValueInt); + if (!result) { + Log.e(TAG, "Unable to set " + propertyName); + } + } catch (NumberFormatException e) { + Log.e(TAG, "Unable to parse propertyName: " + propertyValueString); + } + } + } + } else if (DEBUG) { + Log.d(TAG, "Skipped configuration update because GNSS configuration in GPS HAL is not" + + " supported"); + } + } + + /** + * Loads GNSS properties from carrier config file. + */ + void loadPropertiesFromCarrierConfig() { + CarrierConfigManager configManager = (CarrierConfigManager) + mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); + if (configManager == null) { + return; + } + PersistableBundle configs = configManager.getConfigForSubId( + SubscriptionManager.getDefaultDataSubscriptionId()); + if (configs == null) { + if (DEBUG) Log.d(TAG, "SIM not ready, use default carrier config."); + configs = CarrierConfigManager.getDefaultConfig(); + } + for (String configKey : configs.keySet()) { + if (configKey.startsWith(CarrierConfigManager.Gps.KEY_PREFIX)) { + String key = configKey + .substring(CarrierConfigManager.Gps.KEY_PREFIX.length()) + .toUpperCase(); + Object value = configs.get(configKey); + if (value instanceof String) { + // All GPS properties are of String type; convert so. + if (DEBUG) Log.d(TAG, "Gps config: " + key + " = " + value); + mProperties.setProperty(key, (String) value); + } + } + } + } + + private void loadPropertiesFromGpsDebugConfig(Properties properties) { + try { + File file = new File(DEBUG_PROPERTIES_FILE); + FileInputStream stream = null; + try { + stream = new FileInputStream(file); + properties.load(stream); + } finally { + IoUtils.closeQuietly(stream); + } + } catch (IOException e) { + if (DEBUG) Log.d(TAG, "Could not open GPS configuration file " + DEBUG_PROPERTIES_FILE); + } + } + + private int getRangeCheckedConfigEsExtensionSec() { + int emergencyExtensionSeconds = getIntConfig(CONFIG_ES_EXTENSION_SEC, 0); + if (emergencyExtensionSeconds > MAX_EMERGENCY_MODE_EXTENSION_SECONDS) { + Log.w(TAG, CONFIG_ES_EXTENSION_SEC + ": " + emergencyExtensionSeconds + + " too high, reset to " + MAX_EMERGENCY_MODE_EXTENSION_SECONDS); + emergencyExtensionSeconds = MAX_EMERGENCY_MODE_EXTENSION_SECONDS; + } else if (emergencyExtensionSeconds < 0) { + Log.w(TAG, CONFIG_ES_EXTENSION_SEC + ": " + emergencyExtensionSeconds + + " is negative, reset to zero."); + emergencyExtensionSeconds = 0; + } + return emergencyExtensionSeconds; + } + + private int getIntConfig(String configParameter, int defaultValue) { + String valueString = mProperties.getProperty(configParameter); + if (TextUtils.isEmpty(valueString)) { + return defaultValue; + } + try { + return Integer.parseInt(valueString); + } catch (NumberFormatException e) { + Log.e(TAG, "Unable to parse config parameter " + configParameter + " value: " + + valueString + ". Using default value: " + defaultValue); + return defaultValue; + } + } + + private static boolean isConfigEsExtensionSecSupported( + HalInterfaceVersion gnssConfiguartionIfaceVersion) { + // ES_EXTENSION_SEC is introduced in @2.0::IGnssConfiguration.hal + return gnssConfiguartionIfaceVersion.mMajor >= 2; + } + + private static boolean isConfigSuplEsSupported( + HalInterfaceVersion gnssConfiguartionIfaceVersion) { + // SUPL_ES is deprecated in @2.0::IGnssConfiguration.hal + return gnssConfiguartionIfaceVersion.mMajor < 2; + } + + private static boolean isConfigGpsLockSupported( + HalInterfaceVersion gnssConfiguartionIfaceVersion) { + // GPS_LOCK is deprecated in @2.0::IGnssConfiguration.hal + return gnssConfiguartionIfaceVersion.mMajor < 2; + } + + private static native HalInterfaceVersion native_get_gnss_configuration_version(); + + private static native boolean native_set_supl_version(int version); + + private static native boolean native_set_supl_mode(int mode); + + private static native boolean native_set_supl_es(int es); + + private static native boolean native_set_lpp_profile(int lppProfile); + + private static native boolean native_set_gnss_pos_protocol_select(int gnssPosProtocolSelect); + + private static native boolean native_set_gps_lock(int gpsLock); + + private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn); + + private static native boolean native_set_satellite_blacklist(int[] constellations, int[] svIds); + + private static native boolean native_set_es_extension_sec(int emergencyExtensionSeconds); +} diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java index 05d77ab5867e..3c81a4569407 100644 --- a/services/core/java/com/android/server/location/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/GnssLocationProvider.java @@ -74,12 +74,7 @@ import com.android.internal.location.gnssmetrics.GnssMetrics; import com.android.server.location.GnssSatelliteBlacklistHelper.GnssSatelliteBlacklistCallback; import com.android.server.location.NtpTimeHelper.InjectNtpTimeCallback; -import libcore.io.IoUtils; - -import java.io.File; import java.io.FileDescriptor; -import java.io.FileInputStream; -import java.io.IOException; import java.io.PrintWriter; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -87,11 +82,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; /** * A GNSS implementation of LocationProvider used by LocationManager. @@ -147,7 +138,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private static final int LOCATION_HAS_SPEED_ACCURACY = 64; private static final int LOCATION_HAS_BEARING_ACCURACY = 128; - // IMPORTANT - the GPS_DELETE_* symbols here must match GnssAidingData enum in IGnss.hal private static final int GPS_DELETE_EPHEMERIS = 0x0001; private static final int GPS_DELETE_ALMANAC = 0x0002; @@ -200,9 +190,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1; private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2; - //TODO(b/33112647): Create gps_debug.conf with commented career parameters. - private static final String DEBUG_PROPERTIES_FILE = "/etc/gps_debug.conf"; - // ref. location info private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1; private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2; @@ -375,7 +362,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements * Properties loaded from PROPERTIES_FILE. * It must be accessed only inside {@link #mHandler}. */ - private Properties mProperties; + private GnssConfiguration mGnssConfiguration; private String mSuplServerHost; private int mSuplServerPort = TCP_MIN_PORT; @@ -411,10 +398,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP"; private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT"; - // Persist property for LPP_PROFILE - private final static String LPP_PROFILE = "persist.sys.gps.lpp"; - - private final PowerManager mPowerManager; private final AlarmManager mAlarmManager; private final PendingIntent mWakeupIntent; @@ -502,7 +485,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements */ @Override public void onUpdateSatelliteBlacklist(int[] constellations, int[] svids) { - mHandler.post(() -> native_set_satellite_blacklist(constellations, svids)); + mHandler.post(() -> mGnssConfiguration.setSatelliteBlacklist(constellations, svids)); } private void subscriptionOrCarrierConfigChanged(Context context) { @@ -525,17 +508,17 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } if (isKeepLppProfile) { // load current properties for the carrier - loadPropertiesFromCarrierConfig(context, mProperties); - String lpp_profile = mProperties.getProperty("LPP_PROFILE"); + mGnssConfiguration.loadPropertiesFromCarrierConfig(); + String lpp_profile = mGnssConfiguration.getLppProfile(); // set the persist property LPP_PROFILE for the value if (lpp_profile != null) { - SystemProperties.set(LPP_PROFILE, lpp_profile); + SystemProperties.set(GnssConfiguration.LPP_PROFILE, lpp_profile); } } else { // reset the persist property - SystemProperties.set(LPP_PROFILE, ""); + SystemProperties.set(GnssConfiguration.LPP_PROFILE, ""); } - reloadGpsProperties(context, mProperties); + reloadGpsProperties(); mNIHandler.setSuplEsEnabled(mSuplEsEnabled); } } else { @@ -564,133 +547,14 @@ public class GnssLocationProvider extends AbstractLocationProvider implements return native_is_supported(); } - interface SetCarrierProperty { - boolean set(int value); - } - - private void reloadGpsProperties(Context context, Properties properties) { - if (DEBUG) Log.d(TAG, "Reset GPS properties, previous size = " + properties.size()); - loadPropertiesFromCarrierConfig(context, properties); - - String lpp_prof = SystemProperties.get(LPP_PROFILE); - if (!TextUtils.isEmpty(lpp_prof)) { - // override default value of this if lpp_prof is not empty - properties.setProperty("LPP_PROFILE", lpp_prof); - } - /* - * Overlay carrier properties from a debug configuration file. - */ - loadPropertiesFromGpsDebugConfig(properties); + private void reloadGpsProperties() { + mGnssConfiguration.reloadGpsProperties(); + setSuplHostPort(); // TODO: we should get rid of C2K specific setting. - setSuplHostPort(properties.getProperty("SUPL_HOST"), - properties.getProperty("SUPL_PORT")); - mC2KServerHost = properties.getProperty("C2K_HOST"); - String portString = properties.getProperty("C2K_PORT"); - if (mC2KServerHost != null && portString != null) { - try { - mC2KServerPort = Integer.parseInt(portString); - } catch (NumberFormatException e) { - Log.e(TAG, "unable to parse C2K_PORT: " + portString); - } - } - if (native_is_gnss_configuration_supported()) { - Map<String, SetCarrierProperty> map = new HashMap<String, SetCarrierProperty>() { - { - put("SUPL_VER", GnssLocationProvider::native_set_supl_version); - put("SUPL_MODE", GnssLocationProvider::native_set_supl_mode); - put("SUPL_ES", GnssLocationProvider::native_set_supl_es); - put("LPP_PROFILE", GnssLocationProvider::native_set_lpp_profile); - put("A_GLONASS_POS_PROTOCOL_SELECT", - GnssLocationProvider::native_set_gnss_pos_protocol_select); - put("USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL", - GnssLocationProvider::native_set_emergency_supl_pdn); - put("GPS_LOCK", GnssLocationProvider::native_set_gps_lock); - } - }; - - for (Entry<String, SetCarrierProperty> entry : map.entrySet()) { - String propertyName = entry.getKey(); - String propertyValueString = properties.getProperty(propertyName); - if (propertyValueString != null) { - try { - int propertyValueInt = Integer.decode(propertyValueString); - boolean result = entry.getValue().set(propertyValueInt); - if (!result) { - Log.e(TAG, "Unable to set " + propertyName); - } - } catch (NumberFormatException e) { - Log.e(TAG, "unable to parse propertyName: " + propertyValueString); - } - } - } - } else if (DEBUG) { - Log.d(TAG, "Skipped configuration update because GNSS configuration in GPS HAL is not" - + " supported"); - } - - // SUPL_ES configuration. - String suplESProperty = mProperties.getProperty("SUPL_ES"); - if (suplESProperty != null) { - try { - mSuplEsEnabled = (Integer.parseInt(suplESProperty) == 1); - } catch (NumberFormatException e) { - Log.e(TAG, "unable to parse SUPL_ES: " + suplESProperty); - } - } - - String emergencyExtensionSecondsString - = properties.getProperty("ES_EXTENSION_SEC", "0"); - try { - int emergencyExtensionSeconds = - Integer.parseInt(emergencyExtensionSecondsString); - mNIHandler.setEmergencyExtensionSeconds(emergencyExtensionSeconds); - } catch (NumberFormatException e) { - Log.e(TAG, "unable to parse ES_EXTENSION_SEC: " - + emergencyExtensionSecondsString); - } - } - - private void loadPropertiesFromCarrierConfig(Context context, Properties properties) { - CarrierConfigManager configManager = (CarrierConfigManager) - mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); - if (configManager == null) { - return; - } - PersistableBundle configs = configManager.getConfigForSubId( - SubscriptionManager.getDefaultDataSubscriptionId()); - if (configs == null) { - if (DEBUG) Log.d(TAG, "SIM not ready, use default carrier config."); - configs = CarrierConfigManager.getDefaultConfig(); - } - for (String configKey : configs.keySet()) { - if (configKey.startsWith(CarrierConfigManager.Gps.KEY_PREFIX)) { - String key = configKey - .substring(CarrierConfigManager.Gps.KEY_PREFIX.length()) - .toUpperCase(); - Object value = configs.get(configKey); - if (value instanceof String) { - // All GPS properties are of String type; convert so. - if (DEBUG) Log.d(TAG, "Gps config: " + key + " = " + value); - properties.setProperty(key, (String) value); - } - } - } - } - - private void loadPropertiesFromGpsDebugConfig(Properties properties) { - try { - File file = new File(DEBUG_PROPERTIES_FILE); - FileInputStream stream = null; - try { - stream = new FileInputStream(file); - properties.load(stream); - } finally { - IoUtils.closeQuietly(stream); - } - - } catch (IOException e) { - if (DEBUG) Log.d(TAG, "Could not open GPS configuration file " + DEBUG_PROPERTIES_FILE); - } + mC2KServerHost = mGnssConfiguration.getC2KHost(); + mC2KServerPort = mGnssConfiguration.getC2KPort(TCP_MIN_PORT); + mNIHandler.setEmergencyExtensionSeconds(mGnssConfiguration.getEsExtensionSec()); + mSuplEsEnabled = mGnssConfiguration.getSuplEs(0) == 1; } public GnssLocationProvider(Context context, LocationProviderManager locationProviderManager, @@ -733,7 +597,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // relative long time, so the ctor() is kept to create objects needed by this instance, // while IO initialization and registration is delegated to our internal handler // this approach is just fine because events are posted to our handler anyway - mProperties = new Properties(); + mGnssConfiguration = new GnssConfiguration(mContext); sendMessage(INITIALIZE_HANDLER, 0, null); // Create a GPS net-initiated handler. @@ -918,7 +782,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements mDownloadXtraWakeLock.acquire(DOWNLOAD_XTRA_DATA_TIMEOUT_MS); Log.i(TAG, "WakeLock acquired by handleDownloadXtraData()"); AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> { - GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mProperties); + GpsXtraDownloader xtraDownloader = new GpsXtraDownloader( + mGnssConfiguration.getProperties()); byte[] data = xtraDownloader.downloadXtraData(); if (data != null) { if (DEBUG) Log.d(TAG, "calling native_inject_xtra_data"); @@ -963,17 +828,9 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } } - private void setSuplHostPort(String hostString, String portString) { - if (hostString != null) { - mSuplServerHost = hostString; - } - if (portString != null) { - try { - mSuplServerPort = Integer.parseInt(portString); - } catch (NumberFormatException e) { - Log.e(TAG, "unable to parse SUPL_PORT: " + portString); - } - } + private void setSuplHostPort() { + mSuplServerHost = mGnssConfiguration.getSuplHost(); + mSuplServerPort = mGnssConfiguration.getSuplPort(TCP_MIN_PORT); if (mSuplServerHost != null && mSuplServerPort > TCP_MIN_PORT && mSuplServerPort <= TCP_MAX_PORT) { @@ -986,23 +843,17 @@ public class GnssLocationProvider extends AbstractLocationProvider implements * Checks what SUPL mode to use, according to the AGPS mode as well as the * allowed mode from properties. * - * @param properties GPS properties * @param agpsEnabled whether AGPS is enabled by settings value * @param singleShot whether "singleshot" is needed * @return SUPL mode (MSA vs MSB vs STANDALONE) */ - private int getSuplMode(Properties properties, boolean agpsEnabled, boolean singleShot) { + private int getSuplMode(boolean agpsEnabled, boolean singleShot) { if (agpsEnabled) { - String modeString = properties.getProperty("SUPL_MODE"); - int suplMode = 0; - if (!TextUtils.isEmpty(modeString)) { - try { - suplMode = Integer.parseInt(modeString); - } catch (NumberFormatException e) { - Log.e(TAG, "unable to parse SUPL_MODE: " + modeString); - return GPS_POSITION_MODE_STANDALONE; - } + int suplMode = mGnssConfiguration.getSuplMode(0); + if (suplMode == 0) { + return GPS_POSITION_MODE_STANDALONE; } + // MS-Based is the preferred mode for Assisted-GPS position computation, so we favor // such mode when it is available if (hasCapability(GPS_CAPABILITY_MSB) && (suplMode & AGPS_SUPL_MODE_MSB) != 0) { @@ -1307,7 +1158,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements boolean agpsEnabled = (Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.ASSISTED_GPS_ENABLED, 1) != 0); - mPositionMode = getSuplMode(mProperties, agpsEnabled, singleShot); + mPositionMode = getSuplMode(agpsEnabled, singleShot); if (DEBUG) { String mode; @@ -1670,7 +1521,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // re-calls native_init() and other setup. handleEnable(); // resend configuration into the restarted HAL service. - reloadGpsProperties(mContext, mProperties); + reloadGpsProperties(); } }); } @@ -2072,7 +1923,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // load default GPS configuration // (this configuration might change in the future based on SIM changes) - reloadGpsProperties(mContext, mProperties); + reloadGpsProperties(); // TODO: When this object "finishes" we should unregister by invoking // SubscriptionManager.getInstance(mContext).unregister @@ -2227,8 +2078,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private static native boolean native_is_supported(); - private static native boolean native_is_gnss_configuration_supported(); - private static native void native_init_once(); private native boolean native_init(); @@ -2284,21 +2133,4 @@ public class GnssLocationProvider extends AbstractLocationProvider implements int lac, int cid); private native void native_agps_set_id(int type, String setid); - - // GNSS Configuration - private static native boolean native_set_supl_version(int version); - - private static native boolean native_set_supl_mode(int mode); - - private static native boolean native_set_supl_es(int es); - - private static native boolean native_set_lpp_profile(int lppProfile); - - private static native boolean native_set_gnss_pos_protocol_select(int gnssPosProtocolSelect); - - private static native boolean native_set_gps_lock(int gpsLock); - - private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn); - - private static native boolean native_set_satellite_blacklist(int[] constellations, int[] svIds); -} +}
\ No newline at end of file diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 6d8fc1c88307..b290bc516320 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -135,6 +135,7 @@ using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss; using IGnss_V2_0 = android::hardware::gnss::V2_0::IGnss; using IGnssConfiguration_V1_0 = android::hardware::gnss::V1_0::IGnssConfiguration; using IGnssConfiguration_V1_1 = android::hardware::gnss::V1_1::IGnssConfiguration; +using IGnssConfiguration_V2_0 = android::hardware::gnss::V2_0::IGnssConfiguration; using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement; using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement; using IGnssMeasurement_V2_0 = android::hardware::gnss::V2_0::IGnssMeasurement; @@ -179,6 +180,7 @@ sp<IGnssBatching> gnssBatchingIface = nullptr; sp<IGnssDebug> gnssDebugIface = nullptr; sp<IGnssConfiguration_V1_0> gnssConfigurationIface = nullptr; sp<IGnssConfiguration_V1_1> gnssConfigurationIface_V1_1 = nullptr; +sp<IGnssConfiguration_V2_0> gnssConfigurationIface_V2_0 = nullptr; sp<IGnssNi> gnssNiIface = nullptr; sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr; sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr; @@ -313,6 +315,15 @@ static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodNa } } +static jobject createHalInterfaceVersionJavaObject(JNIEnv* env, jint major, jint minor) { + jclass versionClass = + env->FindClass("com/android/server/location/GnssConfiguration$HalInterfaceVersion"); + jmethodID versionCtor = env->GetMethodID(versionClass, "<init>", "(II)V"); + jobject version = env->NewObject(versionClass, versionCtor, major, minor); + env->DeleteLocalRef(versionClass); + return version; +} + struct ScopedJniString { ScopedJniString(JNIEnv* env, jstring javaString) : mEnv(env), mJavaString(javaString) { mNativeString = mEnv->GetStringUTFChars(mJavaString, nullptr); @@ -1421,10 +1432,19 @@ static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass gnssNiIface = gnssNi; } - if (gnssHal_V1_1 != nullptr) { + if (gnssHal_V2_0 != nullptr) { + auto gnssConfiguration = gnssHal_V2_0->getExtensionGnssConfiguration_2_0(); + if (!gnssConfiguration.isOk()) { + ALOGD("Unable to get a handle to GnssConfiguration_V2_0"); + } else { + gnssConfigurationIface_V2_0 = gnssConfiguration; + gnssConfigurationIface_V1_1 = gnssConfigurationIface_V2_0; + gnssConfigurationIface = gnssConfigurationIface_V2_0; + } + } else if (gnssHal_V1_1 != nullptr) { auto gnssConfiguration = gnssHal_V1_1->getExtensionGnssConfiguration_1_1(); if (!gnssConfiguration.isOk()) { - ALOGD("Unable to get a handle to GnssConfiguration"); + ALOGD("Unable to get a handle to GnssConfiguration_V1_1"); } else { gnssConfigurationIface_V1_1 = gnssConfiguration; gnssConfigurationIface = gnssConfigurationIface_V1_1; @@ -1463,9 +1483,23 @@ static jboolean android_location_GnssNetworkConnectivityHandler_is_agps_ril_supp return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE; } -static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported( - JNIEnv* /* env */, jclass /* jclazz */) { - return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE; +static jobject android_location_GnssConfiguration_get_gnss_configuration_version( + JNIEnv* env, jclass /* jclazz */) { + jint major, minor; + if (gnssConfigurationIface_V2_0 != nullptr) { + major = 2; + minor = 0; + } else if (gnssConfigurationIface_V1_1 != nullptr) { + major = 1; + minor = 1; + } else if (gnssConfigurationIface != nullptr) { + major = 1; + minor = 0; + } else { + return nullptr; + } + + return createHalInterfaceVersionJavaObject(env, major, minor); } static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) { @@ -2278,9 +2312,9 @@ static jboolean android_location_GnssNavigationMessageProvider_stop_navigation_m return boolToJbool(result.isOk()); } -static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*, - jobject, - jint emergencySuplPdn) { +static jboolean android_location_GnssConfiguration_set_emergency_supl_pdn(JNIEnv*, + jobject, + jint emergencySuplPdn) { if (gnssConfigurationIface == nullptr) { ALOGE("no GNSS configuration interface available"); return JNI_FALSE; @@ -2294,7 +2328,7 @@ static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNI } } -static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*, +static jboolean android_location_GnssConfiguration_set_supl_version(JNIEnv*, jobject, jint version) { if (gnssConfigurationIface == nullptr) { @@ -2309,9 +2343,14 @@ static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*, } } -static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*, - jobject, - jint suplEs) { +static jboolean android_location_GnssConfiguration_set_supl_es(JNIEnv*, + jobject, + jint suplEs) { + if (gnssConfigurationIface_V2_0 != nullptr) { + ALOGI("Config parameter SUPL_ES is deprecated in IGnssConfiguration.hal version 2.0."); + return JNI_FALSE; + } + if (gnssConfigurationIface == nullptr) { ALOGE("no GNSS configuration interface available"); return JNI_FALSE; @@ -2325,9 +2364,9 @@ static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*, } } -static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*, - jobject, - jint mode) { +static jboolean android_location_GnssConfiguration_set_supl_mode(JNIEnv*, + jobject, + jint mode) { if (gnssConfigurationIface == nullptr) { ALOGE("no GNSS configuration interface available"); return JNI_FALSE; @@ -2341,9 +2380,14 @@ static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*, } } -static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*, - jobject, - jint gpsLock) { +static jboolean android_location_GnssConfiguration_set_gps_lock(JNIEnv*, + jobject, + jint gpsLock) { + if (gnssConfigurationIface_V2_0 != nullptr) { + ALOGI("Config parameter GPS_LOCK is deprecated in IGnssConfiguration.hal version 2.0."); + return JNI_FALSE; + } + if (gnssConfigurationIface == nullptr) { ALOGE("no GNSS configuration interface available"); return JNI_FALSE; @@ -2357,7 +2401,7 @@ static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*, } } -static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*, +static jboolean android_location_GnssConfiguration_set_lpp_profile(JNIEnv*, jobject, jint lppProfile) { if (gnssConfigurationIface == nullptr) { @@ -2374,9 +2418,9 @@ static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*, } } -static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*, - jobject, - jint gnssPosProtocol) { +static jboolean android_location_GnssConfiguration_set_gnss_pos_protocol_select(JNIEnv*, + jobject, + jint gnssPosProtocol) { if (gnssConfigurationIface == nullptr) { ALOGE("no GNSS configuration interface available"); return JNI_FALSE; @@ -2390,7 +2434,7 @@ static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_sele } } -static jboolean android_location_GnssLocationProvider_set_satellite_blacklist( +static jboolean android_location_GnssConfiguration_set_satellite_blacklist( JNIEnv* env, jobject, jintArray constellations, jintArray sv_ids) { if (gnssConfigurationIface_V1_1 == nullptr) { ALOGI("No GNSS Satellite Blacklist interface available"); @@ -2431,6 +2475,27 @@ static jboolean android_location_GnssLocationProvider_set_satellite_blacklist( } } +static jboolean android_location_GnssConfiguration_set_es_extension_sec( + JNIEnv*, jobject, jint emergencyExtensionSeconds) { + if (gnssConfigurationIface == nullptr) { + ALOGE("no GNSS configuration interface available"); + return JNI_FALSE; + } + + if (gnssConfigurationIface_V2_0 == nullptr) { + ALOGI("Config parameter ES_EXTENSION_SEC is not supported in IGnssConfiguration.hal" + " versions earlier than 2.0."); + return JNI_FALSE; + } + + auto result = gnssConfigurationIface_V2_0->setEsExtensionSec(emergencyExtensionSeconds); + if (result.isOk()) { + return result; + } else { + return JNI_FALSE; + } +} + static jint android_location_GnssBatchingProvider_get_batch_size(JNIEnv*, jclass) { if (gnssBatchingIface == nullptr) { return 0; // batching not supported, size = 0 @@ -2498,17 +2563,14 @@ static const JNINativeMethod sMethods[] = { android_location_GnssLocationProvider_class_init_native)}, {"native_is_supported", "()Z", reinterpret_cast<void *>( android_location_GnssLocationProvider_is_supported)}, - {"native_is_gnss_configuration_supported", "()Z", - reinterpret_cast<void *>( - android_location_gpsLocationProvider_is_gnss_configuration_supported)}, {"native_init_once", "()V", reinterpret_cast<void *>( android_location_GnssLocationProvider_init_once)}, {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)}, {"native_cleanup", "()V", reinterpret_cast<void *>( android_location_GnssLocationProvider_cleanup)}, {"native_set_position_mode", - "(IIIIIZ)Z", - reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)}, + "(IIIIIZ)Z", + reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)}, {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)}, {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)}, {"native_delete_aiding_data", @@ -2545,31 +2607,6 @@ static const JNINativeMethod sMethods[] = { {"native_get_internal_state", "()Ljava/lang/String;", reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)}, - {"native_set_supl_es", - "(I)Z", - reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)}, - {"native_set_supl_version", - "(I)Z", - reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)}, - {"native_set_supl_mode", - "(I)Z", - reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)}, - {"native_set_lpp_profile", - "(I)Z", - reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)}, - {"native_set_gnss_pos_protocol_select", - "(I)Z", - reinterpret_cast<void *>( - android_location_GnssLocationProvider_set_gnss_pos_protocol_select)}, - {"native_set_gps_lock", - "(I)Z", - reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)}, - {"native_set_emergency_supl_pdn", - "(I)Z", - reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)}, - {"native_set_satellite_blacklist", - "([I[I)Z", - reinterpret_cast<void *>(android_location_GnssLocationProvider_set_satellite_blacklist)}, }; static const JNINativeMethod sMethodsBatching[] = { @@ -2663,6 +2700,42 @@ static const JNINativeMethod sNetworkConnectivityMethods[] = { reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed)}, }; +static const JNINativeMethod sConfigurationMethods[] = { + /* name, signature, funcPtr */ + {"native_get_gnss_configuration_version", + "()Lcom/android/server/location/GnssConfiguration$HalInterfaceVersion;", + reinterpret_cast<void *>( + android_location_GnssConfiguration_get_gnss_configuration_version)}, + {"native_set_supl_es", + "(I)Z", + reinterpret_cast<void *>(android_location_GnssConfiguration_set_supl_es)}, + {"native_set_supl_version", + "(I)Z", + reinterpret_cast<void *>(android_location_GnssConfiguration_set_supl_version)}, + {"native_set_supl_mode", + "(I)Z", + reinterpret_cast<void *>(android_location_GnssConfiguration_set_supl_mode)}, + {"native_set_lpp_profile", + "(I)Z", + reinterpret_cast<void *>(android_location_GnssConfiguration_set_lpp_profile)}, + {"native_set_gnss_pos_protocol_select", + "(I)Z", + reinterpret_cast<void *>( + android_location_GnssConfiguration_set_gnss_pos_protocol_select)}, + {"native_set_gps_lock", + "(I)Z", + reinterpret_cast<void *>(android_location_GnssConfiguration_set_gps_lock)}, + {"native_set_emergency_supl_pdn", + "(I)Z", + reinterpret_cast<void *>(android_location_GnssConfiguration_set_emergency_supl_pdn)}, + {"native_set_satellite_blacklist", + "([I[I)Z", + reinterpret_cast<void *>(android_location_GnssConfiguration_set_satellite_blacklist)}, + {"native_set_es_extension_sec", + "(I)Z", + reinterpret_cast<void *>(android_location_GnssConfiguration_set_es_extension_sec)}, +}; + int register_android_server_location_GnssLocationProvider(JNIEnv* env) { jniRegisterNativeMethods( env, @@ -2689,6 +2762,11 @@ int register_android_server_location_GnssLocationProvider(JNIEnv* env) { "com/android/server/location/GnssNetworkConnectivityHandler", sNetworkConnectivityMethods, NELEM(sNetworkConnectivityMethods)); + jniRegisterNativeMethods( + env, + "com/android/server/location/GnssConfiguration", + sConfigurationMethods, + NELEM(sConfigurationMethods)); return jniRegisterNativeMethods( env, "com/android/server/location/GnssLocationProvider", |