diff --git a/src/main/java/io/appium/java_client/android/AndroidDriver.java b/src/main/java/io/appium/java_client/android/AndroidDriver.java index 62016e814..1994bb69a 100644 --- a/src/main/java/io/appium/java_client/android/AndroidDriver.java +++ b/src/main/java/io/appium/java_client/android/AndroidDriver.java @@ -33,6 +33,7 @@ import io.appium.java_client.HasOnScreenKeyboard; import io.appium.java_client.LocksDevice; import io.appium.java_client.android.connection.HasNetworkConnection; +import io.appium.java_client.android.geolocation.SupportsExtendedGeolocationCommands; import io.appium.java_client.android.nativekey.PressesKey; import io.appium.java_client.battery.HasBattery; import io.appium.java_client.remote.MobilePlatform; @@ -68,7 +69,7 @@ public class AndroidDriver HasSupportedPerformanceDataType, AuthenticatesByFinger, HasOnScreenKeyboard, CanRecordScreen, SupportsSpecialEmulatorCommands, SupportsNetworkStateManagement, ListensToLogcatMessages, HasAndroidClipboard, - HasBattery, ExecuteCDPCommand { + HasBattery, ExecuteCDPCommand, SupportsExtendedGeolocationCommands { private static final String ANDROID_PLATFORM = MobilePlatform.ANDROID; diff --git a/src/main/java/io/appium/java_client/android/geolocation/AndroidGeoLocation.java b/src/main/java/io/appium/java_client/android/geolocation/AndroidGeoLocation.java new file mode 100644 index 000000000..9ab204317 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/geolocation/AndroidGeoLocation.java @@ -0,0 +1,125 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.appium.java_client.android.geolocation; + +import com.google.common.collect.ImmutableMap; + +import java.util.Map; + +import static java.util.Optional.ofNullable; + +public class AndroidGeoLocation { + private Double longitude; + private Double latitude; + private Double altitude; + private Integer satellites; + private Double speed; + + /** + * Initializes AndroidLocation instance. + */ + public AndroidGeoLocation() { + + } + + /** + * Initializes AndroidLocation instance with longitude and latitude values. + * + * @param longitude longitude value + * @param latitude latitude value + */ + public AndroidGeoLocation(double longitude, double latitude) { + this.longitude = longitude; + this.latitude = latitude; + } + + /** + * Sets geo longitude value. This value is required to set. + * + * @param longitude geo longitude + * @return self instance for chaining + */ + public AndroidGeoLocation withLongitude(double longitude) { + this.longitude = longitude; + return this; + } + + /** + * Sets geo latitude value. This value is required to set. + * + * @param latitude geo latitude + * @return self instance for chaining + */ + public AndroidGeoLocation withLatitude(double latitude) { + this.latitude = latitude; + return this; + } + + /** + * Sets geo altitude value. + * + * @param altitude geo altitude + * @return self instance for chaining + */ + public AndroidGeoLocation withAltitude(double altitude) { + this.altitude = altitude; + return this; + } + + /** + * Sets the number of geo satellites being tracked. + * This number is respected on Emulators. + * + * @param satellites the count of satellites in range 1..12 + * @return self instance for chaining + */ + public AndroidGeoLocation withSatellites(int satellites) { + this.satellites = satellites; + return this; + } + + /** + * Sets the movement speed. It is measured in meters/second + * for real devices and in knots for emulators. + * + * @param speed the actual speed, which should be greater than zero + * @return self instance for chaining + */ + public AndroidGeoLocation withSpeed(double speed) { + this.speed = speed; + return this; + } + + /** + * Builds parameters map suitable for passing to the downstream API. + * + * @return Parameters mapping + */ + public Map build() { + ImmutableMap.Builder builder = ImmutableMap.builder(); + ofNullable(longitude).map(x -> builder.put("longitude", x)) + .orElseThrow(() -> new IllegalArgumentException( + "A valid 'longitude' must be provided")); + ofNullable(latitude).map(x -> builder.put("latitude", x)) + .orElseThrow(() -> new IllegalArgumentException( + "A valid 'latitude' must be provided")); + ofNullable(altitude).map(x -> builder.put("altitude", x)); + ofNullable(satellites).map(x -> builder.put("satellites", x)); + ofNullable(speed).map(x -> builder.put("speed", x)); + return builder.build(); + } +} diff --git a/src/main/java/io/appium/java_client/android/geolocation/SupportsExtendedGeolocationCommands.java b/src/main/java/io/appium/java_client/android/geolocation/SupportsExtendedGeolocationCommands.java new file mode 100644 index 000000000..3587ad07e --- /dev/null +++ b/src/main/java/io/appium/java_client/android/geolocation/SupportsExtendedGeolocationCommands.java @@ -0,0 +1,40 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.appium.java_client.android.geolocation; + +import com.google.common.collect.ImmutableMap; +import io.appium.java_client.CommandExecutionHelper; +import io.appium.java_client.ExecutesMethod; +import org.openqa.selenium.remote.DriverCommand; + +import java.util.AbstractMap; + +public interface SupportsExtendedGeolocationCommands extends ExecutesMethod { + + /** + * Allows to set geo location with extended parameters + * available for Android platform. + * + * @param location The location object to set. + */ + default void setLocation(AndroidGeoLocation location) { + ImmutableMap parameters = ImmutableMap + .of("location", location.build()); + CommandExecutionHelper.execute(this, + new AbstractMap.SimpleEntry<>(DriverCommand.SET_LOCATION, parameters)); + } +}