Loading location/java/android/location/LocationManager.java +5 −4 Original line number Diff line number Diff line Loading @@ -1943,7 +1943,7 @@ public class LocationManager { * * @param provider the provider name * @param properties the provider properties * @param locationTags the attribution tags for accessing location from the provider * @param extraAttributionTags additional attribution tags associated with this provider * * @throws IllegalArgumentException if provider is null * @throws IllegalArgumentException if properties is null Loading @@ -1952,13 +1952,14 @@ public class LocationManager { * allowed} for your app. */ public void addTestProvider(@NonNull String provider, @NonNull ProviderProperties properties, @NonNull Set<String> locationTags) { @NonNull Set<String> extraAttributionTags) { Preconditions.checkArgument(provider != null, "invalid null provider"); Preconditions.checkArgument(properties != null, "invalid null properties"); Preconditions.checkArgument(locationTags != null, "invalid null location tags"); Preconditions.checkArgument(extraAttributionTags != null, "invalid null extra attribution tags"); try { mService.addTestProvider(provider, properties, new ArrayList<>(locationTags), mService.addTestProvider(provider, properties, new ArrayList<>(extraAttributionTags), mContext.getOpPackageName(), mContext.getFeatureId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); Loading services/core/java/com/android/server/location/LocationManagerService.java +3 −3 Original line number Diff line number Diff line Loading @@ -464,7 +464,7 @@ public class LocationManagerService extends ILocationManager.Stub { .build(); final LocationProviderManager manager = getOrAddLocationProviderManager(name); manager.setMockProvider(new MockLocationProvider(properties, CallerIdentity.fromContext(mContext), /*locationTags*/ null)); CallerIdentity.fromContext(mContext), Collections.emptySet())); } } Loading Loading @@ -1170,7 +1170,7 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public void addTestProvider(String provider, ProviderProperties properties, List<String> locationTags, String packageName, String attributionTag) { List<String> extraAttributionTags, String packageName, String attributionTag) { // unsafe is ok because app ops will verify the package name CallerIdentity identity = CallerIdentity.fromBinderUnsafe(packageName, attributionTag); if (!mInjector.getAppOpsHelper().noteOp(AppOpsManager.OP_MOCK_LOCATION, identity)) { Loading @@ -1179,7 +1179,7 @@ public class LocationManagerService extends ILocationManager.Stub { final LocationProviderManager manager = getOrAddLocationProviderManager(provider); manager.setMockProvider(new MockLocationProvider(properties, identity, (locationTags != null) ? new ArraySet<>(locationTags) : null)); new ArraySet<>(extraAttributionTags))); } @Override Loading services/core/java/com/android/server/location/LocationShellCommand.java +108 −57 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import com.android.modules.utils.BasicShellCommandHandler; import java.io.PrintWriter; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; /** Loading @@ -50,15 +52,11 @@ class LocationShellCommand extends BasicShellCommandHandler { switch (cmd) { case "is-location-enabled": { int userId = parseUserId(); boolean enabled = mService.isLocationEnabledForUser(userId); getOutPrintWriter().println(enabled); handleIsLocationEnabled(); return 0; } case "set-location-enabled": { int userId = parseUserId(); boolean enabled = Boolean.parseBoolean(getNextArgRequired()); mService.setLocationEnabledForUser(enabled, userId); handleSetLocationEnabled(); return 0; } case "providers": { Loading @@ -73,36 +71,23 @@ class LocationShellCommand extends BasicShellCommandHandler { private int parseProvidersCommand(String cmd) { switch (cmd) { case "add-test-provider": { String provider = getNextArgRequired(); ProviderProperties properties = parseTestProviderProviderProperties(); mService.addTestProvider(provider, properties, /*locationTags*/ null, mContext.getOpPackageName(), mContext.getFeatureId()); handleAddTestProvider(); return 0; } case "remove-test-provider": { String provider = getNextArgRequired(); mService.removeTestProvider(provider, mContext.getOpPackageName(), mContext.getFeatureId()); handleRemoveTestProvider(); return 0; } case "set-test-provider-enabled": { String provider = getNextArgRequired(); boolean enabled = Boolean.parseBoolean(getNextArgRequired()); mService.setTestProviderEnabled(provider, enabled, mContext.getOpPackageName(), mContext.getFeatureId()); handleSetTestProviderEnabled(); return 0; } case "set-test-provider-location": { String provider = getNextArgRequired(); Location location = parseTestProviderLocation(provider); mService.setTestProviderLocation(provider, location, mContext.getOpPackageName(), mContext.getFeatureId()); handleSetTestProviderLocation(); return 0; } case "send-extra-command": { String provider = getNextArgRequired(); String command = getNextArgRequired(); mService.sendExtraCommand(provider, command, null); handleSendExtraCommand(); return 0; } default: Loading @@ -110,21 +95,47 @@ class LocationShellCommand extends BasicShellCommandHandler { } } private int parseUserId() { final String option = getNextOption(); if (option != null) { if (option.equals("--user")) { return UserHandle.parseUserArg(getNextArgRequired()); private void handleIsLocationEnabled() { int userId = UserHandle.USER_CURRENT_OR_SELF; do { String option = getNextOption(); if (option == null) { break; } if ("--user".equals(option)) { userId = UserHandle.parseUserArg(getNextArgRequired()); } else { throw new IllegalArgumentException( "Expected \"--user\" option, but got \"" + option + "\" instead"); throw new IllegalArgumentException("Unknown option: " + option); } } while (true); getOutPrintWriter().println(mService.isLocationEnabledForUser(userId)); } return UserHandle.USER_CURRENT_OR_SELF; private void handleSetLocationEnabled() { boolean enabled = Boolean.parseBoolean(getNextArgRequired()); int userId = UserHandle.USER_CURRENT_OR_SELF; do { String option = getNextOption(); if (option == null) { break; } if ("--user".equals(option)) { userId = UserHandle.parseUserArg(getNextArgRequired()); } else { throw new IllegalArgumentException("Unknown option: " + option); } } while (true); mService.setLocationEnabledForUser(enabled, userId); } private void handleAddTestProvider() { String provider = getNextArgRequired(); private ProviderProperties parseTestProviderProviderProperties() { boolean requiresNetwork = false; boolean requiresSatellite = false; boolean requiresCell = false; Loading @@ -135,8 +146,13 @@ class LocationShellCommand extends BasicShellCommandHandler { int powerRequirement = Criteria.POWER_LOW; int accuracy = Criteria.ACCURACY_FINE; List<String> extraAttributionTags = Collections.emptyList(); do { String option = getNextOption(); while (option != null) { if (option == null) { break; } switch (option) { case "--requiresNetwork": { requiresNetwork = true; Loading Loading @@ -174,12 +190,15 @@ class LocationShellCommand extends BasicShellCommandHandler { accuracy = Integer.parseInt(getNextArgRequired()); break; } case "--extraAttributionTags": { extraAttributionTags = Arrays.asList(getNextArgRequired().split(",")); break; } default: throw new IllegalArgumentException( "Received unexpected option: " + option); } option = getNextOption(); } } while(true); ProviderProperties properties = new ProviderProperties.Builder() .setHasNetworkRequirement(requiresNetwork) Loading @@ -192,30 +211,50 @@ class LocationShellCommand extends BasicShellCommandHandler { .setPowerUsage(powerRequirement) .setAccuracy(accuracy) .build(); mService.addTestProvider(provider, properties, extraAttributionTags, mContext.getOpPackageName(), mContext.getAttributionTag()); } return properties; private void handleRemoveTestProvider() { String provider = getNextArgRequired(); mService.removeTestProvider(provider, mContext.getOpPackageName(), mContext.getAttributionTag()); } private Location parseTestProviderLocation(String provider) { boolean hasLatitude = false; boolean hasLongitude = false; private void handleSetTestProviderEnabled() { String provider = getNextArgRequired(); boolean enabled = Boolean.parseBoolean(getNextArgRequired()); mService.setTestProviderEnabled(provider, enabled, mContext.getOpPackageName(), mContext.getAttributionTag()); } private void handleSetTestProviderLocation() { String provider = getNextArgRequired(); boolean hasLatLng = false; Location location = new Location(provider); location.setAccuracy(DEFAULT_TEST_LOCATION_ACCURACY); location.setTime(System.currentTimeMillis()); location.setElapsedRealtimeNanos(System.nanoTime()); do { String option = getNextOption(); while (option != null) { if (option == null) { break; } switch (option) { case "--location": { String[] locationInput = getNextArgRequired().split(","); if (locationInput.length != 2) { throw new IllegalArgumentException( "Unexpected location format: " + Arrays.toString(locationInput)); throw new IllegalArgumentException("Location argument must be in the form " + "of \"<LATITUDE>,<LONGITUDE>\", not " + Arrays.toString(locationInput)); } location.setLatitude(Double.parseDouble(locationInput[0])); location.setLongitude(Double.parseDouble(locationInput[1])); hasLatLng = true; break; } case "--accuracy": { Loading @@ -227,15 +266,22 @@ class LocationShellCommand extends BasicShellCommandHandler { break; } default: throw new IllegalArgumentException( "Received unexpected option: " + option); throw new IllegalArgumentException("Unknown option: " + option); } option = getNextOption(); } while (true); if (!hasLatLng) { throw new IllegalArgumentException("Option \"--location\" is required"); } location.setElapsedRealtimeNanos(System.nanoTime()); mService.setTestProviderLocation(provider, location, mContext.getOpPackageName(), mContext.getAttributionTag()); } return location; private void handleSendExtraCommand() { String provider = getNextArgRequired(); String command = getNextArgRequired(); mService.sendExtraCommand(provider, command, null); } @Override Loading @@ -245,24 +291,29 @@ class LocationShellCommand extends BasicShellCommandHandler { pw.println(" help or -h"); pw.println(" Print this help text."); pw.println(" is-location-enabled [--user <USER_ID>]"); pw.println(" Gets the master location switch enabled state."); pw.println(" set-location-enabled [--user <USER_ID>] true|false"); pw.println(" Sets the master location switch enabled state."); pw.println(" Gets the master location switch enabled state. If no user is specified,"); pw.println(" the current user is assumed."); pw.println(" set-location-enabled true|false [--user <USER_ID>]"); pw.println(" Sets the master location switch enabled state. If no user is specified,"); pw.println(" the current user is assumed."); pw.println(" providers"); pw.println(" The providers command is followed by a subcommand, as listed below:"); pw.println(); pw.println(" add-test-provider <PROVIDER> [--requiresNetwork] [--requiresSatellite]"); pw.println(" [--requiresCell] [--hasMonetaryCost] [--supportsAltitude]"); pw.println(" [--supportsSpeed] [--supportsBearing]"); pw.println(" [--powerRequirement <POWER_REQUIREMENT>]"); pw.println(" [--extraAttributionTags <TAG>,<TAG>,...]"); pw.println(" Add the given test provider. Requires MOCK_LOCATION permissions which"); pw.println(" can be enabled by running \"adb shell appops set <uid>"); pw.println(" android:mock_location allow\". There are optional flags that can be"); pw.println(" used to configure the provider properties. If no flags are included,"); pw.println(" then default values will be used."); pw.println(" used to configure the provider properties and additional arguments. If"); pw.println(" no flags are included, then default values will be used."); pw.println(" remove-test-provider <PROVIDER>"); pw.println(" Remove the given test provider."); pw.println(" set-test-provider-enabled <PROVIDER> true|false"); pw.println(" Sets the given test provider enabled state."); pw.println(" set-test-provider-location <PROVIDER> [--location <LATITUDE>,<LONGITUDE>]"); pw.println(" set-test-provider-location <PROVIDER> --location <LATITUDE>,<LONGITUDE>"); pw.println(" [--accuracy <ACCURACY>] [--time <TIME>]"); pw.println(" Set location for given test provider. Accuracy and time are optional."); pw.println(" send-extra-command <PROVIDER> <COMMAND>"); Loading services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +2 −1 Original line number Diff line number Diff line Loading @@ -103,6 +103,7 @@ import com.android.server.location.provider.AbstractLocationProvider; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Objects; Loading Loading @@ -372,7 +373,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements public GnssLocationProvider(Context context, Injector injector, GnssNative gnssNative, GnssMetrics gnssMetrics) { super(FgThread.getExecutor(), CallerIdentity.fromContext(context), PROPERTIES, /*locationTags*/ null); Collections.emptySet()); mContext = context; mGnssNative = gnssNative; Loading services/core/java/com/android/server/location/provider/AbstractLocationProvider.java +28 −22 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import com.android.internal.util.Preconditions; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Collections; import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; Loading Loading @@ -66,9 +67,10 @@ public abstract class AbstractLocationProvider { /** * Default state value for a location provider that is disabled with no properties and an * empty provider package list. * empty extra attribution tag set. */ public static final State EMPTY_STATE = new State(false, null, null, null); public static final State EMPTY_STATE = new State(false, null, null, Collections.emptySet()); /** * The provider's allowed state. Loading @@ -85,14 +87,18 @@ public abstract class AbstractLocationProvider { */ @Nullable public final CallerIdentity identity; @Nullable public final Set<String> locationTags; /** * A set of attribution tags also associated with this provider - these attribution tags may * be afforded special privileges. */ public final Set<String> extraAttributionTags; private State(boolean allowed, ProviderProperties properties, CallerIdentity identity, Set<String> locationTags) { Set<String> extraAttributionTags) { this.allowed = allowed; this.properties = properties; this.identity = identity; this.locationTags = locationTags; this.extraAttributionTags = Objects.requireNonNull(extraAttributionTags); } /** Loading @@ -102,7 +108,7 @@ public abstract class AbstractLocationProvider { if (allowed == this.allowed) { return this; } else { return new State(allowed, properties, identity, locationTags); return new State(allowed, properties, identity, extraAttributionTags); } } Loading @@ -113,7 +119,7 @@ public abstract class AbstractLocationProvider { if (Objects.equals(properties, this.properties)) { return this; } else { return new State(allowed, properties, identity, locationTags); return new State(allowed, properties, identity, extraAttributionTags); } } Loading @@ -124,18 +130,18 @@ public abstract class AbstractLocationProvider { if (Objects.equals(identity, this.identity)) { return this; } else { return new State(allowed, properties, identity, locationTags); return new State(allowed, properties, identity, extraAttributionTags); } } /** * Returns a state the same as the current but with location tags set as specified. * Returns a state the same as the current but with extra attribution tags set as specified. */ public State withLocationTags(@Nullable Set<String> locationTags) { if (Objects.equals(locationTags, this.locationTags)) { public State withExtraAttributionTags(Set<String> extraAttributionTags) { if (extraAttributionTags.equals(this.extraAttributionTags)) { return this; } else { return new State(allowed, properties, identity, locationTags); return new State(allowed, properties, identity, extraAttributionTags); } } Loading @@ -151,12 +157,12 @@ public abstract class AbstractLocationProvider { State state = (State) o; return allowed == state.allowed && properties == state.properties && Objects.equals(identity, state.identity) && Objects.equals(locationTags, state.locationTags); && extraAttributionTags.equals(state.extraAttributionTags); } @Override public int hashCode() { return Objects.hash(allowed, properties, identity, locationTags); return Objects.hash(allowed, properties, identity, extraAttributionTags); } } Loading Loading @@ -213,14 +219,14 @@ public abstract class AbstractLocationProvider { * An optional identity and properties may be provided to initialize the location provider. */ protected AbstractLocationProvider(Executor executor, @Nullable CallerIdentity identity, @Nullable ProviderProperties properties, @Nullable Set<String> locationTags) { @Nullable ProviderProperties properties, Set<String> extraAttributionTags) { Preconditions.checkArgument(identity == null || identity.getListenerId() == null); mExecutor = executor; mExecutor = Objects.requireNonNull(executor); mInternalState = new AtomicReference<>(new InternalState(null, State.EMPTY_STATE .withIdentity(identity) .withProperties(properties).withLocationTags(locationTags)) ); .withProperties(properties) .withExtraAttributionTags(extraAttributionTags))); mController = new Controller(); } Loading Loading @@ -292,7 +298,7 @@ public abstract class AbstractLocationProvider { } /** * Call this method to report a change in provider packages. * Call this method to report a change in the provider's identity. */ protected void setIdentity(@Nullable CallerIdentity identity) { Preconditions.checkArgument(identity == null || identity.getListenerId() == null); Loading @@ -300,10 +306,10 @@ public abstract class AbstractLocationProvider { } /** * Call this method to report a change in provider location tags. * Call this method to report a change in the provider's extra attribution tags. */ protected void setLocationTags(@Nullable Set<String> locationTags) { setState(state -> state.withLocationTags(locationTags)); protected void setExtraAttributionTags(Set<String> extraAttributionTags) { setState(state -> state.withExtraAttributionTags(extraAttributionTags)); } /** Loading Loading
location/java/android/location/LocationManager.java +5 −4 Original line number Diff line number Diff line Loading @@ -1943,7 +1943,7 @@ public class LocationManager { * * @param provider the provider name * @param properties the provider properties * @param locationTags the attribution tags for accessing location from the provider * @param extraAttributionTags additional attribution tags associated with this provider * * @throws IllegalArgumentException if provider is null * @throws IllegalArgumentException if properties is null Loading @@ -1952,13 +1952,14 @@ public class LocationManager { * allowed} for your app. */ public void addTestProvider(@NonNull String provider, @NonNull ProviderProperties properties, @NonNull Set<String> locationTags) { @NonNull Set<String> extraAttributionTags) { Preconditions.checkArgument(provider != null, "invalid null provider"); Preconditions.checkArgument(properties != null, "invalid null properties"); Preconditions.checkArgument(locationTags != null, "invalid null location tags"); Preconditions.checkArgument(extraAttributionTags != null, "invalid null extra attribution tags"); try { mService.addTestProvider(provider, properties, new ArrayList<>(locationTags), mService.addTestProvider(provider, properties, new ArrayList<>(extraAttributionTags), mContext.getOpPackageName(), mContext.getFeatureId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); Loading
services/core/java/com/android/server/location/LocationManagerService.java +3 −3 Original line number Diff line number Diff line Loading @@ -464,7 +464,7 @@ public class LocationManagerService extends ILocationManager.Stub { .build(); final LocationProviderManager manager = getOrAddLocationProviderManager(name); manager.setMockProvider(new MockLocationProvider(properties, CallerIdentity.fromContext(mContext), /*locationTags*/ null)); CallerIdentity.fromContext(mContext), Collections.emptySet())); } } Loading Loading @@ -1170,7 +1170,7 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public void addTestProvider(String provider, ProviderProperties properties, List<String> locationTags, String packageName, String attributionTag) { List<String> extraAttributionTags, String packageName, String attributionTag) { // unsafe is ok because app ops will verify the package name CallerIdentity identity = CallerIdentity.fromBinderUnsafe(packageName, attributionTag); if (!mInjector.getAppOpsHelper().noteOp(AppOpsManager.OP_MOCK_LOCATION, identity)) { Loading @@ -1179,7 +1179,7 @@ public class LocationManagerService extends ILocationManager.Stub { final LocationProviderManager manager = getOrAddLocationProviderManager(provider); manager.setMockProvider(new MockLocationProvider(properties, identity, (locationTags != null) ? new ArraySet<>(locationTags) : null)); new ArraySet<>(extraAttributionTags))); } @Override Loading
services/core/java/com/android/server/location/LocationShellCommand.java +108 −57 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import com.android.modules.utils.BasicShellCommandHandler; import java.io.PrintWriter; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; /** Loading @@ -50,15 +52,11 @@ class LocationShellCommand extends BasicShellCommandHandler { switch (cmd) { case "is-location-enabled": { int userId = parseUserId(); boolean enabled = mService.isLocationEnabledForUser(userId); getOutPrintWriter().println(enabled); handleIsLocationEnabled(); return 0; } case "set-location-enabled": { int userId = parseUserId(); boolean enabled = Boolean.parseBoolean(getNextArgRequired()); mService.setLocationEnabledForUser(enabled, userId); handleSetLocationEnabled(); return 0; } case "providers": { Loading @@ -73,36 +71,23 @@ class LocationShellCommand extends BasicShellCommandHandler { private int parseProvidersCommand(String cmd) { switch (cmd) { case "add-test-provider": { String provider = getNextArgRequired(); ProviderProperties properties = parseTestProviderProviderProperties(); mService.addTestProvider(provider, properties, /*locationTags*/ null, mContext.getOpPackageName(), mContext.getFeatureId()); handleAddTestProvider(); return 0; } case "remove-test-provider": { String provider = getNextArgRequired(); mService.removeTestProvider(provider, mContext.getOpPackageName(), mContext.getFeatureId()); handleRemoveTestProvider(); return 0; } case "set-test-provider-enabled": { String provider = getNextArgRequired(); boolean enabled = Boolean.parseBoolean(getNextArgRequired()); mService.setTestProviderEnabled(provider, enabled, mContext.getOpPackageName(), mContext.getFeatureId()); handleSetTestProviderEnabled(); return 0; } case "set-test-provider-location": { String provider = getNextArgRequired(); Location location = parseTestProviderLocation(provider); mService.setTestProviderLocation(provider, location, mContext.getOpPackageName(), mContext.getFeatureId()); handleSetTestProviderLocation(); return 0; } case "send-extra-command": { String provider = getNextArgRequired(); String command = getNextArgRequired(); mService.sendExtraCommand(provider, command, null); handleSendExtraCommand(); return 0; } default: Loading @@ -110,21 +95,47 @@ class LocationShellCommand extends BasicShellCommandHandler { } } private int parseUserId() { final String option = getNextOption(); if (option != null) { if (option.equals("--user")) { return UserHandle.parseUserArg(getNextArgRequired()); private void handleIsLocationEnabled() { int userId = UserHandle.USER_CURRENT_OR_SELF; do { String option = getNextOption(); if (option == null) { break; } if ("--user".equals(option)) { userId = UserHandle.parseUserArg(getNextArgRequired()); } else { throw new IllegalArgumentException( "Expected \"--user\" option, but got \"" + option + "\" instead"); throw new IllegalArgumentException("Unknown option: " + option); } } while (true); getOutPrintWriter().println(mService.isLocationEnabledForUser(userId)); } return UserHandle.USER_CURRENT_OR_SELF; private void handleSetLocationEnabled() { boolean enabled = Boolean.parseBoolean(getNextArgRequired()); int userId = UserHandle.USER_CURRENT_OR_SELF; do { String option = getNextOption(); if (option == null) { break; } if ("--user".equals(option)) { userId = UserHandle.parseUserArg(getNextArgRequired()); } else { throw new IllegalArgumentException("Unknown option: " + option); } } while (true); mService.setLocationEnabledForUser(enabled, userId); } private void handleAddTestProvider() { String provider = getNextArgRequired(); private ProviderProperties parseTestProviderProviderProperties() { boolean requiresNetwork = false; boolean requiresSatellite = false; boolean requiresCell = false; Loading @@ -135,8 +146,13 @@ class LocationShellCommand extends BasicShellCommandHandler { int powerRequirement = Criteria.POWER_LOW; int accuracy = Criteria.ACCURACY_FINE; List<String> extraAttributionTags = Collections.emptyList(); do { String option = getNextOption(); while (option != null) { if (option == null) { break; } switch (option) { case "--requiresNetwork": { requiresNetwork = true; Loading Loading @@ -174,12 +190,15 @@ class LocationShellCommand extends BasicShellCommandHandler { accuracy = Integer.parseInt(getNextArgRequired()); break; } case "--extraAttributionTags": { extraAttributionTags = Arrays.asList(getNextArgRequired().split(",")); break; } default: throw new IllegalArgumentException( "Received unexpected option: " + option); } option = getNextOption(); } } while(true); ProviderProperties properties = new ProviderProperties.Builder() .setHasNetworkRequirement(requiresNetwork) Loading @@ -192,30 +211,50 @@ class LocationShellCommand extends BasicShellCommandHandler { .setPowerUsage(powerRequirement) .setAccuracy(accuracy) .build(); mService.addTestProvider(provider, properties, extraAttributionTags, mContext.getOpPackageName(), mContext.getAttributionTag()); } return properties; private void handleRemoveTestProvider() { String provider = getNextArgRequired(); mService.removeTestProvider(provider, mContext.getOpPackageName(), mContext.getAttributionTag()); } private Location parseTestProviderLocation(String provider) { boolean hasLatitude = false; boolean hasLongitude = false; private void handleSetTestProviderEnabled() { String provider = getNextArgRequired(); boolean enabled = Boolean.parseBoolean(getNextArgRequired()); mService.setTestProviderEnabled(provider, enabled, mContext.getOpPackageName(), mContext.getAttributionTag()); } private void handleSetTestProviderLocation() { String provider = getNextArgRequired(); boolean hasLatLng = false; Location location = new Location(provider); location.setAccuracy(DEFAULT_TEST_LOCATION_ACCURACY); location.setTime(System.currentTimeMillis()); location.setElapsedRealtimeNanos(System.nanoTime()); do { String option = getNextOption(); while (option != null) { if (option == null) { break; } switch (option) { case "--location": { String[] locationInput = getNextArgRequired().split(","); if (locationInput.length != 2) { throw new IllegalArgumentException( "Unexpected location format: " + Arrays.toString(locationInput)); throw new IllegalArgumentException("Location argument must be in the form " + "of \"<LATITUDE>,<LONGITUDE>\", not " + Arrays.toString(locationInput)); } location.setLatitude(Double.parseDouble(locationInput[0])); location.setLongitude(Double.parseDouble(locationInput[1])); hasLatLng = true; break; } case "--accuracy": { Loading @@ -227,15 +266,22 @@ class LocationShellCommand extends BasicShellCommandHandler { break; } default: throw new IllegalArgumentException( "Received unexpected option: " + option); throw new IllegalArgumentException("Unknown option: " + option); } option = getNextOption(); } while (true); if (!hasLatLng) { throw new IllegalArgumentException("Option \"--location\" is required"); } location.setElapsedRealtimeNanos(System.nanoTime()); mService.setTestProviderLocation(provider, location, mContext.getOpPackageName(), mContext.getAttributionTag()); } return location; private void handleSendExtraCommand() { String provider = getNextArgRequired(); String command = getNextArgRequired(); mService.sendExtraCommand(provider, command, null); } @Override Loading @@ -245,24 +291,29 @@ class LocationShellCommand extends BasicShellCommandHandler { pw.println(" help or -h"); pw.println(" Print this help text."); pw.println(" is-location-enabled [--user <USER_ID>]"); pw.println(" Gets the master location switch enabled state."); pw.println(" set-location-enabled [--user <USER_ID>] true|false"); pw.println(" Sets the master location switch enabled state."); pw.println(" Gets the master location switch enabled state. If no user is specified,"); pw.println(" the current user is assumed."); pw.println(" set-location-enabled true|false [--user <USER_ID>]"); pw.println(" Sets the master location switch enabled state. If no user is specified,"); pw.println(" the current user is assumed."); pw.println(" providers"); pw.println(" The providers command is followed by a subcommand, as listed below:"); pw.println(); pw.println(" add-test-provider <PROVIDER> [--requiresNetwork] [--requiresSatellite]"); pw.println(" [--requiresCell] [--hasMonetaryCost] [--supportsAltitude]"); pw.println(" [--supportsSpeed] [--supportsBearing]"); pw.println(" [--powerRequirement <POWER_REQUIREMENT>]"); pw.println(" [--extraAttributionTags <TAG>,<TAG>,...]"); pw.println(" Add the given test provider. Requires MOCK_LOCATION permissions which"); pw.println(" can be enabled by running \"adb shell appops set <uid>"); pw.println(" android:mock_location allow\". There are optional flags that can be"); pw.println(" used to configure the provider properties. If no flags are included,"); pw.println(" then default values will be used."); pw.println(" used to configure the provider properties and additional arguments. If"); pw.println(" no flags are included, then default values will be used."); pw.println(" remove-test-provider <PROVIDER>"); pw.println(" Remove the given test provider."); pw.println(" set-test-provider-enabled <PROVIDER> true|false"); pw.println(" Sets the given test provider enabled state."); pw.println(" set-test-provider-location <PROVIDER> [--location <LATITUDE>,<LONGITUDE>]"); pw.println(" set-test-provider-location <PROVIDER> --location <LATITUDE>,<LONGITUDE>"); pw.println(" [--accuracy <ACCURACY>] [--time <TIME>]"); pw.println(" Set location for given test provider. Accuracy and time are optional."); pw.println(" send-extra-command <PROVIDER> <COMMAND>"); Loading
services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +2 −1 Original line number Diff line number Diff line Loading @@ -103,6 +103,7 @@ import com.android.server.location.provider.AbstractLocationProvider; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Objects; Loading Loading @@ -372,7 +373,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements public GnssLocationProvider(Context context, Injector injector, GnssNative gnssNative, GnssMetrics gnssMetrics) { super(FgThread.getExecutor(), CallerIdentity.fromContext(context), PROPERTIES, /*locationTags*/ null); Collections.emptySet()); mContext = context; mGnssNative = gnssNative; Loading
services/core/java/com/android/server/location/provider/AbstractLocationProvider.java +28 −22 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import com.android.internal.util.Preconditions; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Collections; import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; Loading Loading @@ -66,9 +67,10 @@ public abstract class AbstractLocationProvider { /** * Default state value for a location provider that is disabled with no properties and an * empty provider package list. * empty extra attribution tag set. */ public static final State EMPTY_STATE = new State(false, null, null, null); public static final State EMPTY_STATE = new State(false, null, null, Collections.emptySet()); /** * The provider's allowed state. Loading @@ -85,14 +87,18 @@ public abstract class AbstractLocationProvider { */ @Nullable public final CallerIdentity identity; @Nullable public final Set<String> locationTags; /** * A set of attribution tags also associated with this provider - these attribution tags may * be afforded special privileges. */ public final Set<String> extraAttributionTags; private State(boolean allowed, ProviderProperties properties, CallerIdentity identity, Set<String> locationTags) { Set<String> extraAttributionTags) { this.allowed = allowed; this.properties = properties; this.identity = identity; this.locationTags = locationTags; this.extraAttributionTags = Objects.requireNonNull(extraAttributionTags); } /** Loading @@ -102,7 +108,7 @@ public abstract class AbstractLocationProvider { if (allowed == this.allowed) { return this; } else { return new State(allowed, properties, identity, locationTags); return new State(allowed, properties, identity, extraAttributionTags); } } Loading @@ -113,7 +119,7 @@ public abstract class AbstractLocationProvider { if (Objects.equals(properties, this.properties)) { return this; } else { return new State(allowed, properties, identity, locationTags); return new State(allowed, properties, identity, extraAttributionTags); } } Loading @@ -124,18 +130,18 @@ public abstract class AbstractLocationProvider { if (Objects.equals(identity, this.identity)) { return this; } else { return new State(allowed, properties, identity, locationTags); return new State(allowed, properties, identity, extraAttributionTags); } } /** * Returns a state the same as the current but with location tags set as specified. * Returns a state the same as the current but with extra attribution tags set as specified. */ public State withLocationTags(@Nullable Set<String> locationTags) { if (Objects.equals(locationTags, this.locationTags)) { public State withExtraAttributionTags(Set<String> extraAttributionTags) { if (extraAttributionTags.equals(this.extraAttributionTags)) { return this; } else { return new State(allowed, properties, identity, locationTags); return new State(allowed, properties, identity, extraAttributionTags); } } Loading @@ -151,12 +157,12 @@ public abstract class AbstractLocationProvider { State state = (State) o; return allowed == state.allowed && properties == state.properties && Objects.equals(identity, state.identity) && Objects.equals(locationTags, state.locationTags); && extraAttributionTags.equals(state.extraAttributionTags); } @Override public int hashCode() { return Objects.hash(allowed, properties, identity, locationTags); return Objects.hash(allowed, properties, identity, extraAttributionTags); } } Loading Loading @@ -213,14 +219,14 @@ public abstract class AbstractLocationProvider { * An optional identity and properties may be provided to initialize the location provider. */ protected AbstractLocationProvider(Executor executor, @Nullable CallerIdentity identity, @Nullable ProviderProperties properties, @Nullable Set<String> locationTags) { @Nullable ProviderProperties properties, Set<String> extraAttributionTags) { Preconditions.checkArgument(identity == null || identity.getListenerId() == null); mExecutor = executor; mExecutor = Objects.requireNonNull(executor); mInternalState = new AtomicReference<>(new InternalState(null, State.EMPTY_STATE .withIdentity(identity) .withProperties(properties).withLocationTags(locationTags)) ); .withProperties(properties) .withExtraAttributionTags(extraAttributionTags))); mController = new Controller(); } Loading Loading @@ -292,7 +298,7 @@ public abstract class AbstractLocationProvider { } /** * Call this method to report a change in provider packages. * Call this method to report a change in the provider's identity. */ protected void setIdentity(@Nullable CallerIdentity identity) { Preconditions.checkArgument(identity == null || identity.getListenerId() == null); Loading @@ -300,10 +306,10 @@ public abstract class AbstractLocationProvider { } /** * Call this method to report a change in provider location tags. * Call this method to report a change in the provider's extra attribution tags. */ protected void setLocationTags(@Nullable Set<String> locationTags) { setState(state -> state.withLocationTags(locationTags)); protected void setExtraAttributionTags(Set<String> extraAttributionTags) { setState(state -> state.withExtraAttributionTags(extraAttributionTags)); } /** Loading