Loading services/core/java/com/android/server/location/GnssLocationProvider.java +154 −23 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.location; import android.annotation.Nullable; import android.app.AlarmManager; import android.app.AppOpsManager; import android.app.PendingIntent; Loading @@ -28,11 +29,11 @@ import android.hardware.location.GeofenceHardware; import android.hardware.location.GeofenceHardwareImpl; import android.location.Criteria; import android.location.FusedBatchOptions; import android.location.GnssMeasurementsEvent; import android.location.GnssNavigationMessage; import android.location.GnssStatus; import android.location.IGnssStatusListener; import android.location.IGnssStatusProvider; import android.location.GnssMeasurementsEvent; import android.location.GnssNavigationMessage; import android.location.IGpsGeofenceHardware; import android.location.ILocationManager; import android.location.INetInitiatedListener; Loading @@ -48,16 +49,16 @@ import android.net.NetworkInfo; import android.net.NetworkRequest; import android.net.Uri; import android.os.AsyncTask; import android.os.PowerManager.ServiceType; import android.os.PowerSaveState; import android.os.BatteryStats; import android.os.Binder; import android.os.Bundle; import android.os.PersistableBundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.PersistableBundle; import android.os.PowerManager; import android.os.PowerManager.ServiceType; import android.os.PowerSaveState; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; Loading @@ -68,25 +69,21 @@ import android.os.WorkSource.WorkChain; import android.provider.Settings; import android.provider.Telephony.Carriers; import android.provider.Telephony.Sms.Intents; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; import android.telephony.TelephonyManager; import android.telephony.CarrierConfigManager; import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; import android.util.Log; import android.util.NtpTrustedTime; import com.android.internal.app.IAppOpsService; import com.android.internal.app.IBatteryStats; import com.android.internal.location.gnssmetrics.GnssMetrics; import com.android.internal.location.GpsNetInitiatedHandler; import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification; import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; import libcore.io.IoUtils; import com.android.internal.location.gnssmetrics.GnssMetrics; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; Loading @@ -97,11 +94,13 @@ import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Map; import java.util.HashMap; import libcore.io.IoUtils; /** * A GNSS implementation of LocationProvider used by LocationManager. Loading Loading @@ -215,6 +214,7 @@ public class GnssLocationProvider implements LocationProviderInterface { private static final int INITIALIZE_HANDLER = 13; private static final int REQUEST_SUPL_CONNECTION = 14; private static final int RELEASE_SUPL_CONNECTION = 15; private static final int REQUEST_LOCATION = 16; // Request setid private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1; Loading Loading @@ -248,6 +248,13 @@ public class GnssLocationProvider implements LocationProviderInterface { private static final int TCP_MIN_PORT = 0; private static final int TCP_MAX_PORT = 0xffff; // 10 seconds. private static final long LOCATION_TIME_FRESHNESS_THESHOLD_MILLIS = 10 * 1000; // 1 second, or 1 Hz frequency. private static final long LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS = 1000; // 30 seconds. private static final long LOCATION_UPDATE_DURATION_MILLIS = 30 * 1000; /** simpler wrapper for ProviderRequest + Worksource */ private static class GpsRequest { public ProviderRequest request; Loading Loading @@ -409,6 +416,8 @@ public class GnssLocationProvider implements LocationProviderInterface { private final GnssStatusListenerHelper mListenerHelper; private final GnssMeasurementsProvider mGnssMeasurementsProvider; private final GnssNavigationMessageProvider mGnssNavigationMessageProvider; private final FusedLocationListener mFusedLocationListener = new FusedLocationListener(); private static int sNumFusedLocationUpdatesRequests = 0; // Handler for processing events private Handler mHandler; Loading Loading @@ -1074,6 +1083,89 @@ public class GnssLocationProvider implements LocationProviderInterface { }); } private void handleRequestLocation(boolean independentFromGnss) { if (isRequestLocationRateLimited()) { if (DEBUG) { Log.d(TAG, "RequestLocation is denied due to too frequent requests."); } return; } LocationManager locationManager = (LocationManager) mContext.getSystemService( Context.LOCATION_SERVICE); if (independentFromGnss) { // For fast GNSS TTFF Location networkLocation = getLastFreshLocation(locationManager, LocationManager.NETWORK_PROVIDER); if (networkLocation != null) { handleUpdateLocation(networkLocation); return; } locationManager.requestSingleUpdate(LocationManager.NETWORK_PROVIDER, new NetworkLocationListener(), mHandler.getLooper()); } else { // For Device-Based Hybrid (E911) locationManager.requestLocationUpdates(LocationManager.FUSED_PROVIDER, LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0, mFusedLocationListener, mHandler.getLooper()); sNumFusedLocationUpdatesRequests++; mHandler.postDelayed(() -> { if (--sNumFusedLocationUpdatesRequests == 0) { locationManager.removeUpdates(mFusedLocationListener); } }, LOCATION_UPDATE_DURATION_MILLIS); } } private void injectBestLocation(Location location) { int gnssLocationFlags = LOCATION_HAS_LAT_LONG | (location.hasAltitude() ? LOCATION_HAS_ALTITUDE : 0) | (location.hasSpeed() ? LOCATION_HAS_SPEED : 0) | (location.hasBearing() ? LOCATION_HAS_BEARING : 0) | (location.hasAccuracy() ? LOCATION_HAS_HORIZONTAL_ACCURACY : 0) | (location.hasVerticalAccuracy() ? LOCATION_HAS_VERTICAL_ACCURACY : 0) | (location.hasSpeedAccuracy() ? LOCATION_HAS_SPEED_ACCURACY : 0) | (location.hasBearingAccuracy() ? LOCATION_HAS_BEARING_ACCURACY : 0); double latitudeDegrees = location.getLatitude(); double longitudeDegrees = location.getLongitude(); double altitudeMeters = location.getAltitude(); float speedMetersPerSec = location.getSpeed(); float bearingDegrees = location.getBearing(); float horizontalAccuracyMeters = location.getAccuracy(); float verticalAccuracyMeters = location.getVerticalAccuracyMeters(); float speedAccuracyMetersPerSecond = location.getSpeedAccuracyMetersPerSecond(); float bearingAccuracyDegrees = location.getBearingAccuracyDegrees(); long timestamp = location.getTime(); native_inject_best_location(gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters, speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters, verticalAccuracyMeters, speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp); } /** * Get the last fresh location. * * Return null if the last location is not available or not fresh. */ private @Nullable Location getLastFreshLocation(LocationManager locationManager, String provider) { Location location = locationManager.getLastKnownLocation(provider); if (location != null && System.currentTimeMillis() - location.getTime() < LOCATION_TIME_FRESHNESS_THESHOLD_MILLIS) { return location; } return null; } /** Returns true if the location request is too frequent. */ private boolean isRequestLocationRateLimited() { // TODO(b/73198123): implement exponential backoff. return false; } private void handleDownloadXtraData() { if (!mSupportsXtra) { // native code reports xtra not supported, don't try Loading Loading @@ -2270,6 +2362,16 @@ public class GnssLocationProvider implements LocationProviderInterface { native_agps_set_id(type, data); } /** * Called from native code to request location info. */ private void requestLocation(boolean independentFromGnss) { if (DEBUG) { Log.d(TAG, "requestLocation. independentFromGnss: " + independentFromGnss); } sendMessage(REQUEST_LOCATION, 0, independentFromGnss); } /** * Called from native code to request utc time info */ Loading @@ -2281,7 +2383,6 @@ public class GnssLocationProvider implements LocationProviderInterface { /** * Called from native code to request reference location info */ private void requestRefLocation() { TelephonyManager phone = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); Loading Loading @@ -2357,6 +2458,9 @@ public class GnssLocationProvider implements LocationProviderInterface { case INJECT_NTP_TIME: handleInjectNtpTime(); break; case REQUEST_LOCATION: handleRequestLocation((boolean) msg.obj); break; case DOWNLOAD_XTRA_DATA: handleDownloadXtraData(); break; Loading Loading @@ -2482,25 +2586,37 @@ public class GnssLocationProvider implements LocationProviderInterface { } } private final class NetworkLocationListener implements LocationListener { private abstract class LocationChangeListener implements LocationListener { @Override public void onLocationChanged(Location location) { // this callback happens on mHandler looper if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) { handleUpdateLocation(location); public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { public void onProviderDisabled(String provider) { } } private final class NetworkLocationListener extends LocationChangeListener { @Override public void onProviderEnabled(String provider) { public void onLocationChanged(Location location) { // this callback happens on mHandler looper if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) { handleUpdateLocation(location); } } } private final class FusedLocationListener extends LocationChangeListener { @Override public void onProviderDisabled(String provider) { public void onLocationChanged(Location location) { if (LocationManager.FUSED_PROVIDER.equals(location.getProvider())) { Log.d(TAG, "fused location listener: " + location); injectBestLocation(location); } } } Loading Loading @@ -2668,6 +2784,8 @@ public class GnssLocationProvider implements LocationProviderInterface { return "RELEASE_SUPL_CONNECTION"; case INJECT_NTP_TIME: return "INJECT_NTP_TIME"; case REQUEST_LOCATION: return "REQUEST_LOCATION"; case DOWNLOAD_XTRA_DATA: return "DOWNLOAD_XTRA_DATA"; case INJECT_NTP_TIME_FINISHED: Loading Loading @@ -2788,6 +2906,19 @@ public class GnssLocationProvider implements LocationProviderInterface { private native int native_read_nmea(byte[] buffer, int bufferSize); private native void native_inject_best_location( int gnssLocationFlags, double latitudeDegrees, double longitudeDegrees, double altitudeMeters, float speedMetersPerSec, float bearingDegrees, float horizontalAccuracyMeters, float verticalAccuracyMeters, float speedAccuracyMetersPerSecond, float bearingAccuracyDegrees, long timestamp); private native void native_inject_location(double latitude, double longitude, float accuracy); // XTRA Support Loading services/core/jni/com_android_server_location_GnssLocationProvider.cpp +72 −1 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ static jmethodID method_setGnssYearOfHardware; static jmethodID method_setGnssHardwareModelName; static jmethodID method_xtraDownloadRequest; static jmethodID method_reportNiNotification; static jmethodID method_requestLocation; static jmethodID method_requestRefLocation; static jmethodID method_requestSetID; static jmethodID method_requestUtcTime; Loading Loading @@ -346,6 +347,34 @@ static jobject translateLocation(JNIEnv* env, const GnssLocation& location) { return object.get(); } static GnssLocation createGnssLocation( jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees, jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees, jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters, jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees, jlong timestamp) { GnssLocation location; location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags); location.latitudeDegrees = static_cast<double>(latitudeDegrees); location.longitudeDegrees = static_cast<double>(longitudeDegrees); location.altitudeMeters = static_cast<double>(altitudeMeters); location.speedMetersPerSec = static_cast<float>(speedMetersPerSec); location.bearingDegrees = static_cast<float>(bearingDegrees); location.horizontalAccuracyMeters = static_cast<float>(horizontalAccuracyMeters); location.verticalAccuracyMeters = static_cast<float>(verticalAccuracyMeters); location.speedAccuracyMetersPerSecond = static_cast<float>(speedAccuracyMetersPerSecond); location.bearingAccuracyDegrees = static_cast<float>(bearingAccuracyDegrees); location.timestamp = static_cast<uint64_t>(timestamp); return location; } /* * GnssCallback class implements the callback methods for IGnss interface. */ Loading Loading @@ -474,7 +503,9 @@ Return<void> GnssCallback::gnssRequestTimeCb() { } Return<void> GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) { // TODO(b/72405645): call into java implementation JNIEnv* env = getJniEnv(); env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss)); checkAndClearExceptionFromCallback(env, __FUNCTION__); return Void(); } Loading Loading @@ -1042,6 +1073,7 @@ static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V"); method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification", "(IIIIILjava/lang/String;Ljava/lang/String;II)V"); method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(Z)V"); method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V"); method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V"); method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V"); Loading Loading @@ -1441,6 +1473,42 @@ static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, } } static void android_location_GnssLocationProvider_inject_best_location( JNIEnv*, jobject, jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees, jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees, jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters, jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees, jlong timestamp) { if (gnssHal_V1_1 != nullptr) { GnssLocation location = createGnssLocation( gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters, speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters, verticalAccuracyMeters, speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp); auto result = gnssHal_V1_1->injectBestLocation(location); if (!result.isOk() || !result) { ALOGE("%s: Gnss injectBestLocation() failed.", __func__); } } else { ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__); } } static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */, jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) { if (gnssHal != nullptr) { Loading Loading @@ -1996,6 +2064,9 @@ static const JNINativeMethod sMethods[] = { android_location_GnssLocationProvider_read_nmea)}, {"native_inject_time", "(JJI)V", reinterpret_cast<void *>( android_location_GnssLocationProvider_inject_time)}, {"native_inject_best_location", "(IDDDFFFFFFJ)V", reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_best_location)}, {"native_inject_location", "(DDF)V", reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)}, Loading Loading
services/core/java/com/android/server/location/GnssLocationProvider.java +154 −23 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.location; import android.annotation.Nullable; import android.app.AlarmManager; import android.app.AppOpsManager; import android.app.PendingIntent; Loading @@ -28,11 +29,11 @@ import android.hardware.location.GeofenceHardware; import android.hardware.location.GeofenceHardwareImpl; import android.location.Criteria; import android.location.FusedBatchOptions; import android.location.GnssMeasurementsEvent; import android.location.GnssNavigationMessage; import android.location.GnssStatus; import android.location.IGnssStatusListener; import android.location.IGnssStatusProvider; import android.location.GnssMeasurementsEvent; import android.location.GnssNavigationMessage; import android.location.IGpsGeofenceHardware; import android.location.ILocationManager; import android.location.INetInitiatedListener; Loading @@ -48,16 +49,16 @@ import android.net.NetworkInfo; import android.net.NetworkRequest; import android.net.Uri; import android.os.AsyncTask; import android.os.PowerManager.ServiceType; import android.os.PowerSaveState; import android.os.BatteryStats; import android.os.Binder; import android.os.Bundle; import android.os.PersistableBundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.PersistableBundle; import android.os.PowerManager; import android.os.PowerManager.ServiceType; import android.os.PowerSaveState; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; Loading @@ -68,25 +69,21 @@ import android.os.WorkSource.WorkChain; import android.provider.Settings; import android.provider.Telephony.Carriers; import android.provider.Telephony.Sms.Intents; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; import android.telephony.TelephonyManager; import android.telephony.CarrierConfigManager; import android.telephony.gsm.GsmCellLocation; import android.text.TextUtils; import android.util.Log; import android.util.NtpTrustedTime; import com.android.internal.app.IAppOpsService; import com.android.internal.app.IBatteryStats; import com.android.internal.location.gnssmetrics.GnssMetrics; import com.android.internal.location.GpsNetInitiatedHandler; import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification; import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; import libcore.io.IoUtils; import com.android.internal.location.gnssmetrics.GnssMetrics; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; Loading @@ -97,11 +94,13 @@ import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Map; import java.util.HashMap; import libcore.io.IoUtils; /** * A GNSS implementation of LocationProvider used by LocationManager. Loading Loading @@ -215,6 +214,7 @@ public class GnssLocationProvider implements LocationProviderInterface { private static final int INITIALIZE_HANDLER = 13; private static final int REQUEST_SUPL_CONNECTION = 14; private static final int RELEASE_SUPL_CONNECTION = 15; private static final int REQUEST_LOCATION = 16; // Request setid private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1; Loading Loading @@ -248,6 +248,13 @@ public class GnssLocationProvider implements LocationProviderInterface { private static final int TCP_MIN_PORT = 0; private static final int TCP_MAX_PORT = 0xffff; // 10 seconds. private static final long LOCATION_TIME_FRESHNESS_THESHOLD_MILLIS = 10 * 1000; // 1 second, or 1 Hz frequency. private static final long LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS = 1000; // 30 seconds. private static final long LOCATION_UPDATE_DURATION_MILLIS = 30 * 1000; /** simpler wrapper for ProviderRequest + Worksource */ private static class GpsRequest { public ProviderRequest request; Loading Loading @@ -409,6 +416,8 @@ public class GnssLocationProvider implements LocationProviderInterface { private final GnssStatusListenerHelper mListenerHelper; private final GnssMeasurementsProvider mGnssMeasurementsProvider; private final GnssNavigationMessageProvider mGnssNavigationMessageProvider; private final FusedLocationListener mFusedLocationListener = new FusedLocationListener(); private static int sNumFusedLocationUpdatesRequests = 0; // Handler for processing events private Handler mHandler; Loading Loading @@ -1074,6 +1083,89 @@ public class GnssLocationProvider implements LocationProviderInterface { }); } private void handleRequestLocation(boolean independentFromGnss) { if (isRequestLocationRateLimited()) { if (DEBUG) { Log.d(TAG, "RequestLocation is denied due to too frequent requests."); } return; } LocationManager locationManager = (LocationManager) mContext.getSystemService( Context.LOCATION_SERVICE); if (independentFromGnss) { // For fast GNSS TTFF Location networkLocation = getLastFreshLocation(locationManager, LocationManager.NETWORK_PROVIDER); if (networkLocation != null) { handleUpdateLocation(networkLocation); return; } locationManager.requestSingleUpdate(LocationManager.NETWORK_PROVIDER, new NetworkLocationListener(), mHandler.getLooper()); } else { // For Device-Based Hybrid (E911) locationManager.requestLocationUpdates(LocationManager.FUSED_PROVIDER, LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0, mFusedLocationListener, mHandler.getLooper()); sNumFusedLocationUpdatesRequests++; mHandler.postDelayed(() -> { if (--sNumFusedLocationUpdatesRequests == 0) { locationManager.removeUpdates(mFusedLocationListener); } }, LOCATION_UPDATE_DURATION_MILLIS); } } private void injectBestLocation(Location location) { int gnssLocationFlags = LOCATION_HAS_LAT_LONG | (location.hasAltitude() ? LOCATION_HAS_ALTITUDE : 0) | (location.hasSpeed() ? LOCATION_HAS_SPEED : 0) | (location.hasBearing() ? LOCATION_HAS_BEARING : 0) | (location.hasAccuracy() ? LOCATION_HAS_HORIZONTAL_ACCURACY : 0) | (location.hasVerticalAccuracy() ? LOCATION_HAS_VERTICAL_ACCURACY : 0) | (location.hasSpeedAccuracy() ? LOCATION_HAS_SPEED_ACCURACY : 0) | (location.hasBearingAccuracy() ? LOCATION_HAS_BEARING_ACCURACY : 0); double latitudeDegrees = location.getLatitude(); double longitudeDegrees = location.getLongitude(); double altitudeMeters = location.getAltitude(); float speedMetersPerSec = location.getSpeed(); float bearingDegrees = location.getBearing(); float horizontalAccuracyMeters = location.getAccuracy(); float verticalAccuracyMeters = location.getVerticalAccuracyMeters(); float speedAccuracyMetersPerSecond = location.getSpeedAccuracyMetersPerSecond(); float bearingAccuracyDegrees = location.getBearingAccuracyDegrees(); long timestamp = location.getTime(); native_inject_best_location(gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters, speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters, verticalAccuracyMeters, speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp); } /** * Get the last fresh location. * * Return null if the last location is not available or not fresh. */ private @Nullable Location getLastFreshLocation(LocationManager locationManager, String provider) { Location location = locationManager.getLastKnownLocation(provider); if (location != null && System.currentTimeMillis() - location.getTime() < LOCATION_TIME_FRESHNESS_THESHOLD_MILLIS) { return location; } return null; } /** Returns true if the location request is too frequent. */ private boolean isRequestLocationRateLimited() { // TODO(b/73198123): implement exponential backoff. return false; } private void handleDownloadXtraData() { if (!mSupportsXtra) { // native code reports xtra not supported, don't try Loading Loading @@ -2270,6 +2362,16 @@ public class GnssLocationProvider implements LocationProviderInterface { native_agps_set_id(type, data); } /** * Called from native code to request location info. */ private void requestLocation(boolean independentFromGnss) { if (DEBUG) { Log.d(TAG, "requestLocation. independentFromGnss: " + independentFromGnss); } sendMessage(REQUEST_LOCATION, 0, independentFromGnss); } /** * Called from native code to request utc time info */ Loading @@ -2281,7 +2383,6 @@ public class GnssLocationProvider implements LocationProviderInterface { /** * Called from native code to request reference location info */ private void requestRefLocation() { TelephonyManager phone = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); Loading Loading @@ -2357,6 +2458,9 @@ public class GnssLocationProvider implements LocationProviderInterface { case INJECT_NTP_TIME: handleInjectNtpTime(); break; case REQUEST_LOCATION: handleRequestLocation((boolean) msg.obj); break; case DOWNLOAD_XTRA_DATA: handleDownloadXtraData(); break; Loading Loading @@ -2482,25 +2586,37 @@ public class GnssLocationProvider implements LocationProviderInterface { } } private final class NetworkLocationListener implements LocationListener { private abstract class LocationChangeListener implements LocationListener { @Override public void onLocationChanged(Location location) { // this callback happens on mHandler looper if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) { handleUpdateLocation(location); public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { public void onProviderDisabled(String provider) { } } private final class NetworkLocationListener extends LocationChangeListener { @Override public void onProviderEnabled(String provider) { public void onLocationChanged(Location location) { // this callback happens on mHandler looper if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) { handleUpdateLocation(location); } } } private final class FusedLocationListener extends LocationChangeListener { @Override public void onProviderDisabled(String provider) { public void onLocationChanged(Location location) { if (LocationManager.FUSED_PROVIDER.equals(location.getProvider())) { Log.d(TAG, "fused location listener: " + location); injectBestLocation(location); } } } Loading Loading @@ -2668,6 +2784,8 @@ public class GnssLocationProvider implements LocationProviderInterface { return "RELEASE_SUPL_CONNECTION"; case INJECT_NTP_TIME: return "INJECT_NTP_TIME"; case REQUEST_LOCATION: return "REQUEST_LOCATION"; case DOWNLOAD_XTRA_DATA: return "DOWNLOAD_XTRA_DATA"; case INJECT_NTP_TIME_FINISHED: Loading Loading @@ -2788,6 +2906,19 @@ public class GnssLocationProvider implements LocationProviderInterface { private native int native_read_nmea(byte[] buffer, int bufferSize); private native void native_inject_best_location( int gnssLocationFlags, double latitudeDegrees, double longitudeDegrees, double altitudeMeters, float speedMetersPerSec, float bearingDegrees, float horizontalAccuracyMeters, float verticalAccuracyMeters, float speedAccuracyMetersPerSecond, float bearingAccuracyDegrees, long timestamp); private native void native_inject_location(double latitude, double longitude, float accuracy); // XTRA Support Loading
services/core/jni/com_android_server_location_GnssLocationProvider.cpp +72 −1 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ static jmethodID method_setGnssYearOfHardware; static jmethodID method_setGnssHardwareModelName; static jmethodID method_xtraDownloadRequest; static jmethodID method_reportNiNotification; static jmethodID method_requestLocation; static jmethodID method_requestRefLocation; static jmethodID method_requestSetID; static jmethodID method_requestUtcTime; Loading Loading @@ -346,6 +347,34 @@ static jobject translateLocation(JNIEnv* env, const GnssLocation& location) { return object.get(); } static GnssLocation createGnssLocation( jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees, jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees, jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters, jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees, jlong timestamp) { GnssLocation location; location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags); location.latitudeDegrees = static_cast<double>(latitudeDegrees); location.longitudeDegrees = static_cast<double>(longitudeDegrees); location.altitudeMeters = static_cast<double>(altitudeMeters); location.speedMetersPerSec = static_cast<float>(speedMetersPerSec); location.bearingDegrees = static_cast<float>(bearingDegrees); location.horizontalAccuracyMeters = static_cast<float>(horizontalAccuracyMeters); location.verticalAccuracyMeters = static_cast<float>(verticalAccuracyMeters); location.speedAccuracyMetersPerSecond = static_cast<float>(speedAccuracyMetersPerSecond); location.bearingAccuracyDegrees = static_cast<float>(bearingAccuracyDegrees); location.timestamp = static_cast<uint64_t>(timestamp); return location; } /* * GnssCallback class implements the callback methods for IGnss interface. */ Loading Loading @@ -474,7 +503,9 @@ Return<void> GnssCallback::gnssRequestTimeCb() { } Return<void> GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) { // TODO(b/72405645): call into java implementation JNIEnv* env = getJniEnv(); env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss)); checkAndClearExceptionFromCallback(env, __FUNCTION__); return Void(); } Loading Loading @@ -1042,6 +1073,7 @@ static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V"); method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification", "(IIIIILjava/lang/String;Ljava/lang/String;II)V"); method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(Z)V"); method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V"); method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V"); method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V"); Loading Loading @@ -1441,6 +1473,42 @@ static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, } } static void android_location_GnssLocationProvider_inject_best_location( JNIEnv*, jobject, jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees, jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees, jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters, jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees, jlong timestamp) { if (gnssHal_V1_1 != nullptr) { GnssLocation location = createGnssLocation( gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters, speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters, verticalAccuracyMeters, speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp); auto result = gnssHal_V1_1->injectBestLocation(location); if (!result.isOk() || !result) { ALOGE("%s: Gnss injectBestLocation() failed.", __func__); } } else { ALOGE("%s: injectBestLocation() is called but gnssHal_V1_1 is not available.", __func__); } } static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */, jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) { if (gnssHal != nullptr) { Loading Loading @@ -1996,6 +2064,9 @@ static const JNINativeMethod sMethods[] = { android_location_GnssLocationProvider_read_nmea)}, {"native_inject_time", "(JJI)V", reinterpret_cast<void *>( android_location_GnssLocationProvider_inject_time)}, {"native_inject_best_location", "(IDDDFFFFFFJ)V", reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_best_location)}, {"native_inject_location", "(DDF)V", reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)}, Loading