CREATOR = findCreator(LocationSettingsRequest.class);
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+}
diff --git a/play-services-location/src/main/java/com/google/android/gms/location/LocationSettingsResponse.java b/play-services-location/src/main/java/com/google/android/gms/location/LocationSettingsResponse.java
new file mode 100644
index 00000000..dbe22a08
--- /dev/null
+++ b/play-services-location/src/main/java/com/google/android/gms/location/LocationSettingsResponse.java
@@ -0,0 +1,41 @@
+/*
+ * SPDX-FileCopyrightText: 2023 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ * Notice: Portions of this file are reproduced from work created and shared by Google and used
+ * according to terms described in the Creative Commons 4.0 Attribution License.
+ * See https://developers.google.com/readme/policies for details.
+ */
+
+package com.google.android.gms.location;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.ResolvableApiException;
+import com.google.android.gms.common.api.Response;
+import com.google.android.gms.tasks.Task;
+import org.microg.gms.common.Hide;
+import org.microg.gms.common.PublicApi;
+
+/**
+ * Successful response of checking settings via {@link SettingsApi#checkLocationSettings(GoogleApiClient, LocationSettingsRequest)}.
+ *
+ * If a {@link Task} with this response type fails, it will receive a {@link ResolvableApiException} which may be able to resolve the failure.
+ * See {@link SettingsClient} for more details.
+ *
+ * The current location settings states can be accessed via {@link #getLocationSettingsStates()}. See {@link LocationSettingsStates} for more details.
+ */
+public class LocationSettingsResponse extends Response {
+ /**
+ * Retrieves the location settings states.
+ */
+ @Nullable
+ public LocationSettingsStates getLocationSettingsStates() {
+ return getResult().getLocationSettingsStates();
+ }
+
+ @Hide
+ public LocationSettingsResponse(@NonNull LocationSettingsResult result) {
+ super(result);
+ }
+}
diff --git a/play-services-location/src/main/java/com/google/android/gms/location/LocationSettingsResult.java b/play-services-location/src/main/java/com/google/android/gms/location/LocationSettingsResult.java
new file mode 100644
index 00000000..62e00c26
--- /dev/null
+++ b/play-services-location/src/main/java/com/google/android/gms/location/LocationSettingsResult.java
@@ -0,0 +1,86 @@
+/*
+ * SPDX-FileCopyrightText: 2015 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ * Notice: Portions of this file are reproduced from work created and shared by Google and used
+ * according to terms described in the Creative Commons 4.0 Attribution License.
+ * See https://developers.google.com/readme/policies for details.
+ */
+
+package com.google.android.gms.location;
+
+import android.app.Activity;
+import android.os.Parcel;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.Result;
+import com.google.android.gms.common.api.Status;
+
+import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
+import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
+import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
+import org.microg.gms.common.Hide;
+import org.microg.gms.common.PublicApi;
+
+/**
+ * Result of checking settings via {@link SettingsApi#checkLocationSettings(GoogleApiClient, LocationSettingsRequest)},
+ * indicates whether a dialog should be shown to ask the user's consent to change their
+ * settings.
+ *
+ * The method {@link #getStatus()} can 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
+ * {@link Status#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 {@link #getLocationSettingsStates()}. See
+ * {@link LocationSettingsStates} for more details.
+ */
+@PublicApi
+@SafeParcelable.Class
+public class LocationSettingsResult extends AbstractSafeParcelable implements Result {
+
+ @Field(1000)
+ int versionCode = 1;
+
+ @Field(1)
+ @NonNull
+ private final Status status;
+
+ @Field(2)
+ @Nullable
+ private final LocationSettingsStates settings;
+
+
+ /**
+ * Retrieves the location settings states.
+ */
+ @Nullable
+ public LocationSettingsStates getLocationSettingsStates() {
+ return settings;
+ }
+
+ @Override
+ @NonNull
+ public Status getStatus() {
+ return status;
+ }
+
+ @Hide
+ @Constructor
+ public LocationSettingsResult(@Param(1) @NonNull Status status, @Param(2) @Nullable LocationSettingsStates settings) {
+ this.settings = settings;
+ this.status = status;
+ }
+
+ @Hide
+ public LocationSettingsResult(@NonNull Status status) {
+ this(status, null);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(LocationSettingsResult.class);
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+}
diff --git a/play-services-location/src/main/java/com/google/android/gms/location/LocationSettingsStates.java b/play-services-location/src/main/java/com/google/android/gms/location/LocationSettingsStates.java
new file mode 100644
index 00000000..e2f6d02b
--- /dev/null
+++ b/play-services-location/src/main/java/com/google/android/gms/location/LocationSettingsStates.java
@@ -0,0 +1,138 @@
+/*
+ * SPDX-FileCopyrightText: 2015 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ * Notice: Portions of this file are reproduced from work created and shared by Google and used
+ * according to terms described in the Creative Commons 4.0 Attribution License.
+ * See https://developers.google.com/readme/policies for details.
+ */
+
+package com.google.android.gms.location;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Parcel;
+import androidx.annotation.NonNull;
+import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
+import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
+import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
+import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer;
+import org.microg.gms.common.PublicApi;
+
+/**
+ * Stores the current states of all location-related settings.
+ */
+@PublicApi
+@SafeParcelable.Class
+public class LocationSettingsStates extends AbstractSafeParcelable {
+
+ @Field(1000)
+ int versionCode = 2;
+
+ @Field(1)
+ private final boolean gpsUsable;
+
+ @Field(2)
+ private final boolean networkLocationUsable;
+
+ @Field(3)
+ private final boolean bleUsable;
+
+ @Field(4)
+ private final boolean gpsPresent;
+
+ @Field(5)
+ private final boolean networkLocationPresent;
+
+ @Field(6)
+ private final boolean blePresent;
+
+ /**
+ * Whether BLE is present on the device.
+ */
+ public boolean isBlePresent() {
+ return blePresent;
+ }
+
+ /**
+ * Whether BLE is enabled and is usable by the app.
+ */
+ public boolean isBleUsable() {
+ return bleUsable;
+ }
+
+ /**
+ * Whether GPS provider is present on the device.
+ */
+ public boolean isGpsPresent() {
+ return gpsPresent;
+ }
+
+ /**
+ * Whether GPS provider is enabled and is usable by the app.
+ */
+ public boolean isGpsUsable() {
+ return gpsUsable;
+ }
+
+ /**
+ * Whether location is present on the device.
+ *
+ * This method returns true when either GPS or network location provider is present.
+ */
+ public boolean isLocationPresent() {
+ return isGpsPresent() || isNetworkLocationPresent();
+ }
+
+ /**
+ * Whether location is enabled and is usable by the app.
+ *
+ * This method returns true when either GPS or network location provider is usable.
+ */
+ public boolean isLocationUsable() {
+ return isGpsUsable() || isNetworkLocationUsable();
+ }
+
+ /**
+ * Whether network location provider is present on the device.
+ */
+ public boolean isNetworkLocationPresent() {
+ return networkLocationPresent;
+ }
+
+ /**
+ * Whether network location provider is enabled and usable by the app.
+ */
+ public boolean isNetworkLocationUsable() {
+ return networkLocationUsable;
+ }
+
+ @Constructor
+ public LocationSettingsStates(@Param(1) boolean gpsUsable, @Param(2) boolean networkLocationUsable, @Param(3) boolean bleUsable, @Param(4) boolean gpsPresent, @Param(5) boolean networkLocationPresent, @Param(6) boolean blePresent) {
+ this.gpsUsable = gpsUsable;
+ this.networkLocationUsable = networkLocationUsable;
+ this.bleUsable = bleUsable;
+ this.gpsPresent = gpsPresent;
+ this.networkLocationPresent = networkLocationPresent;
+ this.blePresent = blePresent;
+ }
+
+ /**
+ * Retrieves the location settings states from the intent extras. When the location settings dialog finishes, you can use this
+ * method to retrieve the current location settings states from the intent in your
+ * {@link Activity#onActivityResult(int, int, Intent)}.
+ */
+ public static LocationSettingsStates fromIntent(Intent intent) {
+ byte[] bytes = intent.getByteArrayExtra(EXTRA_NAME);
+ if (bytes == null) return null;
+ return SafeParcelableSerializer.deserializeFromBytes(bytes, CREATOR);
+ }
+
+ public static final SafeParcelableCreatorAndWriter CREATOR = findCreator(LocationSettingsStates.class);
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ CREATOR.writeToParcel(this, dest, flags);
+ }
+
+ private static final String EXTRA_NAME = "com.google.android.gms.location.LOCATION_SETTINGS_STATES";
+}
diff --git a/play-services-location/src/main/java/com/google/android/gms/location/SettingsClient.java b/play-services-location/src/main/java/com/google/android/gms/location/SettingsClient.java
new file mode 100644
index 00000000..4c485d72
--- /dev/null
+++ b/play-services-location/src/main/java/com/google/android/gms/location/SettingsClient.java
@@ -0,0 +1,44 @@
+/*
+ * SPDX-FileCopyrightText: 2022 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ * Notice: Portions of this file are reproduced from work created and shared by Google and used
+ * according to terms described in the Creative Commons 4.0 Attribution License.
+ * See https://developers.google.com/readme/policies for details.
+ */
+
+package com.google.android.gms.location;
+
+import android.location.LocationManager;
+import android.provider.Settings;
+import com.google.android.gms.common.api.Api;
+import com.google.android.gms.common.api.HasApiKey;
+import com.google.android.gms.tasks.Task;
+
+/**
+ * The main entry point for interacting with the location settings-enabler APIs.
+ *
+ * This API makes it easy for an app to ensure that the device's system settings are properly configured for the app's
+ * location needs.
+ */
+public interface SettingsClient extends HasApiKey {
+ /**
+ * Checks if the relevant system settings are enabled on the device to carry out the desired location requests.
+ *
+ * @param locationSettingsRequest an object that contains all the location requirements that the client is interested in.
+ */
+ Task checkLocationSettings(LocationSettingsRequest locationSettingsRequest);
+
+ /**
+ * Returns true if the Google Location Accuracy setting is currently enabled. This setting is required for Fused Location
+ * Provider APIs to be able to generate network (wifi, cell, etc) based locations. If Google Play services is chosen as the
+ * platform {@link LocationManager#NETWORK_PROVIDER} (this is the case on all GMS compliant devices, which constitute the
+ * vast majority of the Android ecosystem), then this setting is also required for the platform
+ * {@link LocationManager#NETWORK_PROVIDER} to be enabled.
+ *
+ * On Android P and above devices, the Google Location Accuracy setting may be found under location settings. Below
+ * Android P, Google Location Accuracy is tied to the device location mode - it will be enabled if the device is in
+ * {@link Settings.Secure#LOCATION_MODE_BATTERY_SAVING} or {@link Settings.Secure#LOCATION_MODE_HIGH_ACCURACY}, and
+ * disabled in {@link Settings.Secure#LOCATION_MODE_SENSORS_ONLY}.
+ */
+ Task isGoogleLocationAccuracyEnabled();
+}
diff --git a/play-services-location/src/main/java/org/microg/gms/location/SettingsClientImpl.java b/play-services-location/src/main/java/org/microg/gms/location/SettingsClientImpl.java
new file mode 100644
index 00000000..f8d89125
--- /dev/null
+++ b/play-services-location/src/main/java/org/microg/gms/location/SettingsClientImpl.java
@@ -0,0 +1,39 @@
+/*
+ * SPDX-FileCopyrightText: 2022 microG Project Team
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package org.microg.gms.location;
+
+import android.content.Context;
+
+import android.os.RemoteException;
+import com.google.android.gms.common.api.Api;
+import com.google.android.gms.common.api.GoogleApi;
+import com.google.android.gms.location.*;
+import com.google.android.gms.location.internal.ISettingsCallbacks;
+import com.google.android.gms.tasks.Task;
+import com.google.android.gms.tasks.TaskCompletionSource;
+import com.google.android.gms.tasks.Tasks;
+import org.microg.gms.common.api.PendingGoogleApiCall;
+
+public class SettingsClientImpl extends GoogleApi implements SettingsClient {
+ public SettingsClientImpl(Context context) {
+ super(context, LocationServices.API);
+ }
+
+ @Override
+ public Task checkLocationSettings(LocationSettingsRequest locationSettingsRequest) {
+ return scheduleTask((PendingGoogleApiCall) (client, completionSource) -> client.getServiceInterface().requestLocationSettingsDialog(locationSettingsRequest, new ISettingsCallbacks.Stub() {
+ @Override
+ public void onLocationSettingsResult(LocationSettingsResult result) {
+ completionSource.setResult(new LocationSettingsResponse(result));
+ }
+ }, null));
+ }
+
+ @Override
+ public Task isGoogleLocationAccuracyEnabled() {
+ return Tasks.forResult(true); // TODO
+ }
+}