diff options
17 files changed, 216 insertions, 132 deletions
diff --git a/location/java/android/location/util/identity/CallerIdentity.java b/location/java/android/location/util/identity/CallerIdentity.java index 85a083ee84bc..ade0ea40e157 100644 --- a/location/java/android/location/util/identity/CallerIdentity.java +++ b/location/java/android/location/util/identity/CallerIdentity.java @@ -55,6 +55,20 @@ public final class CallerIdentity { } /** + * Returns a CallerIdentity with PID and listener ID information stripped. This is mostly + * useful for aggregating information for debug purposes, and should not be used in any API with + * security requirements. + */ + public static CallerIdentity forAggregation(CallerIdentity callerIdentity) { + if (callerIdentity.getPid() == 0 && callerIdentity.getListenerId() == null) { + return callerIdentity; + } + + return new CallerIdentity(callerIdentity.getUid(), 0, callerIdentity.getPackageName(), + callerIdentity.getAttributionTag(), null); + } + + /** * Creates a CallerIdentity for the current process and context. */ public static CallerIdentity fromContext(Context context) { @@ -180,17 +194,6 @@ public final class CallerIdentity { } } - /** - * Returns a CallerIdentity corrosponding to this CallerIdentity but with a null listener id. - */ - public CallerIdentity stripListenerId() { - if (mListenerId == null) { - return this; - } else { - return new CallerIdentity(mUid, mPid, mPackageName, mAttributionTag, null); - } - } - @Override public String toString() { int length = 10 + mPackageName.length(); diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java index 2920ddb2d76d..6d1606defa04 100644 --- a/services/core/java/com/android/server/location/LocationManagerService.java +++ b/services/core/java/com/android/server/location/LocationManagerService.java @@ -31,6 +31,7 @@ import static android.location.provider.LocationProviderBase.ACTION_NETWORK_PROV import static com.android.server.location.LocationPermissions.PERMISSION_COARSE; import static com.android.server.location.LocationPermissions.PERMISSION_FINE; +import static com.android.server.location.eventlog.LocationEventLog.EVENT_LOG; import static java.util.concurrent.TimeUnit.NANOSECONDS; @@ -158,10 +159,9 @@ public class LocationManagerService extends ILocationManager.Stub { public Lifecycle(Context context) { super(context); - LocationEventLog eventLog = new LocationEventLog(); mUserInfoHelper = new LifecycleUserInfoHelper(context); - mSystemInjector = new SystemInjector(context, mUserInfoHelper, eventLog); - mService = new LocationManagerService(context, mSystemInjector, eventLog); + mSystemInjector = new SystemInjector(context, mUserInfoHelper); + mService = new LocationManagerService(context, mSystemInjector); } @Override @@ -233,7 +233,6 @@ public class LocationManagerService extends ILocationManager.Stub { private final Context mContext; private final Injector mInjector; - private final LocationEventLog mEventLog; private final LocalService mLocalService; private final GeofenceManager mGeofenceManager; @@ -261,18 +260,20 @@ public class LocationManagerService extends ILocationManager.Stub { @GuardedBy("mLock") private @Nullable OnProviderLocationTagsChangeListener mOnProviderLocationTagsChangeListener; - LocationManagerService(Context context, Injector injector, LocationEventLog eventLog) { + LocationManagerService(Context context, Injector injector) { mContext = context.createAttributionContext(ATTRIBUTION_TAG); mInjector = injector; - mEventLog = eventLog; mLocalService = new LocalService(); LocalServices.addService(LocationManagerInternal.class, mLocalService); mGeofenceManager = new GeofenceManager(mContext, injector); + mInjector.getSettingsHelper().addOnLocationEnabledChangedListener( + this::onLocationModeChanged); + // set up passive provider first since it will be required for all other location providers, // which are loaded later once the system is ready. - mPassiveManager = new PassiveLocationProviderManager(mContext, injector, mEventLog); + mPassiveManager = new PassiveLocationProviderManager(mContext, injector); addLocationProviderManager(mPassiveManager, new PassiveLocationProvider(mContext)); // TODO: load the gps provider here as well, which will require refactoring @@ -313,7 +314,7 @@ public class LocationManagerService extends ILocationManager.Stub { } LocationProviderManager manager = new LocationProviderManager(mContext, mInjector, - mEventLog, providerName, mPassiveManager); + providerName, mPassiveManager); addLocationProviderManager(manager, null); return manager; } @@ -335,7 +336,7 @@ public class LocationManagerService extends ILocationManager.Stub { Settings.Global.LOCATION_ENABLE_STATIONARY_THROTTLE, 1) != 0; if (enableStationaryThrottling) { realProvider = new StationaryThrottlingLocationProvider(manager.getName(), - mInjector, realProvider, mEventLog); + mInjector, realProvider); } } manager.setRealProvider(realProvider); @@ -355,9 +356,6 @@ public class LocationManagerService extends ILocationManager.Stub { } void onSystemReady() { - mInjector.getSettingsHelper().addOnLocationEnabledChangedListener( - this::onLocationModeChanged); - if (Build.IS_DEBUGGABLE) { // on debug builds, watch for location noteOps while location is off. there are some // scenarios (emergency location) where this is expected, but generally this should @@ -385,7 +383,7 @@ public class LocationManagerService extends ILocationManager.Stub { com.android.internal.R.string.config_networkLocationProviderPackageName); if (networkProvider != null) { LocationProviderManager networkManager = new LocationProviderManager(mContext, - mInjector, mEventLog, NETWORK_PROVIDER, mPassiveManager); + mInjector, NETWORK_PROVIDER, mPassiveManager); addLocationProviderManager(networkManager, networkProvider); } else { Log.w(TAG, "no network location provider found"); @@ -404,7 +402,7 @@ public class LocationManagerService extends ILocationManager.Stub { com.android.internal.R.string.config_fusedLocationProviderPackageName); if (fusedProvider != null) { LocationProviderManager fusedManager = new LocationProviderManager(mContext, mInjector, - mEventLog, FUSED_PROVIDER, mPassiveManager); + FUSED_PROVIDER, mPassiveManager); addLocationProviderManager(fusedManager, fusedProvider); } else { Log.wtf(TAG, "no fused location provider found"); @@ -419,7 +417,7 @@ public class LocationManagerService extends ILocationManager.Stub { mGnssManagerService.onSystemReady(); LocationProviderManager gnssManager = new LocationProviderManager(mContext, mInjector, - mEventLog, GPS_PROVIDER, mPassiveManager); + GPS_PROVIDER, mPassiveManager); addLocationProviderManager(gnssManager, mGnssManagerService.getGnssLocationProvider()); } @@ -476,7 +474,7 @@ public class LocationManagerService extends ILocationManager.Stub { Log.d(TAG, "[u" + userId + "] location enabled = " + enabled); } - mEventLog.logLocationEnabled(userId, enabled); + EVENT_LOG.logLocationEnabled(userId, enabled); Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION) .putExtra(LocationManager.EXTRA_LOCATION_ENABLED, enabled) @@ -1268,7 +1266,7 @@ public class LocationManagerService extends ILocationManager.Stub { ipw.println("Event Log:"); ipw.increaseIndent(); - mEventLog.iterate(manager.getName(), ipw::println); + EVENT_LOG.iterate(manager.getName(), ipw::println); ipw.decreaseIndent(); return; } @@ -1313,7 +1311,7 @@ public class LocationManagerService extends ILocationManager.Stub { ipw.println("Historical Aggregate Location Provider Data:"); ipw.increaseIndent(); ArrayMap<String, ArrayMap<CallerIdentity, LocationEventLog.AggregateStats>> aggregateStats = - mEventLog.copyAggregateStats(); + EVENT_LOG.copyAggregateStats(); for (int i = 0; i < aggregateStats.size(); i++) { ipw.print(aggregateStats.keyAt(i)); ipw.println(":"); @@ -1344,7 +1342,7 @@ public class LocationManagerService extends ILocationManager.Stub { ipw.println("Event Log:"); ipw.increaseIndent(); - mEventLog.iterate(ipw::println); + EVENT_LOG.iterate(ipw::println); ipw.decreaseIndent(); } @@ -1456,7 +1454,7 @@ public class LocationManagerService extends ILocationManager.Stub { @GuardedBy("this") private boolean mSystemReady; - SystemInjector(Context context, UserInfoHelper userInfoHelper, LocationEventLog eventLog) { + SystemInjector(Context context, UserInfoHelper userInfoHelper) { mContext = context; mUserInfoHelper = userInfoHelper; @@ -1466,7 +1464,7 @@ public class LocationManagerService extends ILocationManager.Stub { mAppOpsHelper); mSettingsHelper = new SystemSettingsHelper(context); mAppForegroundHelper = new SystemAppForegroundHelper(context); - mLocationPowerSaveModeHelper = new SystemLocationPowerSaveModeHelper(context, eventLog); + mLocationPowerSaveModeHelper = new SystemLocationPowerSaveModeHelper(context); mScreenInteractiveHelper = new SystemScreenInteractiveHelper(context); mDeviceStationaryHelper = new SystemDeviceStationaryHelper(); mDeviceIdleHelper = new SystemDeviceIdleHelper(context); diff --git a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java index 29ce3783c4a1..045e06d001e6 100644 --- a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java +++ b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java @@ -44,6 +44,8 @@ import com.android.internal.util.Preconditions; /** In memory event log for location events. */ public class LocationEventLog extends LocalEventLog { + public static final LocationEventLog EVENT_LOG = new LocationEventLog(); + private static int getLogSize() { if (Build.IS_DEBUGGABLE || D) { return 500; @@ -52,16 +54,17 @@ public class LocationEventLog extends LocalEventLog { } } - private static final int EVENT_LOCATION_ENABLED = 1; - private static final int EVENT_PROVIDER_ENABLED = 2; - private static final int EVENT_PROVIDER_MOCKED = 3; - private static final int EVENT_PROVIDER_REGISTER_CLIENT = 4; - private static final int EVENT_PROVIDER_UNREGISTER_CLIENT = 5; - private static final int EVENT_PROVIDER_UPDATE_REQUEST = 6; - private static final int EVENT_PROVIDER_RECEIVE_LOCATION = 7; - private static final int EVENT_PROVIDER_DELIVER_LOCATION = 8; - private static final int EVENT_PROVIDER_STATIONARY_THROTTLED = 9; - private static final int EVENT_LOCATION_POWER_SAVE_MODE_CHANGE = 10; + private static final int EVENT_USER_SWITCHED = 1; + private static final int EVENT_LOCATION_ENABLED = 2; + private static final int EVENT_PROVIDER_ENABLED = 3; + private static final int EVENT_PROVIDER_MOCKED = 4; + private static final int EVENT_PROVIDER_REGISTER_CLIENT = 5; + private static final int EVENT_PROVIDER_UNREGISTER_CLIENT = 6; + private static final int EVENT_PROVIDER_UPDATE_REQUEST = 7; + private static final int EVENT_PROVIDER_RECEIVE_LOCATION = 8; + private static final int EVENT_PROVIDER_DELIVER_LOCATION = 9; + private static final int EVENT_PROVIDER_STATIONARY_THROTTLED = 10; + private static final int EVENT_LOCATION_POWER_SAVE_MODE_CHANGE = 11; @GuardedBy("mAggregateStats") private final ArrayMap<String, ArrayMap<CallerIdentity, AggregateStats>> mAggregateStats; @@ -90,19 +93,24 @@ public class LocationEventLog extends LocalEventLog { packageMap = new ArrayMap<>(2); mAggregateStats.put(provider, packageMap); } - CallerIdentity stripped = identity.stripListenerId(); - AggregateStats stats = packageMap.get(stripped); + CallerIdentity aggregate = CallerIdentity.forAggregation(identity); + AggregateStats stats = packageMap.get(aggregate); if (stats == null) { stats = new AggregateStats(); - packageMap.put(stripped, stats); + packageMap.put(aggregate, stats); } return stats; } } + /** Logs a user switched event. */ + public void logUserSwitched(int userIdFrom, int userIdTo) { + addLogEvent(EVENT_USER_SWITCHED, userIdFrom, userIdTo); + } + /** Logs a location enabled/disabled event. */ public void logLocationEnabled(int userId, boolean enabled) { - addLogEvent(EVENT_LOCATION_POWER_SAVE_MODE_CHANGE, userId, enabled); + addLogEvent(EVENT_LOCATION_ENABLED, userId, enabled); } /** Logs a location provider enabled/disabled event. */ @@ -183,8 +191,10 @@ public class LocationEventLog extends LocalEventLog { @Override protected LogEvent createLogEvent(long timeDelta, int event, Object... args) { switch (event) { + case EVENT_USER_SWITCHED: + return new UserSwitchedEvent(timeDelta, (Integer) args[0], (Integer) args[1]); case EVENT_LOCATION_ENABLED: - return new LocationEnabledEvent(timeDelta, (Integer) args[1], (Boolean) args[2]); + return new LocationEnabledEvent(timeDelta, (Integer) args[0], (Boolean) args[1]); case EVENT_PROVIDER_ENABLED: return new ProviderEnabledEvent(timeDelta, (String) args[0], (Integer) args[1], (Boolean) args[2]); @@ -397,6 +407,23 @@ public class LocationEventLog extends LocalEventLog { } } + private static final class UserSwitchedEvent extends LogEvent { + + private final int mUserIdFrom; + private final int mUserIdTo; + + UserSwitchedEvent(long timeDelta, int userIdFrom, int userIdTo) { + super(timeDelta); + mUserIdFrom = userIdFrom; + mUserIdTo = userIdTo; + } + + @Override + public String getLogString() { + return "current user switched from u" + mUserIdFrom + " to u" + mUserIdTo; + } + } + private static final class LocationEnabledEvent extends LogEvent { private final int mUserId; @@ -410,7 +437,7 @@ public class LocationEventLog extends LocalEventLog { @Override public String getLogString() { - return "[u" + mUserId + "] location setting " + (mEnabled ? "enabled" : "disabled"); + return "location [u" + mUserId + "] " + (mEnabled ? "enabled" : "disabled"); } } diff --git a/services/core/java/com/android/server/location/injector/LocationPowerSaveModeHelper.java b/services/core/java/com/android/server/location/injector/LocationPowerSaveModeHelper.java index cc00d5684991..53407d928012 100644 --- a/services/core/java/com/android/server/location/injector/LocationPowerSaveModeHelper.java +++ b/services/core/java/com/android/server/location/injector/LocationPowerSaveModeHelper.java @@ -20,12 +20,11 @@ import static android.os.PowerManager.locationPowerSaveModeToString; import static com.android.server.location.LocationManagerService.D; import static com.android.server.location.LocationManagerService.TAG; +import static com.android.server.location.eventlog.LocationEventLog.EVENT_LOG; import android.os.PowerManager.LocationPowerSaveMode; import android.util.Log; -import com.android.server.location.eventlog.LocationEventLog; - import java.util.concurrent.CopyOnWriteArrayList; /** @@ -43,11 +42,9 @@ public abstract class LocationPowerSaveModeHelper { void onLocationPowerSaveModeChanged(@LocationPowerSaveMode int locationPowerSaveMode); } - private final LocationEventLog mLocationEventLog; private final CopyOnWriteArrayList<LocationPowerSaveModeChangedListener> mListeners; - public LocationPowerSaveModeHelper(LocationEventLog locationEventLog) { - mLocationEventLog = locationEventLog; + public LocationPowerSaveModeHelper() { mListeners = new CopyOnWriteArrayList<>(); } @@ -72,7 +69,7 @@ public abstract class LocationPowerSaveModeHelper { Log.d(TAG, "location power save mode is now " + locationPowerSaveModeToString( locationPowerSaveMode)); } - mLocationEventLog.logLocationPowerSaveMode(locationPowerSaveMode); + EVENT_LOG.logLocationPowerSaveMode(locationPowerSaveMode); for (LocationPowerSaveModeChangedListener listener : mListeners) { listener.onLocationPowerSaveModeChanged(locationPowerSaveMode); diff --git a/services/core/java/com/android/server/location/injector/SystemLocationPowerSaveModeHelper.java b/services/core/java/com/android/server/location/injector/SystemLocationPowerSaveModeHelper.java index c47a64d6d9a7..a675f5467b3b 100644 --- a/services/core/java/com/android/server/location/injector/SystemLocationPowerSaveModeHelper.java +++ b/services/core/java/com/android/server/location/injector/SystemLocationPowerSaveModeHelper.java @@ -25,7 +25,6 @@ import android.os.PowerSaveState; import com.android.internal.util.Preconditions; import com.android.server.FgThread; import com.android.server.LocalServices; -import com.android.server.location.eventlog.LocationEventLog; import java.util.Objects; import java.util.function.Consumer; @@ -42,8 +41,7 @@ public class SystemLocationPowerSaveModeHelper extends LocationPowerSaveModeHelp @LocationPowerSaveMode private volatile int mLocationPowerSaveMode; - public SystemLocationPowerSaveModeHelper(Context context, LocationEventLog locationEventLog) { - super(locationEventLog); + public SystemLocationPowerSaveModeHelper(Context context) { mContext = context; } diff --git a/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java b/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java index 3f7345e7c0c3..632ed6ef192a 100644 --- a/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java +++ b/services/core/java/com/android/server/location/injector/SystemSettingsHelper.java @@ -35,6 +35,7 @@ import android.database.ContentObserver; import android.net.Uri; import android.os.Binder; import android.os.Handler; +import android.os.RemoteException; import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; @@ -348,31 +349,73 @@ public class SystemSettingsHelper extends SettingsHelper { */ @Override public void dump(FileDescriptor fd, IndentingPrintWriter ipw, String[] args) { - int userId = ActivityManager.getCurrentUser(); - - ipw.print("Location Enabled: "); - ipw.println(isLocationEnabled(userId)); - - List<String> locationPackageBlacklist = mLocationPackageBlacklist.getValueForUser(userId); - if (!locationPackageBlacklist.isEmpty()) { - ipw.println("Location Deny Packages:"); - ipw.increaseIndent(); - for (String packageName : locationPackageBlacklist) { - ipw.println(packageName); + int[] userIds; + try { + userIds = ActivityManager.getService().getRunningUserIds(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + + ipw.print("Location Setting: "); + ipw.increaseIndent(); + if (userIds.length > 1) { + ipw.println(); + for (int userId : userIds) { + ipw.print("[u"); + ipw.print(userId); + ipw.print("] "); + ipw.println(isLocationEnabled(userId)); } - ipw.decreaseIndent(); + } else { + ipw.println(isLocationEnabled(userIds[0])); + } + ipw.decreaseIndent(); + + ipw.println("Location Allow/Deny Packages:"); + ipw.increaseIndent(); + if (userIds.length > 1) { + for (int userId : userIds) { + List<String> locationPackageBlacklist = mLocationPackageBlacklist.getValueForUser( + userId); + if (locationPackageBlacklist.isEmpty()) { + continue; + } - List<String> locationPackageWhitelist = mLocationPackageWhitelist.getValueForUser( - userId); - if (!locationPackageWhitelist.isEmpty()) { - ipw.println("Location Allow Packages:"); + ipw.print("user "); + ipw.print(userId); + ipw.println(":"); ipw.increaseIndent(); + + for (String packageName : locationPackageBlacklist) { + ipw.print("[deny] "); + ipw.println(packageName); + } + + List<String> locationPackageWhitelist = mLocationPackageWhitelist.getValueForUser( + userId); for (String packageName : locationPackageWhitelist) { + ipw.print("[allow] "); ipw.println(packageName); } + ipw.decreaseIndent(); } + } else { + List<String> locationPackageBlacklist = mLocationPackageBlacklist.getValueForUser( + userIds[0]); + for (String packageName : locationPackageBlacklist) { + ipw.print("[deny] "); + ipw.println(packageName); + } + + List<String> locationPackageWhitelist = mLocationPackageWhitelist.getValueForUser( + userIds[0]); + for (String packageName : locationPackageWhitelist) { + ipw.print("[allow] "); + ipw.println(packageName); + } } + ipw.decreaseIndent(); Set<String> backgroundThrottlePackageWhitelist = mBackgroundThrottlePackageWhitelist.getValue(); diff --git a/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java b/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java index d4a8fbd0ceb0..ed1e65457b24 100644 --- a/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java +++ b/services/core/java/com/android/server/location/injector/SystemUserInfoHelper.java @@ -155,6 +155,11 @@ public class SystemUserInfoHelper extends UserInfoHelper { */ @Override public void dump(FileDescriptor fd, IndentingPrintWriter pw, String[] args) { + int[] runningUserIds = getRunningUserIds(); + if (runningUserIds.length > 1) { + pw.println("running users: u" + Arrays.toString(runningUserIds)); + } + ActivityManagerInternal activityManagerInternal = getActivityManagerInternal(); if (activityManagerInternal == null) { return; diff --git a/services/core/java/com/android/server/location/injector/UserInfoHelper.java b/services/core/java/com/android/server/location/injector/UserInfoHelper.java index 0fcc1ecc4c1a..c835370a6f86 100644 --- a/services/core/java/com/android/server/location/injector/UserInfoHelper.java +++ b/services/core/java/com/android/server/location/injector/UserInfoHelper.java @@ -18,6 +18,7 @@ package com.android.server.location.injector; import static com.android.server.location.LocationManagerService.D; import static com.android.server.location.LocationManagerService.TAG; +import static com.android.server.location.eventlog.LocationEventLog.EVENT_LOG; import static com.android.server.location.injector.UserInfoHelper.UserListener.CURRENT_USER_CHANGED; import static com.android.server.location.injector.UserInfoHelper.UserListener.USER_STARTED; import static com.android.server.location.injector.UserInfoHelper.UserListener.USER_STOPPED; @@ -105,6 +106,7 @@ public abstract class UserInfoHelper { Log.d(TAG, "current user changed from u" + Arrays.toString(fromUserIds) + " to u" + Arrays.toString(toUserIds)); } + EVENT_LOG.logUserSwitched(fromUserId, toUserId); for (UserListener listener : mListeners) { for (int userId : fromUserIds) { diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java index dc8b1d001c74..102263b5f3c2 100644 --- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java +++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java @@ -37,6 +37,7 @@ import static com.android.server.location.LocationManagerService.TAG; import static com.android.server.location.LocationPermissions.PERMISSION_COARSE; import static com.android.server.location.LocationPermissions.PERMISSION_FINE; import static com.android.server.location.LocationPermissions.PERMISSION_NONE; +import static com.android.server.location.eventlog.LocationEventLog.EVENT_LOG; import static java.lang.Math.max; import static java.lang.Math.min; @@ -94,7 +95,6 @@ import com.android.server.FgThread; import com.android.server.LocalServices; import com.android.server.location.LocationPermissions; import com.android.server.location.LocationPermissions.PermissionLevel; -import com.android.server.location.eventlog.LocationEventLog; import com.android.server.location.fudger.LocationFudger; import com.android.server.location.injector.AlarmHelper; import com.android.server.location.injector.AppForegroundHelper; @@ -333,7 +333,7 @@ public class LocationProviderManager extends + getRequest()); } - mEventLog.logProviderClientRegistered(mName, getIdentity(), super.getRequest()); + EVENT_LOG.logProviderClientRegistered(mName, getIdentity(), super.getRequest()); // initialization order is important as there are ordering dependencies mPermitted = mLocationPermissionsHelper.hasLocationPermissions(mPermissionLevel, @@ -345,7 +345,7 @@ public class LocationProviderManager extends onProviderListenerRegister(); if (mForeground) { - mEventLog.logProviderClientForeground(mName, getIdentity()); + EVENT_LOG.logProviderClientForeground(mName, getIdentity()); } } @@ -358,7 +358,7 @@ public class LocationProviderManager extends onProviderListenerUnregister(); - mEventLog.logProviderClientUnregistered(mName, getIdentity()); + EVENT_LOG.logProviderClientUnregistered(mName, getIdentity()); if (D) { Log.d(TAG, mName + " provider removed registration from " + getIdentity()); @@ -383,7 +383,7 @@ public class LocationProviderManager extends Preconditions.checkState(Thread.holdsLock(mLock)); } - mEventLog.logProviderClientActive(mName, getIdentity()); + EVENT_LOG.logProviderClientActive(mName, getIdentity()); if (!getRequest().isHiddenFromAppOps()) { mLocationAttributionHelper.reportLocationStart(getIdentity(), getName(), getKey()); @@ -406,7 +406,7 @@ public class LocationProviderManager extends onProviderListenerInactive(); - mEventLog.logProviderClientInactive(mName, getIdentity()); + EVENT_LOG.logProviderClientInactive(mName, getIdentity()); } /** @@ -543,9 +543,9 @@ public class LocationProviderManager extends mForeground = foreground; if (mForeground) { - mEventLog.logProviderClientForeground(mName, getIdentity()); + EVENT_LOG.logProviderClientForeground(mName, getIdentity()); } else { - mEventLog.logProviderClientBackground(mName, getIdentity()); + EVENT_LOG.logProviderClientBackground(mName, getIdentity()); } // note that onProviderLocationRequestChanged() is always called @@ -654,7 +654,7 @@ public class LocationProviderManager extends protected abstract class LocationRegistration extends Registration implements OnAlarmListener, ProviderEnabledListener { - private final PowerManager.WakeLock mWakeLock; + final PowerManager.WakeLock mWakeLock; private volatile ProviderTransport mProviderTransport; private int mNumLocationsDelivered = 0; @@ -879,7 +879,7 @@ public class LocationProviderManager extends listener.deliverOnLocationChanged(deliverLocationResult, mUseWakeLock ? mWakeLock::release : null); - mEventLog.logProviderDeliveredLocations(mName, locationResult.size(), + EVENT_LOG.logProviderDeliveredLocations(mName, locationResult.size(), getIdentity()); } @@ -1178,7 +1178,7 @@ public class LocationProviderManager extends // we currently don't hold a wakelock for getCurrentLocation deliveries listener.deliverOnLocationChanged(deliverLocationResult, null); - mEventLog.logProviderDeliveredLocations(mName, + EVENT_LOG.logProviderDeliveredLocations(mName, locationResult != null ? locationResult.size() : 0, getIdentity()); } @@ -1247,7 +1247,6 @@ public class LocationProviderManager extends private final CopyOnWriteArrayList<IProviderRequestListener> mProviderRequestListeners; - protected final LocationEventLog mEventLog; protected final LocationManagerInternal mLocationManagerInternal; protected final SettingsHelper mSettingsHelper; protected final UserInfoHelper mUserHelper; @@ -1300,7 +1299,7 @@ public class LocationProviderManager extends @GuardedBy("mLock") private @Nullable OnProviderLocationTagsChangeListener mOnLocationTagsChangeListener; - public LocationProviderManager(Context context, Injector injector, LocationEventLog eventLog, + public LocationProviderManager(Context context, Injector injector, String name, @Nullable PassiveLocationProviderManager passiveManager) { mContext = context; mName = Objects.requireNonNull(name); @@ -1312,7 +1311,6 @@ public class LocationProviderManager extends mEnabledListeners = new ArrayList<>(); mProviderRequestListeners = new CopyOnWriteArrayList<>(); - mEventLog = eventLog; mLocationManagerInternal = Objects.requireNonNull( LocalServices.getService(LocationManagerInternal.class)); mSettingsHelper = injector.getSettingsHelper(); @@ -1477,7 +1475,7 @@ public class LocationProviderManager extends synchronized (mLock) { Preconditions.checkState(mState != STATE_STOPPED); - mEventLog.logProviderMocked(mName, provider != null); + EVENT_LOG.logProviderMocked(mName, provider != null); final long identity = Binder.clearCallingIdentity(); try { @@ -1966,8 +1964,8 @@ public class LocationProviderManager extends } @GuardedBy("mLock") - private void setProviderRequest(ProviderRequest request) { - mEventLog.logProviderUpdateRequest(mName, request); + void setProviderRequest(ProviderRequest request) { + EVENT_LOG.logProviderUpdateRequest(mName, request); mProvider.getController().setRequest(request); FgThread.getHandler().post(() -> { @@ -2324,7 +2322,7 @@ public class LocationProviderManager extends } // don't log location received for passive provider because it's spammy - mEventLog.logProviderReceivedLocations(mName, filtered.size()); + EVENT_LOG.logProviderReceivedLocations(mName, filtered.size()); } else { // passive provider should get already filtered results as input filtered = locationResult; @@ -2424,7 +2422,7 @@ public class LocationProviderManager extends if (D) { Log.d(TAG, "[u" + userId + "] " + mName + " provider enabled = " + enabled); } - mEventLog.logProviderEnabled(mName, userId, enabled); + EVENT_LOG.logProviderEnabled(mName, userId, enabled); } // clear last locations if we become disabled @@ -2464,7 +2462,7 @@ public class LocationProviderManager extends updateRegistrations(registration -> registration.getIdentity().getUserId() == userId); } - private @Nullable Location getPermittedLocation(@Nullable Location fineLocation, + @Nullable Location getPermittedLocation(@Nullable Location fineLocation, @PermissionLevel int permissionLevel) { switch (permissionLevel) { case PERMISSION_FINE: @@ -2477,7 +2475,7 @@ public class LocationProviderManager extends } } - private @Nullable LocationResult getPermittedLocationResult( + @Nullable LocationResult getPermittedLocationResult( @Nullable LocationResult fineLocationResult, @PermissionLevel int permissionLevel) { switch (permissionLevel) { case PERMISSION_FINE: @@ -2538,6 +2536,8 @@ public class LocationProviderManager extends private @Nullable Location mFineBypassLocation; private @Nullable Location mCoarseBypassLocation; + LastLocation() {} + public void clearMock() { if (mFineLocation != null && mFineLocation.isFromMockProvider()) { mFineLocation = null; diff --git a/services/core/java/com/android/server/location/provider/PassiveLocationProviderManager.java b/services/core/java/com/android/server/location/provider/PassiveLocationProviderManager.java index 027f4e94f55b..b35af4f6475c 100644 --- a/services/core/java/com/android/server/location/provider/PassiveLocationProviderManager.java +++ b/services/core/java/com/android/server/location/provider/PassiveLocationProviderManager.java @@ -24,7 +24,6 @@ import android.location.provider.ProviderRequest; import android.os.Binder; import com.android.internal.util.Preconditions; -import com.android.server.location.eventlog.LocationEventLog; import com.android.server.location.injector.Injector; import java.util.Collection; @@ -34,9 +33,8 @@ import java.util.Collection; */ public class PassiveLocationProviderManager extends LocationProviderManager { - public PassiveLocationProviderManager(Context context, Injector injector, - LocationEventLog eventLog) { - super(context, injector, eventLog, LocationManager.PASSIVE_PROVIDER, null); + public PassiveLocationProviderManager(Context context, Injector injector) { + super(context, injector, LocationManager.PASSIVE_PROVIDER, null); } @Override diff --git a/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java b/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java index 6f4aa642500f..ab7e526a8e68 100644 --- a/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java @@ -21,6 +21,7 @@ import static android.location.provider.ProviderRequest.INTERVAL_DISABLED; import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; import static com.android.server.location.LocationManagerService.D; import static com.android.server.location.LocationManagerService.TAG; +import static com.android.server.location.eventlog.LocationEventLog.EVENT_LOG; import android.annotation.Nullable; import android.location.Location; @@ -33,7 +34,6 @@ import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Preconditions; import com.android.server.DeviceIdleInternal; import com.android.server.FgThread; -import com.android.server.location.eventlog.LocationEventLog; import com.android.server.location.injector.DeviceIdleHelper; import com.android.server.location.injector.DeviceStationaryHelper; import com.android.server.location.injector.Injector; @@ -54,12 +54,11 @@ public final class StationaryThrottlingLocationProvider extends DelegateLocation private static final long MAX_STATIONARY_LOCATION_AGE_MS = 30000; - private final Object mLock = new Object(); + final Object mLock = new Object(); private final String mName; private final DeviceIdleHelper mDeviceIdleHelper; private final DeviceStationaryHelper mDeviceStationaryHelper; - private final LocationEventLog mEventLog; @GuardedBy("mLock") private boolean mDeviceIdle = false; @@ -72,21 +71,19 @@ public final class StationaryThrottlingLocationProvider extends DelegateLocation @GuardedBy("mLock") private ProviderRequest mOutgoingRequest = ProviderRequest.EMPTY_REQUEST; @GuardedBy("mLock") - private long mThrottlingIntervalMs = INTERVAL_DISABLED; + long mThrottlingIntervalMs = INTERVAL_DISABLED; @GuardedBy("mLock") - private @Nullable DeliverLastLocationRunnable mDeliverLastLocationCallback = null; - + @Nullable DeliverLastLocationRunnable mDeliverLastLocationCallback = null; @GuardedBy("mLock") - private @Nullable Location mLastLocation; + @Nullable Location mLastLocation; public StationaryThrottlingLocationProvider(String name, Injector injector, - AbstractLocationProvider delegate, LocationEventLog eventLog) { + AbstractLocationProvider delegate) { super(DIRECT_EXECUTOR, delegate); mName = name; mDeviceIdleHelper = injector.getDeviceIdleHelper(); mDeviceStationaryHelper = injector.getDeviceStationaryHelper(); - mEventLog = eventLog; // must be last statement in the constructor because reference is escaping initializeDelegate(); @@ -209,7 +206,7 @@ public final class StationaryThrottlingLocationProvider extends DelegateLocation if (D) { Log.d(TAG, mName + " provider stationary throttled"); } - mEventLog.logProviderStationaryThrottled(mName, true); + EVENT_LOG.logProviderStationaryThrottled(mName, true); } if (mDeliverLastLocationCallback != null) { @@ -227,7 +224,7 @@ public final class StationaryThrottlingLocationProvider extends DelegateLocation } } else { if (oldThrottlingIntervalMs != INTERVAL_DISABLED) { - mEventLog.logProviderStationaryThrottled(mName, false); + EVENT_LOG.logProviderStationaryThrottled(mName, false); if (D) { Log.d(TAG, mName + " provider stationary unthrottled"); } @@ -257,6 +254,9 @@ public final class StationaryThrottlingLocationProvider extends DelegateLocation } private class DeliverLastLocationRunnable implements Runnable { + + DeliverLastLocationRunnable() {} + @Override public void run() { Location location; diff --git a/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java b/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java index c86e49bc7948..317e61b44e46 100644 --- a/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java @@ -36,6 +36,7 @@ import android.util.ArraySet; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ArrayUtils; +import com.android.server.FgThread; import com.android.server.location.provider.AbstractLocationProvider; import com.android.server.servicewatcher.ServiceWatcher; import com.android.server.servicewatcher.ServiceWatcher.BoundService; @@ -55,6 +56,8 @@ public class ProxyLocationProvider extends AbstractLocationProvider { private static final String KEY_EXTRA_ATTRIBUTION_TAGS = "android:location_allow_listed_tags"; private static final String EXTRA_ATTRIBUTION_TAGS_SEPARATOR = ";"; + private static final long RESET_DELAY_MS = 1000; + /** * Creates and registers this proxy. If no suitable service is available for the proxy, returns * null. @@ -80,6 +83,9 @@ public class ProxyLocationProvider extends AbstractLocationProvider { final ArrayList<Runnable> mFlushListeners = new ArrayList<>(0); @GuardedBy("mLock") + @Nullable Runnable mResetter; + + @GuardedBy("mLock") Proxy mProxy; @GuardedBy("mLock") @Nullable ComponentName mService; @@ -111,6 +117,11 @@ public class ProxyLocationProvider extends AbstractLocationProvider { mProxy = new Proxy(); mService = boundService.component; + if (mResetter != null) { + FgThread.getHandler().removeCallbacks(mResetter); + mResetter = null; + } + // update extra attribution tag info from manifest if (boundService.metadata != null) { String tagsList = boundService.metadata.getString(KEY_EXTRA_ATTRIBUTION_TAGS); @@ -134,7 +145,22 @@ public class ProxyLocationProvider extends AbstractLocationProvider { synchronized (mLock) { mProxy = null; mService = null; - setState(prevState -> State.EMPTY_STATE); + + // we need to clear the state - but most disconnections are very temporary. we give a + // grace period where we don't clear the state immediately so that transient + // interruptions are not visible to clients + mResetter = new Runnable() { + @Override + public void run() { + synchronized (mLock) { + if (mResetter == this) { + setState(prevState -> State.EMPTY_STATE); + } + } + } + }; + FgThread.getHandler().postDelayed(mResetter, RESET_DELAY_MS); + flushListeners = mFlushListeners.toArray(new Runnable[0]); mFlushListeners.clear(); } @@ -245,7 +271,8 @@ public class ProxyLocationProvider extends AbstractLocationProvider { identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag); } - setState(prevState -> prevState + setState(prevState -> State.EMPTY_STATE + .withExtraAttributionTags(prevState.extraAttributionTags) .withAllowed(allowed) .withProperties(properties) .withIdentity(identity)); diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeLocationPowerSaveModeHelper.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeLocationPowerSaveModeHelper.java index 059744388197..ef4864620d22 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeLocationPowerSaveModeHelper.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/FakeLocationPowerSaveModeHelper.java @@ -19,8 +19,6 @@ package com.android.server.location.injector; import android.os.IPowerManager; import android.os.PowerManager.LocationPowerSaveMode; -import com.android.server.location.eventlog.LocationEventLog; - /** * Version of LocationPowerSaveModeHelper for testing. Power save mode is initialized as "no * change". @@ -30,8 +28,7 @@ public class FakeLocationPowerSaveModeHelper extends LocationPowerSaveModeHelper @LocationPowerSaveMode private int mLocationPowerSaveMode; - public FakeLocationPowerSaveModeHelper(LocationEventLog locationEventLog) { - super(locationEventLog); + public FakeLocationPowerSaveModeHelper() { mLocationPowerSaveMode = IPowerManager.LOCATION_MODE_NO_CHANGE; } diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemLocationPowerSaveModeHelperTest.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemLocationPowerSaveModeHelperTest.java index 6156ba9359cd..28da027669b8 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemLocationPowerSaveModeHelperTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/SystemLocationPowerSaveModeHelperTest.java @@ -43,7 +43,6 @@ import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.server.LocalServices; -import com.android.server.location.eventlog.LocationEventLog; import com.android.server.location.injector.LocationPowerSaveModeHelper.LocationPowerSaveModeChangedListener; import org.junit.After; @@ -85,7 +84,7 @@ public class SystemLocationPowerSaveModeHelperTest { Context context = mock(Context.class); doReturn(powerManager).when(context).getSystemService(PowerManager.class); - mHelper = new SystemLocationPowerSaveModeHelper(context, new LocationEventLog()); + mHelper = new SystemLocationPowerSaveModeHelper(context); mHelper.onSystemReady(); } diff --git a/services/tests/mockingservicestests/src/com/android/server/location/injector/TestInjector.java b/services/tests/mockingservicestests/src/com/android/server/location/injector/TestInjector.java index 1f102ac32a8e..ae70dadba041 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/injector/TestInjector.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/injector/TestInjector.java @@ -16,8 +16,6 @@ package com.android.server.location.injector; -import com.android.server.location.eventlog.LocationEventLog; - public class TestInjector implements Injector { private final FakeUserInfoHelper mUserInfoHelper; @@ -35,17 +33,13 @@ public class TestInjector implements Injector { private final LocationUsageLogger mLocationUsageLogger; public TestInjector() { - this(new LocationEventLog()); - } - - public TestInjector(LocationEventLog eventLog) { mUserInfoHelper = new FakeUserInfoHelper(); mAlarmHelper = new FakeAlarmHelper(); mAppOpsHelper = new FakeAppOpsHelper(); mLocationPermissionsHelper = new FakeLocationPermissionsHelper(mAppOpsHelper); mSettingsHelper = new FakeSettingsHelper(); mAppForegroundHelper = new FakeAppForegroundHelper(); - mLocationPowerSaveModeHelper = new FakeLocationPowerSaveModeHelper(eventLog); + mLocationPowerSaveModeHelper = new FakeLocationPowerSaveModeHelper(); mScreenInteractiveHelper = new FakeScreenInteractiveHelper(); mDeviceStationaryHelper = new FakeDeviceStationaryHelper(); mDeviceIdleHelper = new FakeDeviceIdleHelper(); diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java index 1b58e924dd6a..24b85f056731 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java @@ -83,7 +83,6 @@ import androidx.test.runner.AndroidJUnit4; import com.android.server.FgThread; import com.android.server.LocalServices; -import com.android.server.location.eventlog.LocationEventLog; import com.android.server.location.injector.FakeUserInfoHelper; import com.android.server.location.injector.TestInjector; @@ -161,19 +160,17 @@ public class LocationProviderManagerTest { doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class); doReturn(mWakeLock).when(mPowerManager).newWakeLock(anyInt(), anyString()); - LocationEventLog eventLog = new LocationEventLog(); - - mInjector = new TestInjector(eventLog); + mInjector = new TestInjector(); mInjector.getUserInfoHelper().startUser(OTHER_USER); - mPassive = new PassiveLocationProviderManager(mContext, mInjector, eventLog); + mPassive = new PassiveLocationProviderManager(mContext, mInjector); mPassive.startManager(); mPassive.setRealProvider(new PassiveLocationProvider(mContext)); mProvider = new TestProvider(PROPERTIES, PROVIDER_IDENTITY); mProvider.setProviderAllowed(true); - mManager = new LocationProviderManager(mContext, mInjector, eventLog, NAME, mPassive); + mManager = new LocationProviderManager(mContext, mInjector, NAME, mPassive); mManager.startManager(); mManager.setRealProvider(mProvider); } diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java index c3cca64154d6..04e0151e619a 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java @@ -36,7 +36,6 @@ import android.util.Log; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.server.location.eventlog.LocationEventLog; import com.android.server.location.injector.TestInjector; import com.android.server.location.test.FakeProvider; @@ -77,7 +76,7 @@ public class StationaryThrottlingLocationProviderTest { mDelegateProvider = new FakeProvider(mDelegate); mProvider = new StationaryThrottlingLocationProvider("test_provider", mInjector, - mDelegateProvider, new LocationEventLog()); + mDelegateProvider); mProvider.getController().setListener(mListener); mProvider.getController().start(); } |