Loading services/core/java/com/android/server/location/gnss/GnssConfiguration.java +10 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,8 @@ public class GnssConfiguration { "ENABLE_PSDS_PERIODIC_DOWNLOAD"; private static final String CONFIG_ENABLE_ACTIVE_SIM_EMERGENCY_SUPL = "ENABLE_ACTIVE_SIM_EMERGENCY_SUPL"; private static final String CONFIG_ENABLE_NI_SUPL_MESSAGE_INJECTION = "ENABLE_NI_SUPL_MESSAGE_INJECTION"; static final String CONFIG_LONGTERM_PSDS_SERVER_1 = "LONGTERM_PSDS_SERVER_1"; static final String CONFIG_LONGTERM_PSDS_SERVER_2 = "LONGTERM_PSDS_SERVER_2"; static final String CONFIG_LONGTERM_PSDS_SERVER_3 = "LONGTERM_PSDS_SERVER_3"; Loading Loading @@ -217,6 +219,14 @@ public class GnssConfiguration { return getBooleanConfig(CONFIG_ENABLE_ACTIVE_SIM_EMERGENCY_SUPL, false); } /** * Returns true if NI SUPL message injection is enabled; Returns false otherwise. * Default false if not set. */ boolean isNiSuplMessageInjectionEnabled() { return getBooleanConfig(CONFIG_ENABLE_NI_SUPL_MESSAGE_INJECTION, false); } /** * Returns true if a long-term PSDS server is configured. */ Loading services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +101 −16 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ import android.os.UserHandle; import android.os.WorkSource; import android.os.WorkSource.WorkChain; import android.provider.Settings; import android.provider.Telephony.Sms.Intents; import android.telephony.CarrierConfigManager; import android.telephony.CellIdentity; import android.telephony.CellIdentityGsm; Loading @@ -95,6 +96,7 @@ import android.telephony.CellInfoGsm; import android.telephony.CellInfoLte; import android.telephony.CellInfoNr; import android.telephony.CellInfoWcdma; import android.telephony.SmsMessage; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; Loading @@ -107,6 +109,7 @@ import com.android.internal.app.IBatteryStats; import com.android.internal.location.GpsNetInitiatedHandler; import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.HexDump; import com.android.server.FgThread; import com.android.server.location.gnss.GnssSatelliteBlocklistHelper.GnssSatelliteBlocklistCallback; import com.android.server.location.gnss.NtpTimeHelper.InjectNtpTimeCallback; Loading Loading @@ -523,23 +526,31 @@ public class GnssLocationProvider extends AbstractLocationProvider implements IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); intentFilter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action); if (action == null) { return; mContext.registerReceiver(mIntentReceiver, intentFilter, null, mHandler); if (mNetworkConnectivityHandler.isNativeAgpsRilSupported() && mGnssConfiguration.isNiSuplMessageInjectionEnabled()) { // Listen to WAP PUSH NI SUPL message. // See User Plane Location Protocol Candidate Version 3.0, // OMA-TS-ULP-V3_0-20110920-C, Section 8.3 OMA Push. intentFilter = new IntentFilter(); intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION); try { intentFilter.addDataType("application/vnd.omaloc-supl-init"); } catch (IntentFilter.MalformedMimeTypeException e) { Log.w(TAG, "Malformed SUPL init mime type"); } mContext.registerReceiver(mIntentReceiver, intentFilter, null, mHandler); switch (action) { case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED: case TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED: subscriptionOrCarrierConfigChanged(); break; } // Listen to MT SMS NI SUPL message. // See User Plane Location Protocol Candidate Version 3.0, // OMA-TS-ULP-V3_0-20110920-C, Section 8.4 MT SMS. intentFilter = new IntentFilter(); intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION); intentFilter.addDataScheme("sms"); intentFilter.addDataAuthority("localhost", "7275"); mContext.registerReceiver(mIntentReceiver, intentFilter, null, mHandler); } }, intentFilter, null, mHandler); mNetworkConnectivityHandler.registerNetworkCallbacks(); Loading @@ -560,6 +571,80 @@ public class GnssLocationProvider extends AbstractLocationProvider implements updateEnabled(); } private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action); if (action == null) { return; } switch (action) { case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED: case TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED: subscriptionOrCarrierConfigChanged(); break; case Intents.WAP_PUSH_RECEIVED_ACTION: case Intents.DATA_SMS_RECEIVED_ACTION: injectSuplInit(intent); break; } } }; private void injectSuplInit(Intent intent) { if (!isNfwLocationAccessAllowed()) { Log.w(TAG, "Reject SUPL INIT as no NFW location access"); return; } int slotIndex = intent.getIntExtra(SubscriptionManager.EXTRA_SLOT_INDEX, SubscriptionManager.INVALID_SIM_SLOT_INDEX); if (slotIndex == SubscriptionManager.INVALID_SIM_SLOT_INDEX) { Log.e(TAG, "Invalid slot index"); return; } byte[] suplInit = null; String action = intent.getAction(); if (action.equals(Intents.DATA_SMS_RECEIVED_ACTION)) { SmsMessage[] messages = Intents.getMessagesFromIntent(intent); if (messages == null) { Log.e(TAG, "Message does not exist in the intent"); return; } for (SmsMessage message : messages) { suplInit = message.getUserData(); injectSuplInit(suplInit, slotIndex); } } else if (action.equals(Intents.WAP_PUSH_RECEIVED_ACTION)) { suplInit = intent.getByteArrayExtra("data"); injectSuplInit(suplInit, slotIndex); } } private void injectSuplInit(byte[] suplInit, int slotIndex) { if (suplInit != null) { if (DEBUG) { Log.d(TAG, "suplInit = " + HexDump.toHexString(suplInit) + " slotIndex = " + slotIndex); } mGnssNative.injectNiSuplMessageData(suplInit, suplInit.length , slotIndex); } } private boolean isNfwLocationAccessAllowed() { if (mGnssNative.isInEmergencySession()) { return true; } if (mGnssVisibilityControl != null && mGnssVisibilityControl.hasLocationPermissionEnabledProxyApps()) { return true; } return false; } /** * Implements {@link InjectNtpTimeCallback#injectTime} */ Loading services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java +4 −0 Original line number Diff line number Diff line Loading @@ -762,6 +762,10 @@ class GnssNetworkConnectivityHandler { return APN_INVALID; } protected boolean isNativeAgpsRilSupported() { return native_is_agps_ril_supported(); } // AGPS support private native void native_agps_data_conn_open(long networkHandle, String apn, int apnIpType); Loading services/core/java/com/android/server/location/gnss/GnssVisibilityControl.java +4 −0 Original line number Diff line number Diff line Loading @@ -437,6 +437,10 @@ class GnssVisibilityControl { return locationPermissionEnabledProxyApps; } public boolean hasLocationPermissionEnabledProxyApps() { return getLocationPermissionEnabledProxyApps().length > 0; } private void handleNfwNotification(NfwNotification nfwNotification) { if (DEBUG) Log.d(TAG, "Non-framework location access notification: " + nfwNotification); Loading services/core/java/com/android/server/location/gnss/hal/GnssNative.java +16 −1 Original line number Diff line number Diff line Loading @@ -989,6 +989,14 @@ public class GnssNative { mGnssHal.injectPsdsData(data, length, psdsType); } /** * Injects NI SUPL message data into the GNSS HAL. */ public void injectNiSuplMessageData(byte[] data, int length, int slotIndex) { Preconditions.checkState(mRegistered); mGnssHal.injectNiSuplMessageData(data, length, slotIndex); } @NativeEntryPoint void reportGnssServiceDied() { // Not necessary to clear (and restore) binder identity since it runs on another thread. Loading Loading @@ -1278,7 +1286,7 @@ public class GnssNative { } @NativeEntryPoint boolean isInEmergencySession() { public boolean isInEmergencySession() { return Binder.withCleanCallingIdentity( () -> mEmergencyHelper.isInEmergency( TimeUnit.SECONDS.toMillis(mConfiguration.getEsExtensionSec()))); Loading Loading @@ -1507,6 +1515,10 @@ public class GnssNative { protected void injectPsdsData(byte[] data, int length, int psdsType) { native_inject_psds_data(data, length, psdsType); } protected void injectNiSuplMessageData(byte[] data, int length, int slotIndex) { native_inject_ni_supl_message_data(data, length, slotIndex); } } // basic APIs Loading Loading @@ -1650,6 +1662,9 @@ public class GnssNative { private static native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc, int lac, long cid, int tac, int pcid, int arfcn); private static native void native_inject_ni_supl_message_data(byte[] data, int length, int slotIndex); // PSDS APIs private static native boolean native_supports_psds(); Loading Loading
services/core/java/com/android/server/location/gnss/GnssConfiguration.java +10 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,8 @@ public class GnssConfiguration { "ENABLE_PSDS_PERIODIC_DOWNLOAD"; private static final String CONFIG_ENABLE_ACTIVE_SIM_EMERGENCY_SUPL = "ENABLE_ACTIVE_SIM_EMERGENCY_SUPL"; private static final String CONFIG_ENABLE_NI_SUPL_MESSAGE_INJECTION = "ENABLE_NI_SUPL_MESSAGE_INJECTION"; static final String CONFIG_LONGTERM_PSDS_SERVER_1 = "LONGTERM_PSDS_SERVER_1"; static final String CONFIG_LONGTERM_PSDS_SERVER_2 = "LONGTERM_PSDS_SERVER_2"; static final String CONFIG_LONGTERM_PSDS_SERVER_3 = "LONGTERM_PSDS_SERVER_3"; Loading Loading @@ -217,6 +219,14 @@ public class GnssConfiguration { return getBooleanConfig(CONFIG_ENABLE_ACTIVE_SIM_EMERGENCY_SUPL, false); } /** * Returns true if NI SUPL message injection is enabled; Returns false otherwise. * Default false if not set. */ boolean isNiSuplMessageInjectionEnabled() { return getBooleanConfig(CONFIG_ENABLE_NI_SUPL_MESSAGE_INJECTION, false); } /** * Returns true if a long-term PSDS server is configured. */ Loading
services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +101 −16 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ import android.os.UserHandle; import android.os.WorkSource; import android.os.WorkSource.WorkChain; import android.provider.Settings; import android.provider.Telephony.Sms.Intents; import android.telephony.CarrierConfigManager; import android.telephony.CellIdentity; import android.telephony.CellIdentityGsm; Loading @@ -95,6 +96,7 @@ import android.telephony.CellInfoGsm; import android.telephony.CellInfoLte; import android.telephony.CellInfoNr; import android.telephony.CellInfoWcdma; import android.telephony.SmsMessage; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; Loading @@ -107,6 +109,7 @@ import com.android.internal.app.IBatteryStats; import com.android.internal.location.GpsNetInitiatedHandler; import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.HexDump; import com.android.server.FgThread; import com.android.server.location.gnss.GnssSatelliteBlocklistHelper.GnssSatelliteBlocklistCallback; import com.android.server.location.gnss.NtpTimeHelper.InjectNtpTimeCallback; Loading Loading @@ -523,23 +526,31 @@ public class GnssLocationProvider extends AbstractLocationProvider implements IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); intentFilter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action); if (action == null) { return; mContext.registerReceiver(mIntentReceiver, intentFilter, null, mHandler); if (mNetworkConnectivityHandler.isNativeAgpsRilSupported() && mGnssConfiguration.isNiSuplMessageInjectionEnabled()) { // Listen to WAP PUSH NI SUPL message. // See User Plane Location Protocol Candidate Version 3.0, // OMA-TS-ULP-V3_0-20110920-C, Section 8.3 OMA Push. intentFilter = new IntentFilter(); intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION); try { intentFilter.addDataType("application/vnd.omaloc-supl-init"); } catch (IntentFilter.MalformedMimeTypeException e) { Log.w(TAG, "Malformed SUPL init mime type"); } mContext.registerReceiver(mIntentReceiver, intentFilter, null, mHandler); switch (action) { case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED: case TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED: subscriptionOrCarrierConfigChanged(); break; } // Listen to MT SMS NI SUPL message. // See User Plane Location Protocol Candidate Version 3.0, // OMA-TS-ULP-V3_0-20110920-C, Section 8.4 MT SMS. intentFilter = new IntentFilter(); intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION); intentFilter.addDataScheme("sms"); intentFilter.addDataAuthority("localhost", "7275"); mContext.registerReceiver(mIntentReceiver, intentFilter, null, mHandler); } }, intentFilter, null, mHandler); mNetworkConnectivityHandler.registerNetworkCallbacks(); Loading @@ -560,6 +571,80 @@ public class GnssLocationProvider extends AbstractLocationProvider implements updateEnabled(); } private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action); if (action == null) { return; } switch (action) { case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED: case TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED: subscriptionOrCarrierConfigChanged(); break; case Intents.WAP_PUSH_RECEIVED_ACTION: case Intents.DATA_SMS_RECEIVED_ACTION: injectSuplInit(intent); break; } } }; private void injectSuplInit(Intent intent) { if (!isNfwLocationAccessAllowed()) { Log.w(TAG, "Reject SUPL INIT as no NFW location access"); return; } int slotIndex = intent.getIntExtra(SubscriptionManager.EXTRA_SLOT_INDEX, SubscriptionManager.INVALID_SIM_SLOT_INDEX); if (slotIndex == SubscriptionManager.INVALID_SIM_SLOT_INDEX) { Log.e(TAG, "Invalid slot index"); return; } byte[] suplInit = null; String action = intent.getAction(); if (action.equals(Intents.DATA_SMS_RECEIVED_ACTION)) { SmsMessage[] messages = Intents.getMessagesFromIntent(intent); if (messages == null) { Log.e(TAG, "Message does not exist in the intent"); return; } for (SmsMessage message : messages) { suplInit = message.getUserData(); injectSuplInit(suplInit, slotIndex); } } else if (action.equals(Intents.WAP_PUSH_RECEIVED_ACTION)) { suplInit = intent.getByteArrayExtra("data"); injectSuplInit(suplInit, slotIndex); } } private void injectSuplInit(byte[] suplInit, int slotIndex) { if (suplInit != null) { if (DEBUG) { Log.d(TAG, "suplInit = " + HexDump.toHexString(suplInit) + " slotIndex = " + slotIndex); } mGnssNative.injectNiSuplMessageData(suplInit, suplInit.length , slotIndex); } } private boolean isNfwLocationAccessAllowed() { if (mGnssNative.isInEmergencySession()) { return true; } if (mGnssVisibilityControl != null && mGnssVisibilityControl.hasLocationPermissionEnabledProxyApps()) { return true; } return false; } /** * Implements {@link InjectNtpTimeCallback#injectTime} */ Loading
services/core/java/com/android/server/location/gnss/GnssNetworkConnectivityHandler.java +4 −0 Original line number Diff line number Diff line Loading @@ -762,6 +762,10 @@ class GnssNetworkConnectivityHandler { return APN_INVALID; } protected boolean isNativeAgpsRilSupported() { return native_is_agps_ril_supported(); } // AGPS support private native void native_agps_data_conn_open(long networkHandle, String apn, int apnIpType); Loading
services/core/java/com/android/server/location/gnss/GnssVisibilityControl.java +4 −0 Original line number Diff line number Diff line Loading @@ -437,6 +437,10 @@ class GnssVisibilityControl { return locationPermissionEnabledProxyApps; } public boolean hasLocationPermissionEnabledProxyApps() { return getLocationPermissionEnabledProxyApps().length > 0; } private void handleNfwNotification(NfwNotification nfwNotification) { if (DEBUG) Log.d(TAG, "Non-framework location access notification: " + nfwNotification); Loading
services/core/java/com/android/server/location/gnss/hal/GnssNative.java +16 −1 Original line number Diff line number Diff line Loading @@ -989,6 +989,14 @@ public class GnssNative { mGnssHal.injectPsdsData(data, length, psdsType); } /** * Injects NI SUPL message data into the GNSS HAL. */ public void injectNiSuplMessageData(byte[] data, int length, int slotIndex) { Preconditions.checkState(mRegistered); mGnssHal.injectNiSuplMessageData(data, length, slotIndex); } @NativeEntryPoint void reportGnssServiceDied() { // Not necessary to clear (and restore) binder identity since it runs on another thread. Loading Loading @@ -1278,7 +1286,7 @@ public class GnssNative { } @NativeEntryPoint boolean isInEmergencySession() { public boolean isInEmergencySession() { return Binder.withCleanCallingIdentity( () -> mEmergencyHelper.isInEmergency( TimeUnit.SECONDS.toMillis(mConfiguration.getEsExtensionSec()))); Loading Loading @@ -1507,6 +1515,10 @@ public class GnssNative { protected void injectPsdsData(byte[] data, int length, int psdsType) { native_inject_psds_data(data, length, psdsType); } protected void injectNiSuplMessageData(byte[] data, int length, int slotIndex) { native_inject_ni_supl_message_data(data, length, slotIndex); } } // basic APIs Loading Loading @@ -1650,6 +1662,9 @@ public class GnssNative { private static native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc, int lac, long cid, int tac, int pcid, int arfcn); private static native void native_inject_ni_supl_message_data(byte[] data, int length, int slotIndex); // PSDS APIs private static native boolean native_supports_psds(); Loading