diff --git a/play-services-location-api/src/main/aidl/com/google/android/gms/location/Geofence.aidl b/play-services-location-api/src/main/aidl/com/google/android/gms/location/Geofence.aidl deleted file mode 100644 index 4fc554eb..00000000 --- a/play-services-location-api/src/main/aidl/com/google/android/gms/location/Geofence.aidl +++ /dev/null @@ -1,3 +0,0 @@ -package com.google.android.gms.location; - -parcelable Geofence; \ No newline at end of file diff --git a/play-services-location-api/src/main/aidl/com/google/android/gms/location/internal/IGoogleLocationManagerService.aidl b/play-services-location-api/src/main/aidl/com/google/android/gms/location/internal/IGoogleLocationManagerService.aidl index 123a0952..605bbf1d 100644 --- a/play-services-location-api/src/main/aidl/com/google/android/gms/location/internal/IGoogleLocationManagerService.aidl +++ b/play-services-location-api/src/main/aidl/com/google/android/gms/location/internal/IGoogleLocationManagerService.aidl @@ -10,6 +10,7 @@ import com.google.android.gms.location.places.internal.IPlacesCallbacks; import com.google.android.gms.location.internal.ISettingsCallbacks; import com.google.android.gms.location.internal.LocationRequestInternal; import com.google.android.gms.location.internal.LocationRequestUpdateData; +import com.google.android.gms.location.internal.ParcelableGeofence; import com.google.android.gms.location.places.NearbyAlertRequest; import com.google.android.gms.location.places.PlaceFilter; import com.google.android.gms.location.places.PlaceRequest; @@ -18,7 +19,6 @@ import com.google.android.gms.location.places.internal.PlacesParams; import com.google.android.gms.location.places.UserAddedPlace; import com.google.android.gms.location.places.UserDataType; import com.google.android.gms.location.ActivityRecognitionResult; -import com.google.android.gms.location.Geofence; import com.google.android.gms.location.GeofencingRequest; import com.google.android.gms.location.GestureRequest; import com.google.android.gms.location.LocationAvailability; @@ -31,7 +31,7 @@ import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.LatLngBounds; interface IGoogleLocationManagerService { - void addGeofencesList(in List geofences, in PendingIntent pendingIntent, IGeofencerCallbacks callbacks, String packageName) = 0; + void addGeofencesList(in List geofences, in PendingIntent pendingIntent, IGeofencerCallbacks callbacks, String packageName) = 0; void addGeofences(in GeofencingRequest geofencingRequest, in PendingIntent pendingIntent, IGeofencerCallbacks callbacks) = 56; void removeGeofencesByIntent(in PendingIntent pendingIntent, IGeofencerCallbacks callbacks, String packageName) = 1; void removeGeofencesById(in String[] geofenceRequestIds, IGeofencerCallbacks callbacks, String packageName) = 2; diff --git a/play-services-location-api/src/main/aidl/com/google/android/gms/location/internal/ParcelableGeofence.aidl b/play-services-location-api/src/main/aidl/com/google/android/gms/location/internal/ParcelableGeofence.aidl new file mode 100644 index 00000000..d4d69547 --- /dev/null +++ b/play-services-location-api/src/main/aidl/com/google/android/gms/location/internal/ParcelableGeofence.aidl @@ -0,0 +1,3 @@ +package com.google.android.gms.location.internal; + +parcelable ParcelableGeofence; \ No newline at end of file diff --git a/play-services-location-api/src/main/java/com/google/android/gms/location/ActivityRecognitionResult.java b/play-services-location-api/src/main/java/com/google/android/gms/location/ActivityRecognitionResult.java index 497cfdb8..af6c7887 100644 --- a/play-services-location-api/src/main/java/com/google/android/gms/location/ActivityRecognitionResult.java +++ b/play-services-location-api/src/main/java/com/google/android/gms/location/ActivityRecognitionResult.java @@ -16,8 +16,177 @@ package com.google.android.gms.location; -import org.microg.safeparcel.AutoSafeParcelable; +import android.content.Intent; +import android.os.Bundle; +import org.microg.gms.common.PublicApi; +import org.microg.safeparcel.AutoSafeParcelable; +import org.microg.safeparcel.SafeParcelUtil; +import org.microg.safeparcel.SafeParceled; + +import java.util.Collections; +import java.util.List; + +/** + * Result of an activity recognition. + *

+ * It contains a list of activities that a user may have been doing at a particular time. The + * activities are sorted by the most probable activity first. A confidence is associated with each + * activity which indicates how likely that activity is. + *

+ * {@link #getMostProbableActivity()} will return the most probable activity of the user at the time + * that activity recognition was run. + */ +@PublicApi public class ActivityRecognitionResult extends AutoSafeParcelable { + + @PublicApi(exclude = true) + public static final String EXTRA_ACTIVITY_RESULT = "com.google.android.location.internal.EXTRA_ACTIVITY_RESULT"; + @PublicApi(exclude = true) + public static final String EXTRA_ACTIVITY_RESULT_LIST = "com.google.android.location.internal.EXTRA_ACTIVITY_RESULT_LIST"; + + @SafeParceled(1000) + private int versionCode = 2; + + @SafeParceled(value = 1, subClass = DetectedActivity.class) + private List probableActivities; + + @SafeParceled(2) + private long time; + + @SafeParceled(3) + private long elapsedRealtimeMillis; + + @SafeParceled(5) + private Bundle extras; + + /** + * Constructs an ActivityRecognitionResult. + * + * @param probableActivities the activities that where detected, sorted by confidence (most probable first). + * @param time the UTC time of this detection, in milliseconds since January 1, 1970. + * @param elapsedRealtimeMillis milliseconds since boot + */ + public ActivityRecognitionResult(List probableActivities, long time, long elapsedRealtimeMillis) { + this(probableActivities, time, elapsedRealtimeMillis, null); + } + + /** + * Constructs an ActivityRecognitionResult from a single activity. + * + * @param activity the most probable activity of the device. + * @param time the UTC time of this detection, in milliseconds since January 1, 1970. + * @param elapsedRealtimeMillis milliseconds since boot + */ + public ActivityRecognitionResult(DetectedActivity activity, long time, long elapsedRealtimeMillis) { + this(Collections.singletonList(activity), time, elapsedRealtimeMillis); + } + + private ActivityRecognitionResult(List probableActivities, long time, long elapsedRealtimeMillis, Bundle extras) { + if (probableActivities == null || probableActivities.isEmpty()) + throw new IllegalArgumentException("Must have at least 1 detected activity"); + if (time <= 0 || elapsedRealtimeMillis <= 0) + throw new IllegalArgumentException("Must set times"); + this.probableActivities = probableActivities; + this.time = time; + this.elapsedRealtimeMillis = elapsedRealtimeMillis; + this.extras = extras; + } + + /** + * Extracts the ActivityRecognitionResult from an Intent. + *

+ * This is a utility function which extracts the ActivityRecognitionResult from the extras of + * an Intent that was sent from the activity detection service. + * + * @return an ActivityRecognitionResult, or {@code null} if the intent doesn't contain an + * ActivityRecognitionResult. + */ + public static ActivityRecognitionResult extractResult(Intent intent) { + if (intent.hasExtra(EXTRA_ACTIVITY_RESULT_LIST)) { + intent.setExtrasClassLoader(ActivityRecognitionResult.class.getClassLoader()); + List list = intent.getParcelableArrayListExtra(EXTRA_ACTIVITY_RESULT_LIST); + if (list != null && !list.isEmpty()) + return list.get(list.size() - 1); + } + if (intent.hasExtra(EXTRA_ACTIVITY_RESULT)) { + Bundle extras = intent.getExtras(); + extras.setClassLoader(ActivityRecognitionResult.class.getClassLoader()); + Object res = extras.get(EXTRA_ACTIVITY_RESULT); + if (res instanceof ActivityRecognitionResult) + return (ActivityRecognitionResult) res; + if (res instanceof byte[]) + return SafeParcelUtil.fromByteArray((byte[]) res, CREATOR); + } + return null; + } + + /** + * Returns the confidence of the given activity type. + */ + public int getActivityConfidence(int activityType) { + for (DetectedActivity activity : probableActivities) { + if (activity.getType() == activityType) + return activity.getConfidence(); + } + return 0; + } + + /** + * Returns the elapsed real time of this detection in milliseconds since boot, including time + * spent in sleep as obtained by SystemClock.elapsedRealtime(). + */ + public long getElapsedRealtimeMillis() { + return elapsedRealtimeMillis; + } + + /** + * Returns the most probable activity of the user. + */ + public DetectedActivity getMostProbableActivity() { + return probableActivities.get(0); + } + + /** + * Returns the list of activities that where detected with the confidence value associated with + * each activity. The activities are sorted by most probable activity first. + *

+ * The sum of the confidences of all detected activities this method returns does not have to + * be <= 100 since some activities are not mutually exclusive (for example, you can be walking + * while in a bus) and some activities are hierarchical (ON_FOOT is a generalization of WALKING + * and RUNNING). + */ + public List getProbableActivities() { + return probableActivities; + } + + /** + * Returns the UTC time of this detection, in milliseconds since January 1, 1970. + */ + public long getTime() { + return time; + } + + /** + * Returns true if an Intent contains an ActivityRecognitionResult. + *

+ * This is a utility function that can be called from inside an intent receiver to make sure + * the received intent is from activity recognition. + * + * @return true if the intent contains an ActivityRecognitionResult, false otherwise or the given intent is null + */ + public static boolean hasResult(Intent intent) { + if (intent == null) return false; + if (intent.hasExtra(EXTRA_ACTIVITY_RESULT)) return true; + intent.setExtrasClassLoader(ActivityRecognitionResult.class.getClassLoader()); + List list = intent.getParcelableArrayListExtra(EXTRA_ACTIVITY_RESULT_LIST); + return list != null && !list.isEmpty(); + } + + @Override + public String toString() { + return "ActivityRecognitionResult [probableActivities=" + probableActivities + ", timeMillis" + time + ", elapsedRealtimeMillis=" + elapsedRealtimeMillis + "]"; + } + public static final Creator CREATOR = new AutoCreator(ActivityRecognitionResult.class); } diff --git a/play-services-location-api/src/main/java/com/google/android/gms/location/DetectedActivity.java b/play-services-location-api/src/main/java/com/google/android/gms/location/DetectedActivity.java new file mode 100644 index 00000000..36744730 --- /dev/null +++ b/play-services-location-api/src/main/java/com/google/android/gms/location/DetectedActivity.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2017 microG Project Team + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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 com.google.android.gms.location; + +import org.microg.gms.common.PublicApi; +import org.microg.safeparcel.AutoSafeParcelable; +import org.microg.safeparcel.SafeParceled; + +/** + * The detected activity of the device with an an associated confidence. See ActivityRecognitionApi + * for details on how to obtain a DetectedActivity. + */ +@PublicApi +public class DetectedActivity extends AutoSafeParcelable { + + /** + * The device is in a vehicle, such as a car. + */ + public static final int IN_VEHICLE = 0; + + /** + * The device is on a bicycle. + */ + public static final int ON_BICYCLE = 1; + + /** + * The device is on a user who is walking or running. + */ + public static final int ON_FOOT = 2; + + /** + * The device is on a user who is running. This is a sub-activity of ON_FOOT. + */ + public static final int RUNNING = 8; + + /** + * The device is still (not moving). + */ + public static final int STILL = 3; + + /** + * The device angle relative to gravity changed significantly. This often occurs when a device + * is picked up from a desk or a user who is sitting stands up. + */ + public static final int TILTING = 5; + + /** + * Unable to detect the current activity. + */ + public static final int UNKNOWN = 4; + + /** + * The device is on a user who is walking. This is a sub-activity of ON_FOOT. + */ + public static final int WALKING = 7; + + @SafeParceled(1000) + private int versionCode = 1; + + @SafeParceled(1) + private int type; + + @SafeParceled(2) + private int confidence; + + private DetectedActivity() { + } + + + /** + * Constructs a DetectedActivity. + * + * @param activityType the activity that was detected. + * @param confidence value from 0 to 100 indicating how likely it is that the user is performing this activity. + */ + public DetectedActivity(int activityType, int confidence) { + this.type = activityType; + this.confidence = confidence; + } + + /** + * Returns a value from 0 to 100 indicating the likelihood that the user is performing this + * activity. + *

+ * The larger the value, the more consistent the data used to perform the classification is + * with the detected activity. + *

+ * This value will be <= 100. It means that larger values indicate that it's likely that the + * detected activity is correct, while a value of <= 50 indicates that there may be another + * activity that is just as or more likely. + *

+ * Multiple activities may have high confidence values. For example, the ON_FOOT may have a + * confidence of 100 while the RUNNING activity may have a confidence of 95. The sum of the + * confidences of all detected activities for a classification does not have to be <= 100 since + * some activities are not mutually exclusive (for example, you can be walking while in a bus) + * and some activities are hierarchical (ON_FOOT is a generalization of WALKING and RUNNING). + */ + public int getConfidence() { + return confidence; + } + + /** + * Returns the type of activity that was detected. + */ + public int getType() { + return type; + } + + @Override + public String toString() { + return "DetectedActivity [type=" + typeToString(getType()) + ", confidence=" + getConfidence() + "]"; + } + + @PublicApi(exclude = true) + public static String typeToString(int type) { + switch (type) { + case 0: + return "IN_VEHICLE"; + case 1: + return "ON_BICYCLE"; + case 2: + return "ON_FOOT"; + case 3: + return "STILL"; + case 4: + return "UNKNOWN"; + case 5: + return "TILTING"; + case 6: + default: + return Integer.toString(type); + case 7: + return "WALKING"; + case 8: + return "RUNNING"; + } + } + + public static final Creator CREATOR = new AutoCreator(DetectedActivity.class); +} diff --git a/play-services-location-api/src/main/java/com/google/android/gms/location/Geofence.java b/play-services-location-api/src/main/java/com/google/android/gms/location/Geofence.java index c48aef56..9f588789 100644 --- a/play-services-location-api/src/main/java/com/google/android/gms/location/Geofence.java +++ b/play-services-location-api/src/main/java/com/google/android/gms/location/Geofence.java @@ -16,9 +16,157 @@ package com.google.android.gms.location; -import org.microg.safeparcel.AutoSafeParcelable; +import android.os.SystemClock; -public class Geofence extends AutoSafeParcelable { +import com.google.android.gms.location.internal.ParcelableGeofence; - public static Creator CREATOR = new AutoCreator(Geofence.class); +/** + * Represents a geographical region, also known as a geofence. Geofences can be monitored by + * geofencer service. And when the user crosses the boundary of a geofence, an alert will be + * generated. + */ +public interface Geofence { + int GEOFENCE_TRANSITION_DWELL = 4; + + /** + * The transition type indicating that the user enters the geofence(s). + */ + int GEOFENCE_TRANSITION_ENTER = 1; + + /** + * The transition type indicating that the user exits the geofence(s). + */ + int GEOFENCE_TRANSITION_EXIT = 2; + + /** + * Expiration value that indicates the geofence should never expire. + */ + long NEVER_EXPIRE = -1L; + + /** + * Returns the request ID of this geofence. The request ID is a string to identify this geofence + * inside your application. When two geofences with the same requestId are monitored, the new + * one will replace the old one regardless the geographical region these two geofences + * represent. + */ + String getRequestId(); + + /** + * A builder that builds {@link Geofence}. + */ + class Builder { + private int regionType = -1; + private double latitude; + private double longitude; + private float radius; + private long expirationTime = Long.MIN_VALUE; + private int loiteringDelay = -1; + private int notificationResponsiveness; + private String requestId; + private int transitionTypes; + + /** + * Creates a geofence object. + * + * @throws IllegalArgumentException if any parameters are not set or out of range + */ + public Geofence build() throws IllegalArgumentException { + if (requestId == null) { + throw new IllegalArgumentException("Request ID not set."); + } else if (transitionTypes == 0) { + throw new IllegalArgumentException("Transition types not set."); + } else if ((transitionTypes & GEOFENCE_TRANSITION_DWELL) > 0 && loiteringDelay < 0) { + throw new IllegalArgumentException("Non-negative loitering delay needs to be set when transition types include GEOFENCE_TRANSITION_DWELLING."); + } else if (expirationTime == Long.MIN_VALUE) { + throw new IllegalArgumentException("Expiration not set."); + } else if (regionType == -1) { + throw new IllegalArgumentException("Geofence region not set."); + } else if (notificationResponsiveness < 0) { + throw new IllegalArgumentException("Notification responsiveness should be nonnegative."); + } else { + return new ParcelableGeofence(requestId, expirationTime, regionType, latitude, longitude, radius, transitionTypes, notificationResponsiveness, loiteringDelay); + } + } + + /** + * Sets the region of this geofence. The geofence represents a circular area on a flat, horizontal plane. + * + * @param latitude latitude in degrees, between -90 and +90 inclusive + * @param longitude longitude in degrees, between -180 and +180 inclusive + * @param radius radius in meters + */ + public Builder setCircularRegion(double latitude, double longitude, float radius) { + this.regionType = 1; + this.latitude = latitude; + this.longitude = longitude; + this.radius = radius; + return this; + } + + /** + * Sets the expiration duration of geofence. This geofence will be removed automatically + * after this period of time. + * + * @param durationMillis time for this proximity alert, in milliseconds, or {@link #NEVER_EXPIRE} + * to indicate no expiration. When positive, this geofence will be + * removed automatically after this amount of time. + */ + public Builder setExpirationDuration(long durationMillis) { + if (durationMillis < 0) { + expirationTime = -1; + } else { + expirationTime = SystemClock.elapsedRealtime() + durationMillis; + } + return this; + } + + public Builder setLoiteringDelay(int loiteringDelayMs) { + this.loiteringDelay = loiteringDelayMs; + return this; + } + + /** + * Sets the best-effort notification responsiveness of the geofence. Defaults to 0. Setting + * a big responsiveness value, for example 5 minutes, can save power significantly. However, + * setting a very small responsiveness value, for example 5 seconds, doesn't necessarily + * mean you will get notified right after the user enters or exits a geofence: internally, + * the geofence might adjust the responsiveness value to save power when needed. + * + * @param notificationResponsivenessMs notificationResponsivenessMs (milliseconds) defines + * the best-effort description of how soon should the + * callback be called when the transition associated + * with the Geofence is triggered. For instance, if set + * to 300000 milliseconds the callback will be called 5 + * minutes within entering or exiting the geofence. + */ + public Builder setNotificationResponsiveness(int notificationResponsivenessMs) { + this.notificationResponsiveness = notificationResponsivenessMs; + return this; + } + + /** + * Sets the request ID of the geofence. Request ID is a string to identify this geofence + * inside your application. When two geofences with the same requestId are monitored, the + * new one will replace the old one regardless the geographical region these two geofences + * represent. + * + * @param requestId the request ID. The length of the string can be up to 100 characters. + */ + public Builder setRequestId(String requestId) { + this.requestId = requestId; + return this; + } + + /** + * Sets the transition types of interest. Alerts are only generated for the given transition + * types. + * + * @param transitionTypes geofence transition types of interest, as a bitwise-OR of + * GEOFENCE_TRANSITION_ flags. + */ + public Builder setTransitionTypes(int transitionTypes) { + this.transitionTypes = transitionTypes; + return this; + } + } } diff --git a/play-services-location-api/src/main/java/com/google/android/gms/location/GeofenceStatusCodes.java b/play-services-location-api/src/main/java/com/google/android/gms/location/GeofenceStatusCodes.java new file mode 100644 index 00000000..8733e4cb --- /dev/null +++ b/play-services-location-api/src/main/java/com/google/android/gms/location/GeofenceStatusCodes.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2017 microG Project Team + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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 com.google.android.gms.location; + +import com.google.android.gms.common.api.CommonStatusCodes; + +public class GeofenceStatusCodes extends CommonStatusCodes { + /** + * Geofence service is not available now. Typically this is because the user turned off + * location access in settings > location access. + */ + public static final int GEOFENCE_NOT_AVAILABLE = 1000; + + /** + * Your app has registered more than 100 geofences. Remove unused ones before adding new + * geofences. + */ + public static final int GEOFENCE_TOO_MANY_GEOFENCES = 1001; + + /** + * You have provided more than 5 different PendingIntents to the addGeofences(GoogleApiClient, + * GeofencingRequest, PendingIntent) call. + */ + public static final int GEOFENCE_TOO_MANY_PENDING_INTENTS = 1002; + + /** + * Returns an untranslated debug (not user-friendly!) string based on the current status code. + */ + public static String getStatusCodeString(int statusCode) { + switch (statusCode) { + case GEOFENCE_NOT_AVAILABLE: + return "GEOFENCE_NOT_AVAILABLE"; + case GEOFENCE_TOO_MANY_GEOFENCES: + return "GEOFENCE_TOO_MANY_GEOFENCES"; + case GEOFENCE_TOO_MANY_PENDING_INTENTS: + return "GEOFENCE_TOO_MANY_PENDING_INTENTS"; + default: + return CommonStatusCodes.getStatusCodeString(statusCode); + } + } +} diff --git a/play-services-location-api/src/main/java/com/google/android/gms/location/LocationAvailability.java b/play-services-location-api/src/main/java/com/google/android/gms/location/LocationAvailability.java index f2f70201..79ea84f8 100644 --- a/play-services-location-api/src/main/java/com/google/android/gms/location/LocationAvailability.java +++ b/play-services-location-api/src/main/java/com/google/android/gms/location/LocationAvailability.java @@ -27,9 +27,9 @@ import java.util.Arrays; /** * Status on the availability of location data. *

- * Delivered from {@link LocationCallback} registered via {@link FusedLocationProviderApi#requestLocationUpdates(com.google.android.gms.common.api.GoogleApiClient, LocationRequest, LocationCallback, android.os.Looper) - * or from a PendingIntent registered via {@link FusedLocationProviderApi#requestLocationUpdates(com.google.android.gms.common.api.GoogleApiClient, LocationRequest, android.app.PendingIntent)}. - * It is also available on demand via {@link FusedLocationProviderApi#getLocationAvailability(com.google.android.gms.common.api.GoogleApiClient)}. + * Delivered from LocationCallback registered via FusedLocationProviderApi#requestLocationUpdates(GoogleApiClient, LocationRequest, LocationCallback, Looper) + * or from a PendingIntent registered via FusedLocationProviderApi#requestLocationUpdates(GoogleApiClient, LocationRequest, PendingIntent). + * It is also available on demand via FusedLocationProviderApi#getLocationAvailability(GoogleApiClient). */ @PublicApi public class LocationAvailability extends AutoSafeParcelable { diff --git a/play-services-location-api/src/main/java/com/google/android/gms/location/LocationSettingsRequest.java b/play-services-location-api/src/main/java/com/google/android/gms/location/LocationSettingsRequest.java index 3d5aa5a9..3f8823a5 100644 --- a/play-services-location-api/src/main/java/com/google/android/gms/location/LocationSettingsRequest.java +++ b/play-services-location-api/src/main/java/com/google/android/gms/location/LocationSettingsRequest.java @@ -20,6 +20,8 @@ import org.microg.gms.common.PublicApi; import org.microg.safeparcel.AutoSafeParcelable; import org.microg.safeparcel.SafeParceled; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; @PublicApi @@ -38,5 +40,70 @@ public class LocationSettingsRequest extends AutoSafeParcelable { @PublicApi(exclude = true) public boolean needBle; + private LocationSettingsRequest() { + } + + private LocationSettingsRequest(List requests, boolean alwaysShow, boolean needBle) { + this.requests = requests; + this.alwaysShow = alwaysShow; + this.needBle = needBle; + } + + /** + * A builder that builds {@link LocationSettingsRequest}. + */ + public static class Builder { + private List requests = new ArrayList(); + private boolean alwaysShow = false; + private boolean needBle = false; + + /** + * Adds a collection of {@link LocationRequest}s that the client is interested in. Settings + * will be checked for optimal performance of all {@link LocationRequest}s. + */ + public Builder addAllLocationRequests(Collection requests) { + this.requests.addAll(requests); + return this; + } + + /** + * Adds one {@link LocationRequest} that the client is interested in. Settings will be + * checked for optimal performance of all {@link LocationRequest}s. + */ + public Builder addLocationRequest(LocationRequest request) { + requests.add(request); + return this; + } + + /** + * Creates a LocationSettingsRequest that can be used with SettingsApi. + */ + public LocationSettingsRequest build() { + return new LocationSettingsRequest(requests, alwaysShow, needBle); + } + + /** + * Whether or not location is required by the calling app in order to continue. Set this to + * true if location is required to continue and false if having location provides better + * results, but is not required. This changes the wording/appearance of the dialog + * accordingly. + */ + public Builder setAlwaysShow(boolean show) { + alwaysShow = show; + return this; + } + + /** + * Sets whether the client wants BLE scan to be enabled. When this flag is set to true, if + * the platform supports BLE scan mode and Bluetooth is off, the dialog will prompt the + * user to enable BLE scan. If the platform doesn't support BLE scan mode, the dialog will + * prompt to enable Bluetooth. + */ + public Builder setNeedBle(boolean needBle) { + this.needBle = needBle; + return this; + } + } + public static final Creator CREATOR = new AutoCreator(LocationSettingsRequest.class); } diff --git a/play-services-location-api/src/main/java/com/google/android/gms/location/LocationSettingsResult.java b/play-services-location-api/src/main/java/com/google/android/gms/location/LocationSettingsResult.java index 1ca160ea..d49fc209 100644 --- a/play-services-location-api/src/main/java/com/google/android/gms/location/LocationSettingsResult.java +++ b/play-services-location-api/src/main/java/com/google/android/gms/location/LocationSettingsResult.java @@ -23,6 +23,15 @@ import org.microg.gms.common.PublicApi; import org.microg.safeparcel.AutoSafeParcelable; import org.microg.safeparcel.SafeParceled; +/** + * Result of checking settings via checkLocationSettings(GoogleApiClient, LocationSettingsRequest), + * indicates whether a dialog should be shown to ask the user's consent to change their settings. + * The method getStatus() can be be used to confirm if the request was successful. If the current + * location settings don't satisfy the app's requirements and the user has permission to change the + * settings, the app could use startResolutionForResult(Activity, int) to start an intent to show a + * dialog, asking for user's consent to change the settings. The current location settings states + * can be accessed via getLocationSettingsStates(). See LocationSettingsResult for more details. + */ @PublicApi public class LocationSettingsResult extends AutoSafeParcelable implements Result { @@ -36,6 +45,9 @@ public class LocationSettingsResult extends AutoSafeParcelable implements Result private LocationSettingsStates settings; + /** + * Retrieves the location settings states. + */ public LocationSettingsStates getLocationSettingsStates() { return settings; } diff --git a/play-services-location-api/src/main/java/com/google/android/gms/location/LocationSettingsStates.java b/play-services-location-api/src/main/java/com/google/android/gms/location/LocationSettingsStates.java index 5d9305d3..b592a257 100644 --- a/play-services-location-api/src/main/java/com/google/android/gms/location/LocationSettingsStates.java +++ b/play-services-location-api/src/main/java/com/google/android/gms/location/LocationSettingsStates.java @@ -20,6 +20,9 @@ import org.microg.gms.common.PublicApi; import org.microg.safeparcel.AutoSafeParcelable; import org.microg.safeparcel.SafeParceled; +/** + * Stores the current states of all location-related settings. + */ @PublicApi public class LocationSettingsStates extends AutoSafeParcelable { diff --git a/play-services-location-api/src/main/java/com/google/android/gms/location/LocationSettingsStatusCodes.java b/play-services-location-api/src/main/java/com/google/android/gms/location/LocationSettingsStatusCodes.java new file mode 100644 index 00000000..028de68c --- /dev/null +++ b/play-services-location-api/src/main/java/com/google/android/gms/location/LocationSettingsStatusCodes.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2017 microG Project Team + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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 com.google.android.gms.location; + +import com.google.android.gms.common.api.CommonStatusCodes; +import com.google.android.gms.common.api.Status; + +import org.microg.gms.common.PublicApi; + +/** + * Location settings specific status codes, for use in {@link Status#getStatusCode()} + */ +@PublicApi +public class LocationSettingsStatusCodes extends CommonStatusCodes { + /** + * Location settings can't be changed to meet the requirements, no dialog pops up + */ + public static final int SETTINGS_CHANGE_UNAVAILABLE = 8502; +} diff --git a/play-services-location-api/src/main/java/com/google/android/gms/location/internal/ParcelableGeofence.java b/play-services-location-api/src/main/java/com/google/android/gms/location/internal/ParcelableGeofence.java new file mode 100644 index 00000000..3abc611c --- /dev/null +++ b/play-services-location-api/src/main/java/com/google/android/gms/location/internal/ParcelableGeofence.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2017 microG Project Team + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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 com.google.android.gms.location.internal; + +import com.google.android.gms.location.Geofence; + +import org.microg.safeparcel.AutoSafeParcelable; +import org.microg.safeparcel.SafeParceled; + +public class ParcelableGeofence extends AutoSafeParcelable implements Geofence { + + @SafeParceled(1000) + private int versionCode = 1; + + @SafeParceled(1) + public String requestId; + + @SafeParceled(2) + public long expirationTime; + + @SafeParceled(3) + public int regionType; + + @SafeParceled(4) + public double latitude; + + @SafeParceled(5) + public double longitude; + + @SafeParceled(6) + public float radius; + + @SafeParceled(7) + public int transitionType; + + @SafeParceled(8) + public int notificationResponsiveness; + + @SafeParceled(9) + public int loiteringDelay; + + private ParcelableGeofence() { + } + + public ParcelableGeofence(String requestId, long expirationTime, int regionType, double latitude, double longitude, float radius, int transitionType, int notificationResponsiveness, int loiteringDelay) { + this.requestId = requestId; + this.expirationTime = expirationTime; + this.regionType = regionType; + this.latitude = latitude; + this.longitude = longitude; + this.radius = radius; + this.transitionType = transitionType; + this.notificationResponsiveness = notificationResponsiveness; + this.loiteringDelay = loiteringDelay; + } + + @Override + public String getRequestId() { + return requestId; + } + + public static final Creator CREATOR = new AutoCreator(ParcelableGeofence.class); +}