diff options
6 files changed, 76 insertions, 47 deletions
diff --git a/location/java/android/location/util/identity/CallerIdentity.java b/location/java/android/location/util/identity/CallerIdentity.java index 0bb7dbb71ae8..85a083ee84bc 100644 --- a/location/java/android/location/util/identity/CallerIdentity.java +++ b/location/java/android/location/util/identity/CallerIdentity.java @@ -42,7 +42,16 @@ public final class CallerIdentity { @VisibleForTesting public static CallerIdentity forTest(int uid, int pid, String packageName, @Nullable String attributionTag) { - return new CallerIdentity(uid, pid, packageName, attributionTag, null); + return forTest(uid, pid, packageName, attributionTag, null); + } + + /** + * Construct a CallerIdentity for test purposes. + */ + @VisibleForTesting + public static CallerIdentity forTest(int uid, int pid, String packageName, + @Nullable String attributionTag, @Nullable String listenerId) { + return new CallerIdentity(uid, pid, packageName, attributionTag, listenerId); } /** @@ -145,7 +154,10 @@ public final class CallerIdentity { return mAttributionTag; } - /** The calling listener id. */ + /** + * The calling listener id. A null listener id will match any other listener id for the purposes + * of {@link #equals(Object)}. + */ public String getListenerId() { return mListenerId; } @@ -168,6 +180,17 @@ 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(); @@ -201,15 +224,12 @@ public final class CallerIdentity { return false; } CallerIdentity that = (CallerIdentity) o; - return equalsIgnoringListenerId(that) && Objects.equals(mListenerId, that.mListenerId); - } - - public boolean equalsIgnoringListenerId(CallerIdentity that) { - return that != null - && mUid == that.mUid + return mUid == that.mUid && mPid == that.mPid && mPackageName.equals(that.mPackageName) - && Objects.equals(mAttributionTag, that.mAttributionTag); + && Objects.equals(mAttributionTag, that.mAttributionTag) + && (mListenerId == null || that.mListenerId == null || mListenerId.equals( + that.mListenerId)); } @Override diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java index 1bf9da701311..cbbc981d9ed6 100644 --- a/services/core/java/com/android/server/location/LocationManagerService.java +++ b/services/core/java/com/android/server/location/LocationManagerService.java @@ -252,7 +252,7 @@ public class LocationManagerService extends ILocationManager.Stub { // @GuardedBy("mProviderManagers") // hold lock for writes, no lock necessary for simple reads - private final CopyOnWriteArrayList<LocationProviderManager> mProviderManagers = + final CopyOnWriteArrayList<LocationProviderManager> mProviderManagers = new CopyOnWriteArrayList<>(); LocationManagerService(Context context, Injector injector, LocationEventLog eventLog) { @@ -284,7 +284,7 @@ public class LocationManagerService extends ILocationManager.Stub { } @Nullable - private LocationProviderManager getLocationProviderManager(String providerName) { + LocationProviderManager getLocationProviderManager(String providerName) { if (providerName == null) { return null; } @@ -1288,13 +1288,13 @@ public class LocationManagerService extends ILocationManager.Stub { ipw.println("Historical Aggregate Location Provider Data:"); ipw.increaseIndent(); - ArrayMap<String, ArrayMap<String, LocationEventLog.AggregateStats>> aggregateStats = + ArrayMap<String, ArrayMap<CallerIdentity, LocationEventLog.AggregateStats>> aggregateStats = mEventLog.copyAggregateStats(); for (int i = 0; i < aggregateStats.size(); i++) { ipw.print(aggregateStats.keyAt(i)); ipw.println(":"); ipw.increaseIndent(); - ArrayMap<String, LocationEventLog.AggregateStats> providerStats = + ArrayMap<CallerIdentity, LocationEventLog.AggregateStats> providerStats = aggregateStats.valueAt(i); for (int j = 0; j < providerStats.size(); j++) { ipw.print(providerStats.keyAt(j)); @@ -1362,7 +1362,7 @@ public class LocationManagerService extends ILocationManager.Stub { if (provider != null && !provider.equals(manager.getName())) { continue; } - if (identity.equalsIgnoringListenerId(manager.getIdentity())) { + if (identity.equals(manager.getIdentity())) { return true; } } 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 dbfd0a52b013..29ce3783c4a1 100644 --- a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java +++ b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java @@ -64,16 +64,17 @@ public class LocationEventLog extends LocalEventLog { private static final int EVENT_LOCATION_POWER_SAVE_MODE_CHANGE = 10; @GuardedBy("mAggregateStats") - private final ArrayMap<String, ArrayMap<String, AggregateStats>> mAggregateStats; + private final ArrayMap<String, ArrayMap<CallerIdentity, AggregateStats>> mAggregateStats; public LocationEventLog() { super(getLogSize()); mAggregateStats = new ArrayMap<>(4); } - public ArrayMap<String, ArrayMap<String, AggregateStats>> copyAggregateStats() { + /** Copies out all aggregated stats. */ + public ArrayMap<String, ArrayMap<CallerIdentity, AggregateStats>> copyAggregateStats() { synchronized (mAggregateStats) { - ArrayMap<String, ArrayMap<String, AggregateStats>> copy = new ArrayMap<>( + ArrayMap<String, ArrayMap<CallerIdentity, AggregateStats>> copy = new ArrayMap<>( mAggregateStats); for (int i = 0; i < copy.size(); i++) { copy.setValueAt(i, new ArrayMap<>(copy.valueAt(i))); @@ -82,17 +83,18 @@ public class LocationEventLog extends LocalEventLog { } } - private AggregateStats getAggregateStats(String provider, String packageName) { + private AggregateStats getAggregateStats(String provider, CallerIdentity identity) { synchronized (mAggregateStats) { - ArrayMap<String, AggregateStats> packageMap = mAggregateStats.get(provider); + ArrayMap<CallerIdentity, AggregateStats> packageMap = mAggregateStats.get(provider); if (packageMap == null) { packageMap = new ArrayMap<>(2); mAggregateStats.put(provider, packageMap); } - AggregateStats stats = packageMap.get(packageName); + CallerIdentity stripped = identity.stripListenerId(); + AggregateStats stats = packageMap.get(stripped); if (stats == null) { stats = new AggregateStats(); - packageMap.put(packageName, stats); + packageMap.put(stripped, stats); } return stats; } @@ -117,34 +119,33 @@ public class LocationEventLog extends LocalEventLog { public void logProviderClientRegistered(String provider, CallerIdentity identity, LocationRequest request) { addLogEvent(EVENT_PROVIDER_REGISTER_CLIENT, provider, identity, request); - getAggregateStats(provider, identity.getPackageName()) - .markRequestAdded(request.getIntervalMillis()); + getAggregateStats(provider, identity).markRequestAdded(request.getIntervalMillis()); } /** Logs a client unregistration for a location provider. */ public void logProviderClientUnregistered(String provider, CallerIdentity identity) { addLogEvent(EVENT_PROVIDER_UNREGISTER_CLIENT, provider, identity); - getAggregateStats(provider, identity.getPackageName()).markRequestRemoved(); + getAggregateStats(provider, identity).markRequestRemoved(); } /** Logs a client for a location provider entering the active state. */ public void logProviderClientActive(String provider, CallerIdentity identity) { - getAggregateStats(provider, identity.getPackageName()).markRequestActive(); + getAggregateStats(provider, identity).markRequestActive(); } /** Logs a client for a location provider leaving the active state. */ public void logProviderClientInactive(String provider, CallerIdentity identity) { - getAggregateStats(provider, identity.getPackageName()).markRequestInactive(); + getAggregateStats(provider, identity).markRequestInactive(); } /** Logs a client for a location provider entering the foreground state. */ public void logProviderClientForeground(String provider, CallerIdentity identity) { - getAggregateStats(provider, identity.getPackageName()).markRequestForeground(); + getAggregateStats(provider, identity).markRequestForeground(); } /** Logs a client for a location provider leaving the foreground state. */ public void logProviderClientBackground(String provider, CallerIdentity identity) { - getAggregateStats(provider, identity.getPackageName()).markRequestBackground(); + getAggregateStats(provider, identity).markRequestBackground(); } /** Logs a change to the provider request for a location provider. */ @@ -165,7 +166,7 @@ public class LocationEventLog extends LocalEventLog { if (Build.IS_DEBUGGABLE || D) { addLogEvent(EVENT_PROVIDER_DELIVER_LOCATION, provider, numLocations, identity); } - getAggregateStats(provider, identity.getPackageName()).markLocationDelivered(); + getAggregateStats(provider, identity).markLocationDelivered(); } /** Logs that a provider has entered or exited stationary throttling. */ @@ -218,7 +219,7 @@ public class LocationEventLog extends LocalEventLog { protected final String mProvider; - protected ProviderEvent(long timeDelta, String provider) { + ProviderEvent(long timeDelta, String provider) { super(timeDelta); mProvider = provider; } @@ -234,7 +235,7 @@ public class LocationEventLog extends LocalEventLog { private final int mUserId; private final boolean mEnabled; - protected ProviderEnabledEvent(long timeDelta, String provider, int userId, + ProviderEnabledEvent(long timeDelta, String provider, int userId, boolean enabled) { super(timeDelta, provider); mUserId = userId; @@ -252,7 +253,7 @@ public class LocationEventLog extends LocalEventLog { private final boolean mMocked; - protected ProviderMockedEvent(long timeDelta, String provider, boolean mocked) { + ProviderMockedEvent(long timeDelta, String provider, boolean mocked) { super(timeDelta, provider); mMocked = mocked; } @@ -273,7 +274,7 @@ public class LocationEventLog extends LocalEventLog { private final CallerIdentity mIdentity; @Nullable private final LocationRequest mLocationRequest; - private ProviderRegisterEvent(long timeDelta, String provider, boolean registered, + ProviderRegisterEvent(long timeDelta, String provider, boolean registered, CallerIdentity identity, @Nullable LocationRequest locationRequest) { super(timeDelta, provider); mRegistered = registered; @@ -296,7 +297,7 @@ public class LocationEventLog extends LocalEventLog { private final ProviderRequest mRequest; - private ProviderUpdateEvent(long timeDelta, String provider, ProviderRequest request) { + ProviderUpdateEvent(long timeDelta, String provider, ProviderRequest request) { super(timeDelta, provider); mRequest = request; } @@ -311,7 +312,7 @@ public class LocationEventLog extends LocalEventLog { private final int mNumLocations; - private ProviderReceiveLocationEvent(long timeDelta, String provider, int numLocations) { + ProviderReceiveLocationEvent(long timeDelta, String provider, int numLocations) { super(timeDelta, provider); mNumLocations = numLocations; } @@ -327,7 +328,7 @@ public class LocationEventLog extends LocalEventLog { private final int mNumLocations; @Nullable private final CallerIdentity mIdentity; - private ProviderDeliverLocationEvent(long timeDelta, String provider, int numLocations, + ProviderDeliverLocationEvent(long timeDelta, String provider, int numLocations, @Nullable CallerIdentity identity) { super(timeDelta, provider); mNumLocations = numLocations; @@ -345,7 +346,7 @@ public class LocationEventLog extends LocalEventLog { private final boolean mStationaryThrottled; - private ProviderStationaryThrottledEvent(long timeDelta, String provider, + ProviderStationaryThrottledEvent(long timeDelta, String provider, boolean stationaryThrottled) { super(timeDelta, provider); mStationaryThrottled = stationaryThrottled; @@ -363,7 +364,7 @@ public class LocationEventLog extends LocalEventLog { @LocationPowerSaveMode private final int mLocationPowerSaveMode; - private LocationPowerSaveModeEvent(long timeDelta, + LocationPowerSaveModeEvent(long timeDelta, @LocationPowerSaveMode int locationPowerSaveMode) { super(timeDelta); mLocationPowerSaveMode = locationPowerSaveMode; @@ -401,7 +402,7 @@ public class LocationEventLog extends LocalEventLog { private final int mUserId; private final boolean mEnabled; - private LocationEnabledEvent(long timeDelta, int userId, boolean enabled) { + LocationEnabledEvent(long timeDelta, int userId, boolean enabled) { super(timeDelta); mUserId = userId; mEnabled = enabled; diff --git a/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java b/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java index 4e0a0b89f238..08deb8698608 100644 --- a/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java +++ b/services/core/java/com/android/server/location/provider/AbstractLocationProvider.java @@ -196,9 +196,12 @@ public abstract class AbstractLocationProvider { */ protected AbstractLocationProvider(Executor executor, @Nullable CallerIdentity identity, @Nullable ProviderProperties properties) { + Preconditions.checkArgument(identity == null || identity.getListenerId() == null); mExecutor = executor; mInternalState = new AtomicReference<>(new InternalState(null, - State.EMPTY_STATE.withIdentity(identity).withProperties(properties))); + State.EMPTY_STATE + .withIdentity(identity) + .withProperties(properties))); mController = new Controller(); } @@ -273,6 +276,7 @@ public abstract class AbstractLocationProvider { * Call this method to report a change in provider packages. */ protected void setIdentity(@Nullable CallerIdentity identity) { + Preconditions.checkArgument(identity == null || identity.getListenerId() == null); setState(state -> state.withIdentity(identity)); } @@ -335,6 +339,8 @@ public abstract class AbstractLocationProvider { private boolean mStarted = false; + Controller() {} + @Override public State setListener(@Nullable Listener listener) { InternalState oldInternalState = mInternalState.getAndUpdate( 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 388b5a4dd54e..5a35d7f88ff3 100644 --- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java +++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java @@ -304,6 +304,7 @@ public class LocationProviderManager extends LocationTransport transport, @PermissionLevel int permissionLevel) { super(Objects.requireNonNull(request), identity, transport); + Preconditions.checkArgument(identity.getListenerId() != null); Preconditions.checkArgument(permissionLevel > PERMISSION_NONE); Preconditions.checkArgument(!request.getWorkSource().isEmpty()); 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 66b037d70a40..68d6557880c4 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 @@ -123,9 +123,10 @@ public class LocationProviderManagerTest { .setPowerUsage(POWER_USAGE_HIGH) .setAccuracy(ProviderProperties.ACCURACY_FINE) .build(); + private static final CallerIdentity PROVIDER_IDENTITY = CallerIdentity.forTest(CURRENT_USER, 1, + "mypackage", "attribution"); private static final CallerIdentity IDENTITY = CallerIdentity.forTest(CURRENT_USER, 1, - "mypackage", - "attribution"); + "mypackage", "attribution", "listener"); private static final WorkSource WORK_SOURCE = new WorkSource(IDENTITY.getUid()); private Random mRandom; @@ -169,7 +170,7 @@ public class LocationProviderManagerTest { mPassive.startManager(); mPassive.setRealProvider(new PassiveLocationProvider(mContext)); - mProvider = new TestProvider(PROPERTIES, IDENTITY); + mProvider = new TestProvider(PROPERTIES, PROVIDER_IDENTITY); mProvider.setProviderAllowed(true); mManager = new LocationProviderManager(mContext, mInjector, eventLog, NAME, mPassive); @@ -351,7 +352,7 @@ public class LocationProviderManagerTest { @Test public void testGetLastLocation_ClearOnMockRemoval() { - MockLocationProvider mockProvider = new MockLocationProvider(PROPERTIES, IDENTITY); + MockLocationProvider mockProvider = new MockLocationProvider(PROPERTIES, PROVIDER_IDENTITY); mockProvider.setAllowed(true); mManager.setMockProvider(mockProvider); @@ -441,7 +442,7 @@ public class LocationProviderManagerTest { @Test public void testRegisterListener_SameProcess() throws Exception { CallerIdentity identity = CallerIdentity.forTest(CURRENT_USER, Process.myPid(), "mypackage", - "attribution"); + "attribution", "listener"); ILocationListener listener = createMockLocationListener(); mManager.registerLocationRequest( @@ -477,7 +478,7 @@ public class LocationProviderManagerTest { @Test public void testRegisterListener_Unregister_SameProcess() throws Exception { CallerIdentity identity = CallerIdentity.forTest(CURRENT_USER, Process.myPid(), "mypackage", - "attribution"); + "attribution", "listener"); ILocationListener listener = createMockLocationListener(); mManager.registerLocationRequest( @@ -604,7 +605,7 @@ public class LocationProviderManagerTest { @Test public void testRegisterListener_Wakelock() throws Exception { CallerIdentity identity = CallerIdentity.forTest(CURRENT_USER, Process.myPid(), "mypackage", - "attribution"); + "attribution", "listener"); ILocationListener listener = createMockLocationListener(); mManager.registerLocationRequest( |