diff options
4 files changed, 159 insertions, 288 deletions
diff --git a/services/core/java/com/android/server/location/AbstractLocationProvider.java b/services/core/java/com/android/server/location/AbstractLocationProvider.java index 26bf6c15d21b..fac7952fb86a 100644 --- a/services/core/java/com/android/server/location/AbstractLocationProvider.java +++ b/services/core/java/com/android/server/location/AbstractLocationProvider.java @@ -310,6 +310,7 @@ public abstract class AbstractLocationProvider { * Sets a new request and worksource for the provider. */ public final void setRequest(ProviderRequest request) { + // TODO: do we want to hold a wakelock until onSetRequest is run? // all calls into the provider must be moved onto the provider thread to prevent deadlock mExecutor.execute(() -> onSetRequest(request)); } diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java index d225f968d593..086757f42e37 100644 --- a/services/core/java/com/android/server/location/LocationManagerService.java +++ b/services/core/java/com/android/server/location/LocationManagerService.java @@ -324,6 +324,8 @@ public class LocationManagerService extends ILocationManager.Stub { } void onSystemThirdPartyAppsCanStart() { + // network provider should always be initialized before the gps provider since the gps + // provider has unfortunate hard dependencies on the network provider ProxyLocationProvider networkProvider = ProxyLocationProvider.createAndRegister( mContext, NETWORK_LOCATION_SERVICE_ACTION, diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java index 55073c038c9d..593312e82f21 100644 --- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java @@ -16,11 +16,12 @@ package com.android.server.location.gnss; +import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; + import static java.util.concurrent.TimeUnit.MILLISECONDS; import android.app.AlarmManager; import android.app.AppOpsManager; -import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; @@ -45,10 +46,8 @@ import android.location.LocationResult; import android.location.util.identity.CallerIdentity; import android.os.AsyncTask; import android.os.BatteryStats; -import android.os.Binder; import android.os.Bundle; import android.os.Handler; -import android.os.HandlerExecutor; import android.os.Looper; import android.os.Message; import android.os.PersistableBundle; @@ -77,9 +76,7 @@ import com.android.internal.location.ProviderProperties; import com.android.internal.location.ProviderRequest; import com.android.internal.location.gnssmetrics.GnssMetrics; import com.android.internal.util.FrameworkStatsLog; -import com.android.server.DeviceIdleInternal; import com.android.server.FgThread; -import com.android.server.LocalServices; import com.android.server.location.AbstractLocationProvider; import com.android.server.location.gnss.GnssSatelliteBlocklistHelper.GnssSatelliteBlocklistCallback; import com.android.server.location.gnss.NtpTimeHelper.InjectNtpTimeCallback; @@ -91,6 +88,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; /** @@ -182,12 +180,9 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private static final int AGPS_SUPL_MODE_MSA = 0x02; private static final int AGPS_SUPL_MODE_MSB = 0x01; - private static final int UPDATE_LOW_POWER_MODE = 1; - private static final int SET_REQUEST = 3; private static final int INJECT_NTP_TIME = 5; // PSDS stands for Predicted Satellite Data Service private static final int DOWNLOAD_PSDS_DATA = 6; - private static final int INITIALIZE_HANDLER = 13; private static final int REQUEST_LOCATION = 16; private static final int REPORT_LOCATION = 17; // HAL reports location private static final int REPORT_SV_STATUS = 18; // HAL reports SV status @@ -270,8 +265,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } } - private final Object mLock = new Object(); - // stop trying if we do not receive a fix within 60 seconds private static final int NO_FIX_TIMEOUT = 60 * 1000; @@ -293,6 +286,23 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private static final long DOWNLOAD_PSDS_DATA_TIMEOUT_MS = 60 * 1000; private static final long WAKELOCK_TIMEOUT_MILLIS = 30 * 1000; + // threshold for delay in GNSS engine turning off before warning & error + private static final long LOCATION_OFF_DELAY_THRESHOLD_WARN_MILLIS = 2 * 1000; + private static final long LOCATION_OFF_DELAY_THRESHOLD_ERROR_MILLIS = 15 * 1000; + + private static final String DOWNLOAD_EXTRA_WAKELOCK_KEY = "GnssLocationProviderPsdsDownload"; + + // Set lower than the current ITAR limit of 600m/s to allow this to trigger even if GPS HAL + // stops output right at 600m/s, depriving this of the information of a device that reaches + // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases. + private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F; + + + private final Object mLock = new Object(); + + private final Context mContext; + private final Handler mHandler; + @GuardedBy("mLock") private final ExponentialBackOff mPsdsBackOff = new ExponentialBackOff(RETRY_INTERVAL, MAX_RETRY_INTERVAL); @@ -305,37 +315,16 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private boolean mBatchingEnabled; private boolean mShutdown; - - @GuardedBy("mLock") - private Set<Integer> mPendingDownloadPsdsTypes = new HashSet<>(); - - // true if GPS is navigating private boolean mNavigating; - - // requested frequency of fixes, in milliseconds - private int mFixInterval = 1000; - - // true if low power mode for the GNSS chipset is part of the latest request. - private boolean mLowPowerMode = false; - - // true if we started navigation in the HAL, only change value of this in setStarted private boolean mStarted; - - // true if batching is being used private boolean mBatchingStarted; - - // for logging of latest change, and warning of ongoing location after a stop private long mStartedChangedElapsedRealtime; + private int mFixInterval = 1000; - // threshold for delay in GNSS engine turning off before warning & error - private static final long LOCATION_OFF_DELAY_THRESHOLD_WARN_MILLIS = 2 * 1000; - private static final long LOCATION_OFF_DELAY_THRESHOLD_ERROR_MILLIS = 15 * 1000; - - // capabilities reported through the top level IGnssCallback.hal - private volatile int mTopHalCapabilities; + private ProviderRequest mProviderRequest; - // true if PSDS is supported - private boolean mSupportsPsds; + private int mPositionMode; + private GnssPositionMode mLastPositionMode; // for calculating time to first fix private long mFixRequestTime = 0; @@ -344,25 +333,23 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // time we received our last fix private long mLastFixTime; - private int mPositionMode; - private GnssPositionMode mLastPositionMode; + private final WorkSource mClientSource = new WorkSource(); - // Current request from underlying location clients. - private ProviderRequest mProviderRequest; - // True if gps should be disabled because of PowerManager controls - private boolean mDisableGpsForPowerManager = false; + // capabilities reported through the top level IGnssCallback.hal + private volatile int mTopHalCapabilities; - /** - * True if the device idle controller has determined that the device is stationary. This is only - * updated when the device enters idle mode. - */ - private volatile boolean mIsDeviceStationary = false; + // true if PSDS is supported + private boolean mSupportsPsds; + @GuardedBy("mLock") + private final PowerManager.WakeLock mDownloadPsdsWakeLock; + @GuardedBy("mLock") + private final Set<Integer> mPendingDownloadPsdsTypes = new HashSet<>(); /** * Properties loaded from PROPERTIES_FILE. * It must be accessed only inside {@link #mHandler}. */ - private GnssConfiguration mGnssConfiguration; + private final GnssConfiguration mGnssConfiguration; private String mSuplServerHost; private int mSuplServerPort = TCP_MIN_PORT; @@ -370,15 +357,12 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private int mC2KServerPort; private boolean mSuplEsEnabled = false; - private final Looper mLooper; private final LocationExtras mLocationExtras = new LocationExtras(); private final GnssStatusProvider mGnssStatusListenerHelper; private final GnssMeasurementsProvider mGnssMeasurementsProvider; private final GnssMeasurementCorrectionsProvider mGnssMeasurementCorrectionsProvider; private final GnssAntennaInfoProvider mGnssAntennaInfoProvider; private final GnssNavigationMessageProvider mGnssNavigationMessageProvider; - private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener(); - private final LocationChangeListener mFusedLocationListener = new FusedLocationListener(); private final NtpTimeHelper mNtpTimeHelper; private final GnssGeofenceProvider mGnssGeofenceProvider; private final GnssCapabilitiesProvider mGnssCapabilitiesProvider; @@ -387,53 +371,32 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // Available only on GNSS HAL 2.0 implementations and later. private GnssVisibilityControl mGnssVisibilityControl; - private final Context mContext; - private Handler mHandler; - private final GnssNetworkConnectivityHandler mNetworkConnectivityHandler; private final GpsNetInitiatedHandler mNIHandler; // Wakelocks - private static final String WAKELOCK_KEY = "GnssLocationProvider"; private final PowerManager.WakeLock mWakeLock; - private static final String DOWNLOAD_EXTRA_WAKELOCK_KEY = "GnssLocationProviderPsdsDownload"; - @GuardedBy("mLock") - private final PowerManager.WakeLock mDownloadPsdsWakeLock; - // Alarms - private static final String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP"; - private static final String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT"; - - private final PowerManager mPowerManager; private final AlarmManager mAlarmManager; - private final PendingIntent mWakeupIntent; - private final PendingIntent mTimeoutIntent; + private final AlarmManager.OnAlarmListener mWakeupListener = this::startNavigating; + private final AlarmManager.OnAlarmListener mTimeoutListener = this::hibernate; private final AppOpsManager mAppOps; private final IBatteryStats mBatteryStats; - // Current list of underlying location clients. - // only modified on handler thread - private WorkSource mClientSource = new WorkSource(); - private GeofenceHardwareImpl mGeofenceHardwareImpl; // Volatile for simple inter-thread sync on these values. private volatile int mHardwareYear = 0; private volatile String mHardwareModelName; - // Set lower than the current ITAR limit of 600m/s to allow this to trigger even if GPS HAL - // stops output right at 600m/s, depriving this of the information of a device that reaches - // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases. - private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F; - private volatile boolean mItarSpeedLimitExceeded = false; @GuardedBy("mLock") private final ArrayList<Runnable> mFlushListeners = new ArrayList<>(0); // GNSS Metrics - private GnssMetrics mGnssMetrics; + private final GnssMetrics mGnssMetrics; public GnssStatusProvider getGnssStatusProvider() { return mGnssStatusListenerHelper; @@ -459,51 +422,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements return mGnssNavigationMessageProvider; } - private final DeviceIdleInternal.StationaryListener mDeviceIdleStationaryListener = - isStationary -> { - mIsDeviceStationary = isStationary; - // Call updateLowPowerMode on handler thread so it's always called from the same - // thread. - mHandler.sendEmptyMessage(UPDATE_LOW_POWER_MODE); - }; - - private final BroadcastReceiver mBroadcastReceiver = 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 ALARM_WAKEUP: - startNavigating(); - break; - case ALARM_TIMEOUT: - hibernate(); - break; - case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED: - DeviceIdleInternal deviceIdleService = LocalServices.getService( - DeviceIdleInternal.class); - if (mPowerManager.isDeviceIdleMode()) { - deviceIdleService.registerStationaryListener(mDeviceIdleStationaryListener); - } else { - deviceIdleService.unregisterStationaryListener( - mDeviceIdleStationaryListener); - } - // Call updateLowPowerMode on handler thread so it's always called from the - // same thread. - mHandler.sendEmptyMessage(UPDATE_LOW_POWER_MODE); - break; - case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED: - case TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED: - subscriptionOrCarrierConfigChanged(); - break; - } - } - }; - /** * Implements {@link GnssSatelliteBlocklistCallback#onUpdateSatelliteBlocklist}. */ @@ -553,16 +471,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } } - private void updateLowPowerMode() { - // Disable GPS if we are in device idle mode and the device is stationary. - boolean disableGpsForPowerManager = mPowerManager.isDeviceIdleMode() && mIsDeviceStationary; - if (disableGpsForPowerManager != mDisableGpsForPowerManager) { - mDisableGpsForPowerManager = disableGpsForPowerManager; - updateEnabled(); - updateRequirements(); - } - } - private void reloadGpsProperties() { mGnssConfiguration.reloadGpsProperties(); setSuplHostPort(); @@ -581,23 +489,19 @@ public class GnssLocationProvider extends AbstractLocationProvider implements super(FgThread.getExecutor(), CallerIdentity.fromContext(context)); mContext = context; - mLooper = FgThread.getHandler().getLooper(); // Create a wake lock - mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); - mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); + PowerManager powerManager = Objects.requireNonNull( + mContext.getSystemService(PowerManager.class)); + mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mWakeLock.setReferenceCounted(true); // Create a separate wake lock for psds downloader as it may be released due to timeout. - mDownloadPsdsWakeLock = mPowerManager.newWakeLock( + mDownloadPsdsWakeLock = powerManager.newWakeLock( PowerManager.PARTIAL_WAKE_LOCK, DOWNLOAD_EXTRA_WAKELOCK_KEY); mDownloadPsdsWakeLock.setReferenceCounted(true); mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); - mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), - PendingIntent.FLAG_IMMUTABLE); - mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), - PendingIntent.FLAG_IMMUTABLE); // App ops service to keep track of who is accessing the GPS mAppOps = mContext.getSystemService(AppOpsManager.class); @@ -607,7 +511,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements BatteryStats.SERVICE_NAME)); // Construct internal handler - mHandler = new ProviderHandler(mLooper); + mHandler = new ProviderHandler(FgThread.getHandler().getLooper()); // Load GPS configuration and register listeners in the background: // some operations, such as opening files and registering broadcast receivers, can take a @@ -623,7 +527,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // Trigger PSDS data download when the network comes up after booting. mPendingDownloadPsdsTypes.add(GnssPsdsDownloader.LONG_TERM_PSDS_SERVER_INDEX); mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(context, - GnssLocationProvider.this::onNetworkAvailable, mLooper, mNIHandler); + GnssLocationProvider.this::onNetworkAvailable, mHandler.getLooper(), mNIHandler); mGnssStatusListenerHelper = new GnssStatusProvider(injector); mGnssMeasurementsProvider = new GnssMeasurementsProvider(injector); @@ -632,10 +536,10 @@ public class GnssLocationProvider extends AbstractLocationProvider implements mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(injector); mGnssMetrics = new GnssMetrics(mContext, mBatteryStats); - mNtpTimeHelper = new NtpTimeHelper(mContext, mLooper, this); + mNtpTimeHelper = new NtpTimeHelper(mContext, mHandler.getLooper(), this); mGnssSatelliteBlocklistHelper = new GnssSatelliteBlocklistHelper(mContext, - mLooper, this); + mHandler.getLooper(), this); mGnssGeofenceProvider = new GnssGeofenceProvider(); setProperties(PROPERTIES); @@ -664,10 +568,66 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } }, UserHandle.USER_ALL); - sendMessage(INITIALIZE_HANDLER, 0, null); + mHandler.post(this::handleInitialize); mHandler.post(mGnssSatelliteBlocklistHelper::updateSatelliteBlocklist); } + private void handleInitialize() { + // it *appears* that native_init() needs to be called at least once before invoking any + // other gnss methods, so we cycle once on initialization. + native_init(); + native_cleanup(); + + if (native_is_gnss_visibility_control_supported()) { + mGnssVisibilityControl = new GnssVisibilityControl(mContext, mHandler.getLooper(), + mNIHandler); + } + + // load default GPS configuration + // (this configuration might change in the future based on SIM changes) + reloadGpsProperties(); + + // listen for events + 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; + } + + switch (action) { + case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED: + case TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED: + subscriptionOrCarrierConfigChanged(); + break; + } + } + }, intentFilter, null, mHandler); + + mNetworkConnectivityHandler.registerNetworkCallbacks(); + + // permanently passively listen to all network locations + LocationManager locationManager = Objects.requireNonNull( + mContext.getSystemService(LocationManager.class)); + if (locationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) { + locationManager.requestLocationUpdates( + LocationManager.NETWORK_PROVIDER, + new LocationRequest.Builder(LocationRequest.PASSIVE_INTERVAL) + .setMinUpdateIntervalMillis(0) + .setHiddenFromAppOps(true) + .build(), + DIRECT_EXECUTOR, + this::injectLocation); + } + + updateEnabled(); + } + /** * Implements {@link InjectNtpTimeCallback#injectTime} */ @@ -712,19 +672,20 @@ public class GnssLocationProvider extends AbstractLocationProvider implements LocationManager locationManager = (LocationManager) mContext.getSystemService( Context.LOCATION_SERVICE); String provider; - LocationChangeListener locationListener; + LocationListener locationListener; LocationRequest.Builder locationRequest = new LocationRequest.Builder( - LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS); + LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS).setMaxUpdates(1); if (independentFromGnss) { - // For fast GNSS TTFF + // For fast GNSS TTFF - we use an empty listener because we will rely on the passive + // network listener to actually inject the location. this prevents double injection provider = LocationManager.NETWORK_PROVIDER; - locationListener = mNetworkLocationListener; + locationListener = location -> { }; locationRequest.setQuality(LocationRequest.QUALITY_LOW_POWER); } else { // For Device-Based Hybrid (E911) provider = LocationManager.FUSED_PROVIDER; - locationListener = mFusedLocationListener; + locationListener = this::injectBestLocation; locationRequest.setQuality(LocationRequest.QUALITY_HIGH_ACCURACY); } @@ -739,31 +700,26 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } } + locationRequest.setDurationMillis(durationMillis); + Log.i(TAG, String.format( "GNSS HAL Requesting location updates from %s provider for %d millis.", provider, durationMillis)); - try { - locationManager.requestLocationUpdates(provider, locationRequest.build(), - new HandlerExecutor(mHandler), locationListener); - locationListener.mNumLocationUpdateRequest++; - mHandler.postDelayed(() -> { - if (--locationListener.mNumLocationUpdateRequest == 0) { - Log.i(TAG, - String.format("Removing location updates from %s provider.", provider)); - locationManager.removeUpdates(locationListener); - } - }, durationMillis); - } catch (IllegalArgumentException e) { - Log.w(TAG, "Unable to request location.", e); - } + locationManager.requestLocationUpdates(provider, locationRequest.build(), + DIRECT_EXECUTOR, locationListener); } private void injectBestLocation(Location location) { if (DEBUG) { Log.d(TAG, "injectBestLocation: " + location); } + + if (location.isFromMockProvider()) { + return; + } + int gnssLocationFlags = LOCATION_HAS_LAT_LONG | (location.hasAltitude() ? LOCATION_HAS_ALTITUDE : 0) | (location.hasSpeed() ? LOCATION_HAS_SPEED : 0) @@ -864,10 +820,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } private void injectLocation(Location location) { - if (location.hasAccuracy()) { - if (DEBUG) { - Log.d(TAG, "injectLocation: " + location); - } + if (location.hasAccuracy() && !location.isFromMockProvider()) { native_inject_location(location.getLatitude(), location.getLongitude(), location.getAccuracy()); } @@ -954,6 +907,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements mGnssVisibilityControl.onGpsEnabledChanged(/* isEnabled= */ false); } // do this before releasing wakelock + native_cleanup_batching(); native_cleanup(); } @@ -962,10 +916,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements boolean enabled = mContext.getSystemService(LocationManager.class) .isLocationEnabledForUser(UserHandle.CURRENT); - // ... but disable if PowerManager overrides - enabled &= !mDisableGpsForPowerManager; - - // .. but enable anyway, if there's an active settings-ignored request + // .. but enable anyway, if there's an active settings-ignored request (e.g. ELS) enabled |= (mProviderRequest != null && mProviderRequest.isActive() && mProviderRequest.isLocationSettingsIgnored()); @@ -1016,10 +967,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements @Override public void onSetRequest(ProviderRequest request) { - sendMessage(SET_REQUEST, 0, request); - } - - private void handleSetRequest(ProviderRequest request) { mProviderRequest = request; updateEnabled(); updateRequirements(); @@ -1037,7 +984,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements updateClientUids(mProviderRequest.getWorkSource()); mFixInterval = (int) mProviderRequest.getIntervalMillis(); - mLowPowerMode = mProviderRequest.isLowPower(); // check for overflow if (mFixInterval != mProviderRequest.getIntervalMillis()) { Log.w(TAG, "interval overflow: " + mProviderRequest.getIntervalMillis()); @@ -1066,7 +1012,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) { // change period and/or lowPowerMode if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC, - mFixInterval, mLowPowerMode)) { + mFixInterval, mProviderRequest.isLowPower())) { Log.e(TAG, "set_position_mode failed in updateRequirements"); } } else if (!mStarted) { @@ -1074,18 +1020,18 @@ public class GnssLocationProvider extends AbstractLocationProvider implements startNavigating(); } else { // GNSS Engine is already ON, but no GPS_CAPABILITY_SCHEDULING - mAlarmManager.cancel(mTimeoutIntent); + mAlarmManager.cancel(mTimeoutListener); if (mFixInterval >= NO_FIX_TIMEOUT) { // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT // and our fix interval is not short mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent); + SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, TAG, + mTimeoutListener, mHandler); } } } } else { updateClientUids(new WorkSource()); - stopNavigating(); stopBatching(); } @@ -1123,6 +1069,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // (2) Inform AppOps service about the list of changes to UIDs. + // TODO: this doesn't seem correct, work chain attribution tag != package? List<WorkChain>[] diffs = WorkSource.diffChains(mClientSource, source); if (diffs != null) { List<WorkChain> newChains = diffs[0]; @@ -1146,6 +1093,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } // Update the flat UIDs and names list and inform app-ops of all changes. + // TODO: why is GnssLocationProvider the only component using these deprecated APIs? WorkSource[] changes = mClientSource.setReturningDiffs(source); if (changes != null) { WorkSource newWork = changes[0]; @@ -1171,23 +1119,17 @@ public class GnssLocationProvider extends AbstractLocationProvider implements @Override public void onExtraCommand(int uid, int pid, String command, Bundle extras) { - - final long identity = Binder.clearCallingIdentity(); - try { - if ("delete_aiding_data".equals(command)) { - deleteAidingData(extras); - } else if ("force_time_injection".equals(command)) { - requestUtcTime(); - } else if ("force_psds_injection".equals(command)) { - if (mSupportsPsds) { - downloadPsdsData(/* psdsType= */ - GnssPsdsDownloader.LONG_TERM_PSDS_SERVER_INDEX); - } - } else { - Log.w(TAG, "sendExtraCommand: unknown command " + command); + if ("delete_aiding_data".equals(command)) { + deleteAidingData(extras); + } else if ("force_time_injection".equals(command)) { + requestUtcTime(); + } else if ("force_psds_injection".equals(command)) { + if (mSupportsPsds) { + downloadPsdsData(/* psdsType= */ + GnssPsdsDownloader.LONG_TERM_PSDS_SERVER_INDEX); } - } finally { - Binder.restoreCallingIdentity(identity); + } else { + Log.w(TAG, "sendExtraCommand: unknown command " + command); } } @@ -1258,9 +1200,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000); - mLowPowerMode = mProviderRequest.isLowPower(); if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC, - interval, mLowPowerMode)) { + interval, mProviderRequest.isLowPower())) { setStarted(false); Log.e(TAG, "set_position_mode failed in startNavigating()"); return; @@ -1279,7 +1220,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // and our fix interval is not short if (mFixInterval >= NO_FIX_TIMEOUT) { mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent); + SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, TAG, mTimeoutListener, + mHandler); } } } @@ -1297,8 +1239,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // reset SV count to zero mLocationExtras.reset(); } - mAlarmManager.cancel(mTimeoutIntent); - mAlarmManager.cancel(mWakeupIntent); + mAlarmManager.cancel(mTimeoutListener); + mAlarmManager.cancel(mWakeupListener); } private void startBatching() { @@ -1331,7 +1273,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // stop GPS until our next fix interval arrives stopNavigating(); long now = SystemClock.elapsedRealtime(); - mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent); + mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, TAG, + mWakeupListener, mHandler); } private boolean hasCapability(int capability) { @@ -1409,7 +1352,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // slow. // As we just recievied a location, we'll cancel that timer. if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) { - mAlarmManager.cancel(mTimeoutIntent); + mAlarmManager.cancel(mTimeoutListener); } } @@ -1428,11 +1371,10 @@ public class GnssLocationProvider extends AbstractLocationProvider implements case GPS_STATUS_SESSION_BEGIN: mNavigating = true; break; - case GPS_STATUS_SESSION_END: - mNavigating = false; - break; case GPS_STATUS_ENGINE_ON: break; + case GPS_STATUS_SESSION_END: + // fall through case GPS_STATUS_ENGINE_OFF: mNavigating = false; break; @@ -1626,7 +1568,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements * @hide */ public GnssMetricsProvider getGnssMetricsProvider() { - return () -> mGnssMetrics.dumpGnssMetricsAsProtoString(); + return mGnssMetrics::dumpGnssMetricsAsProtoString; } /** @@ -1959,9 +1901,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements public void handleMessage(Message msg) { int message = msg.what; switch (message) { - case SET_REQUEST: - handleSetRequest((ProviderRequest) msg.obj); - break; case INJECT_NTP_TIME: mNtpTimeHelper.retrieveAndInjectNtpTime(); break; @@ -1971,18 +1910,12 @@ public class GnssLocationProvider extends AbstractLocationProvider implements case DOWNLOAD_PSDS_DATA: handleDownloadPsdsData(msg.arg1); break; - case INITIALIZE_HANDLER: - handleInitialize(); - break; case REPORT_LOCATION: handleReportLocation(msg.arg1 == 1, (Location) msg.obj); break; case REPORT_SV_STATUS: handleReportSvStatus((GnssStatus) msg.obj); break; - case UPDATE_LOW_POWER_MODE: - updateLowPowerMode(); - break; } if (msg.arg2 == 1) { // wakelock was taken for this message, release it @@ -1993,70 +1926,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } } } - - /** - * This method is bound to the constructor. It is in charge of loading properties and - * registering for events that will be posted to this handler. - */ - private void handleInitialize() { - // it *appears* that native_init() needs to be called at least once before invoking any - // other gnss methods, so we cycle once on initialization. - native_init(); - native_cleanup(); - - if (native_is_gnss_visibility_control_supported()) { - mGnssVisibilityControl = new GnssVisibilityControl(mContext, mLooper, mNIHandler); - } - - // load default GPS configuration - // (this configuration might change in the future based on SIM changes) - reloadGpsProperties(); - - // listen for events - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(ALARM_WAKEUP); - intentFilter.addAction(ALARM_TIMEOUT); - intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); - intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED); - intentFilter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED); - mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this); - - mNetworkConnectivityHandler.registerNetworkCallbacks(); - - // listen for PASSIVE_PROVIDER updates - LocationManager locManager = - (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); - locManager.requestLocationUpdates( - LocationManager.PASSIVE_PROVIDER, - new LocationRequest.Builder(0) - .setHiddenFromAppOps(true) - .build(), - new HandlerExecutor(this), - new NetworkLocationListener()); - - updateEnabled(); - } - } - - private abstract static class LocationChangeListener implements LocationListener { - private int mNumLocationUpdateRequest; - } - - private final class NetworkLocationListener extends LocationChangeListener { - @Override - public void onLocationChanged(Location location) { - // this callback happens on mHandler looper - if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) { - injectLocation(location); - } - } - } - - private final class FusedLocationListener extends LocationChangeListener { - @Override - public void onLocationChanged(Location location) { - injectBestLocation(location); - } } /** @@ -2064,16 +1933,12 @@ public class GnssLocationProvider extends AbstractLocationProvider implements */ private String messageIdAsString(int message) { switch (message) { - case SET_REQUEST: - return "SET_REQUEST"; case INJECT_NTP_TIME: return "INJECT_NTP_TIME"; case REQUEST_LOCATION: return "REQUEST_LOCATION"; case DOWNLOAD_PSDS_DATA: return "DOWNLOAD_PSDS_DATA"; - case INITIALIZE_HANDLER: - return "INITIALIZE_HANDLER"; case REPORT_LOCATION: return "REPORT_LOCATION"; case REPORT_SV_STATUS: @@ -2109,8 +1974,6 @@ public class GnssLocationProvider extends AbstractLocationProvider implements s.append("mBatchingStarted=").append(mBatchingStarted).append('\n'); s.append("mBatchSize=").append(getBatchSize()).append('\n'); s.append("mFixInterval=").append(mFixInterval).append('\n'); - s.append("mLowPowerMode=").append(mLowPowerMode).append('\n'); - s.append("mDisableGpsForPowerManager=").append(mDisableGpsForPowerManager).append('\n'); s.append("mTopHalCapabilities=0x").append(Integer.toHexString(mTopHalCapabilities)); s.append(" ( "); if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING "); diff --git a/services/core/java/com/android/server/location/util/LocationEventLog.java b/services/core/java/com/android/server/location/util/LocationEventLog.java index ff4503e215e7..134b1422eee6 100644 --- a/services/core/java/com/android/server/location/util/LocationEventLog.java +++ b/services/core/java/com/android/server/location/util/LocationEventLog.java @@ -22,6 +22,8 @@ import static android.os.PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF import static android.os.PowerManager.LOCATION_MODE_NO_CHANGE; import static android.os.PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF; +import static com.android.server.location.LocationManagerService.D; + import android.annotation.Nullable; import android.location.LocationRequest; import android.location.util.identity.CallerIdentity; @@ -29,14 +31,13 @@ import android.os.Build; import android.os.PowerManager.LocationPowerSaveMode; import com.android.internal.location.ProviderRequest; -import com.android.server.location.LocationManagerService; import com.android.server.utils.eventlog.LocalEventLog; /** In memory event log for location events. */ public class LocationEventLog extends LocalEventLog { private static int getLogSize() { - if (Build.IS_DEBUGGABLE || LocationManagerService.D) { + if (Build.IS_DEBUGGABLE || D) { return 500; } else { return 200; @@ -91,13 +92,17 @@ public class LocationEventLog extends LocalEventLog { /** Logs a new incoming location for a location provider. */ public synchronized void logProviderReceivedLocations(String provider, int numLocations) { - addLogEvent(EVENT_PROVIDER_RECEIVE_LOCATION, provider, numLocations); + if (Build.IS_DEBUGGABLE || D) { + addLogEvent(EVENT_PROVIDER_RECEIVE_LOCATION, provider, numLocations); + } } /** Logs a location deliver for a client of a location provider. */ public synchronized void logProviderDeliveredLocations(String provider, int numLocations, CallerIdentity identity) { - addLogEvent(EVENT_PROVIDER_DELIVER_LOCATION, provider, numLocations, identity); + if (Build.IS_DEBUGGABLE || D) { + addLogEvent(EVENT_PROVIDER_DELIVER_LOCATION, provider, numLocations, identity); + } } /** Logs that the location power save mode has changed. */ |