mirror of
https://github.com/TeamVanced/VancedMicroG
synced 2024-12-30 22:45:47 +01:00
Update location service
This commit is contained in:
parent
d593de25ef
commit
0bdcb1319b
@ -5,7 +5,7 @@
|
||||
|
||||
buildscript {
|
||||
ext.cronetVersion = '91.0.4472.120.1'
|
||||
ext.nlpVersion = '2.0-alpha6'
|
||||
ext.nlpVersion = '2.0-alpha7'
|
||||
ext.safeParcelVersion = '1.7.0'
|
||||
ext.wearableVersion = '0.1.1'
|
||||
|
||||
|
@ -0,0 +1,3 @@
|
||||
package com.google.android.gms.location;
|
||||
|
||||
parcelable DeviceOrientation;
|
@ -0,0 +1,7 @@
|
||||
package com.google.android.gms.location;
|
||||
|
||||
import com.google.android.gms.location.DeviceOrientation;
|
||||
|
||||
interface IDeviceOrientationListener {
|
||||
void onDeviceOrientationChanged(in DeviceOrientation deviceOrientation);
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
package com.google.android.gms.location.internal;
|
||||
|
||||
parcelable DeviceOrientationRequestUpdateData;
|
@ -5,8 +5,10 @@ import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.common.api.internal.IStatusCallback;
|
||||
import com.google.android.gms.location.places.AutocompleteFilter;
|
||||
import com.google.android.gms.location.places.internal.IPlacesCallbacks;
|
||||
import com.google.android.gms.location.internal.DeviceOrientationRequestUpdateData;
|
||||
import com.google.android.gms.location.internal.ISettingsCallbacks;
|
||||
import com.google.android.gms.location.internal.LocationRequestInternal;
|
||||
import com.google.android.gms.location.internal.LocationRequestUpdateData;
|
||||
@ -36,17 +38,19 @@ interface IGoogleLocationManagerService {
|
||||
void removeGeofencesByIntent(in PendingIntent pendingIntent, IGeofencerCallbacks callbacks, String packageName) = 1;
|
||||
void removeGeofencesById(in String[] geofenceRequestIds, IGeofencerCallbacks callbacks, String packageName) = 2;
|
||||
void removeAllGeofences(IGeofencerCallbacks callbacks, String packageName) = 3;
|
||||
// void removeGeofences(in RemoveGeofencingRequest request, IGeofencerCallbacks callback) = 73;
|
||||
|
||||
void requestActivityUpdates(long detectionIntervalMillis, boolean alwaysTrue, in PendingIntent callbackIntent) = 4;
|
||||
void removeActivityUpdates(in PendingIntent callbackIntent) = 5;
|
||||
ActivityRecognitionResult getLastActivity(String packageName) = 63;
|
||||
Status iglms65(in PendingIntent pendingIntent) = 64;
|
||||
Status iglms66(in PendingIntent pendingIntent) = 65;
|
||||
|
||||
Status requestGestureUpdates(in GestureRequest request, in PendingIntent pendingIntent) = 59;
|
||||
Status iglms61(in PendingIntent pendingIntent) = 60;
|
||||
|
||||
Location getLastLocation() = 6;
|
||||
Location getLastLocationWithPackage(String packageName) = 20;
|
||||
Location getLastLocationWith(String s) = 79;
|
||||
|
||||
void requestLocationUpdatesWithListener(in LocationRequest request, ILocationListener listener) = 7;
|
||||
void requestLocationUpdatesWithPackage(in LocationRequest request, ILocationListener listener, String packageName) = 19;
|
||||
void requestLocationUpdatesWithIntent(in LocationRequest request, in PendingIntent callbackIntent) = 8;
|
||||
@ -55,34 +59,55 @@ interface IGoogleLocationManagerService {
|
||||
void removeLocationUpdatesWithListener(ILocationListener listener) = 9;
|
||||
void removeLocationUpdatesWithIntent(in PendingIntent callbackIntent) = 10;
|
||||
void updateLocationRequest(in LocationRequestUpdateData locationRequestUpdateData) = 58;
|
||||
//void flushLocations(IFusedLocationProviderCallback callback = 66;
|
||||
// void flushLocations(IFusedLocationProviderCallback callback) = 66;
|
||||
|
||||
void setMockMode(boolean mockMode) = 11;
|
||||
void setMockLocation(in Location mockLocation) = 12;
|
||||
void injectLocation(in Location mockLocation, int injectionType) = 25;
|
||||
|
||||
Location getLastLocationWithPackage(String packageName) = 20;
|
||||
void iglms26(in Location var1, int var2) = 25;
|
||||
LocationAvailability getLocationAvailabilityWithPackage(String packageName) = 33;
|
||||
|
||||
IBinder iglms51() = 50;
|
||||
// void requestSleepSegmentUpdates(in PendingIntent pendingIntent, in SleepSegmentRequest request, IStatusCallback callback) = 78;
|
||||
void removeSleepSegmentUpdates(in PendingIntent pendingIntent, IStatusCallback callback) = 68;
|
||||
|
||||
void requestLocationSettingsDialog(in LocationSettingsRequest settingsRequest, ISettingsCallbacks callback, String packageName) = 62;
|
||||
|
||||
// void requestActivityTransitionUpdates(in ActivityTransitionRequest request, in PendingIntent pendingIntent, IStatusCallback callback) = 71;
|
||||
void removeActivityTransitionUpdates(in PendingIntent pendingIntent, IStatusCallback callback) = 72;
|
||||
|
||||
void updateDeviceOrientationRequest(in DeviceOrientationRequestUpdateData request) = 74;
|
||||
|
||||
boolean setActivityRecognitionMode(int mode) = 76;
|
||||
|
||||
void iglms14(in LatLngBounds var1, int var2, in PlaceFilter var3, in PlacesParams var4, IPlacesCallbacks var5) = 13;
|
||||
void iglms15(String var1, in PlacesParams var2, IPlacesCallbacks var3) = 14;
|
||||
void iglms16(in LatLng var1, in PlaceFilter var2, in PlacesParams var3, IPlacesCallbacks var4) = 15;
|
||||
void iglms17(in PlaceFilter var1, in PlacesParams var2, IPlacesCallbacks var3) = 16;
|
||||
void iglms18(in PlaceRequest var1, in PlacesParams var2, in PendingIntent var3) = 17;
|
||||
void iglms19(in PlacesParams var1, in PendingIntent var2) = 18;
|
||||
|
||||
void iglms25(in PlaceReport var1, in PlacesParams var2) = 24;
|
||||
|
||||
void iglms42(String var1, in PlacesParams var2, IPlacesCallbacks var3) = 41;
|
||||
|
||||
void iglms46(in UserAddedPlace var1, in PlacesParams var2, IPlacesCallbacks var3) = 45;
|
||||
void iglms47(in LatLngBounds var1, int var2, String var3, in PlaceFilter var4, in PlacesParams var5, IPlacesCallbacks var6) = 46;
|
||||
void iglms48(in NearbyAlertRequest var1, in PlacesParams var2, in PendingIntent var3) = 47;
|
||||
void iglms49(in PlacesParams var1, in PendingIntent var2) = 48;
|
||||
void iglms50(in UserDataType var1, in LatLngBounds var2, in List var3, in PlacesParams var4, IPlacesCallbacks var5) = 49;
|
||||
IBinder iglms51() = 50;
|
||||
|
||||
IBinder iglms54() = 53;
|
||||
void iglms55(String var1, in LatLngBounds var2, in AutocompleteFilter var3, in PlacesParams var4, IPlacesCallbacks var5) = 54;
|
||||
|
||||
void iglms58(in List var1, in PlacesParams var2, IPlacesCallbacks var3) = 57;
|
||||
|
||||
//void updateDeviceOrientationRequest(in DeviceOrientationRequestUpdateData request) = 74;
|
||||
void iglms65(in PendingIntent pendingIntent, IStatusCallback callback) = 64;
|
||||
void iglms66(in PendingIntent pendingIntent, IStatusCallback callback) = 65;
|
||||
|
||||
void iglms68(in PendingIntent pendingIntent, IStatusCallback callback) = 67;
|
||||
// void iglms70(in ActivityRecognitionRequest request, in PendingIntent pendingIntent, IStatusCallback callback) = 69;
|
||||
void iglms71(IStatusCallback callback) = 70;
|
||||
void iglms76(in PendingIntent pendingIntent) = 75;
|
||||
int iglms78() = 77;
|
||||
}
|
||||
|
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.location;
|
||||
|
||||
import org.microg.safeparcel.AutoSafeParcelable;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class DeviceOrientation extends AutoSafeParcelable {
|
||||
@Field(1)
|
||||
private float[] attitude = new float[4];
|
||||
@Field(2)
|
||||
private int attitudeConfidence = -1;
|
||||
@Field(3)
|
||||
private int magConfidence = -1;
|
||||
@Field(4)
|
||||
private float headingDegrees = Float.NaN;
|
||||
@Field(5)
|
||||
private float headingErrorDegrees = Float.NaN;
|
||||
@Field(6)
|
||||
private long elapsedRealtimeNanos = 0;
|
||||
@Field(7)
|
||||
private byte flags = 0;
|
||||
@Field(8)
|
||||
private float conservativeHeadingErrorVonMisesKappa = Float.NaN;
|
||||
|
||||
public float[] getAttitude() {
|
||||
if ((flags & 0x10) != 0) return attitude;
|
||||
return new float[4];
|
||||
}
|
||||
|
||||
public void setAttitude(float[] attitude) {
|
||||
if (attitude.length != 4) throw new IllegalArgumentException();
|
||||
this.attitude = attitude;
|
||||
flags = (byte) (flags | 0x10);
|
||||
}
|
||||
|
||||
public int getAttitudeConfidence() {
|
||||
if ((flags & 0x1) != 0) return attitudeConfidence;
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void setAttitudeConfidence(int attitudeConfidence) {
|
||||
this.attitudeConfidence = attitudeConfidence;
|
||||
flags = (byte) (flags | 0x1);
|
||||
}
|
||||
|
||||
public int getMagConfidence() {
|
||||
if ((flags & 0x2) != 0) return magConfidence;
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void setMagConfidence(int magConfidence) {
|
||||
this.magConfidence = magConfidence;
|
||||
flags = (byte) (flags | 0x2);
|
||||
}
|
||||
|
||||
public float getHeadingDegrees() {
|
||||
if ((flags & 0x4) != 0) return headingDegrees;
|
||||
return Float.NaN;
|
||||
}
|
||||
|
||||
public void setHeadingDegrees(float headingDegrees) {
|
||||
this.headingDegrees = headingDegrees;
|
||||
flags = (byte) (flags | 0x4);
|
||||
}
|
||||
|
||||
public float getHeadingErrorDegrees() {
|
||||
if ((flags & 0x8) != 0) return headingErrorDegrees;
|
||||
return Float.NaN;
|
||||
}
|
||||
|
||||
public void setHeadingErrorDegrees(float headingErrorDegrees) {
|
||||
this.headingErrorDegrees = headingErrorDegrees;
|
||||
flags = (byte) (flags | 0x8);
|
||||
}
|
||||
|
||||
public float getConservativeHeadingErrorVonMisesKappa() {
|
||||
if ((flags & 0x20) != 0) return conservativeHeadingErrorVonMisesKappa;
|
||||
return Float.NaN;
|
||||
}
|
||||
|
||||
public void setConservativeHeadingErrorVonMisesKappa(float conservativeHeadingErrorVonMisesKappa) {
|
||||
this.conservativeHeadingErrorVonMisesKappa = conservativeHeadingErrorVonMisesKappa;
|
||||
flags = (byte) (flags | 0x20);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("DeviceOrientation{");
|
||||
if ((flags & 0x10) != 0)
|
||||
sb.append("attitude=").append(Arrays.toString(attitude));
|
||||
if ((flags & 0x1) != 0)
|
||||
sb.append(", attitudeConfidence=").append(attitudeConfidence);
|
||||
if ((flags & 0x2) != 0)
|
||||
sb.append(", magConfidence=").append(magConfidence);
|
||||
if ((flags & 0x4) != 0)
|
||||
sb.append(", headingDegrees=").append(headingDegrees);
|
||||
if ((flags & 0x8) != 0)
|
||||
sb.append(", headingErrorDegrees=").append(headingErrorDegrees);
|
||||
return "DeviceOrientation{" +
|
||||
"attitude=" + Arrays.toString(attitude) +
|
||||
", attitudeConfidence=" + attitudeConfidence +
|
||||
", magConfidence=" + magConfidence +
|
||||
", headingDegrees=" + headingDegrees +
|
||||
", headingErrorDegrees=" + headingErrorDegrees +
|
||||
", elapsedRealtimeNanos=" + elapsedRealtimeNanos +
|
||||
", flags=" + flags +
|
||||
", conservativeHeadingErrorVonMisesKappa=" + conservativeHeadingErrorVonMisesKappa +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static final Creator<DeviceOrientation> CREATOR = new AutoCreator<DeviceOrientation>(DeviceOrientation.class);
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.location;
|
||||
|
||||
import android.os.SystemClock;
|
||||
|
||||
import org.microg.safeparcel.AutoSafeParcelable;
|
||||
|
||||
public class DeviceOrientationRequest extends AutoSafeParcelable {
|
||||
@Field(1)
|
||||
public boolean shouldUseMag;
|
||||
@Field(2)
|
||||
public long minimumSamplingPeriodMs;
|
||||
@Field(3)
|
||||
public float smallesAngleChangeRadians;
|
||||
@Field(4)
|
||||
public long expirationTime;
|
||||
@Field(5)
|
||||
public int numUpdates;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Request[shouldUseMag=").append(shouldUseMag);
|
||||
sb.append(" minimumSamplingPeriod=").append(minimumSamplingPeriodMs).append("ms");
|
||||
sb.append(" smallesAngleChange=").append(smallesAngleChangeRadians).append("rad");
|
||||
if (expirationTime != Long.MAX_VALUE)
|
||||
sb.append(" expireIn=").append(SystemClock.elapsedRealtime() - expirationTime).append("ms");
|
||||
if (numUpdates != Integer.MAX_VALUE)
|
||||
sb.append(" num=").append(numUpdates);
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static final Creator<DeviceOrientationRequest> CREATOR = new AutoCreator<DeviceOrientationRequest>(DeviceOrientationRequest.class);
|
||||
}
|
@ -17,8 +17,8 @@
|
||||
package com.google.android.gms.location;
|
||||
|
||||
import android.os.SystemClock;
|
||||
|
||||
import org.microg.safeparcel.AutoSafeParcelable;
|
||||
import org.microg.safeparcel.SafeParceled;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@ -101,24 +101,26 @@ public class LocationRequest extends AutoSafeParcelable {
|
||||
*/
|
||||
public static final int PRIORITY_NO_POWER = 105;
|
||||
|
||||
@SafeParceled(1000)
|
||||
@Field(1000)
|
||||
private int versionCode = 1;
|
||||
@SafeParceled(1)
|
||||
@Field(1)
|
||||
private int priority;
|
||||
@SafeParceled(2)
|
||||
@Field(2)
|
||||
private long interval;
|
||||
@SafeParceled(3)
|
||||
@Field(3)
|
||||
private long fastestInterval;
|
||||
@SafeParceled(4)
|
||||
@Field(4)
|
||||
private boolean explicitFastestInterval;
|
||||
@SafeParceled(5)
|
||||
@Field(5)
|
||||
private long expirationTime;
|
||||
@SafeParceled(6)
|
||||
@Field(6)
|
||||
private int numUpdates;
|
||||
@SafeParceled(7)
|
||||
private float smallestDesplacement;
|
||||
@SafeParceled(8)
|
||||
@Field(7)
|
||||
private float smallestDisplacement;
|
||||
@Field(8)
|
||||
private long maxWaitTime;
|
||||
@Field(9)
|
||||
private boolean waitForAccurateLocation;
|
||||
|
||||
public LocationRequest() {
|
||||
this.priority = PRIORITY_BALANCED_POWER_ACCURACY;
|
||||
@ -127,7 +129,7 @@ public class LocationRequest extends AutoSafeParcelable {
|
||||
this.explicitFastestInterval = false;
|
||||
this.expirationTime = Long.MAX_VALUE;
|
||||
this.numUpdates = Integer.MAX_VALUE;
|
||||
this.smallestDesplacement = 0;
|
||||
this.smallestDisplacement = 0;
|
||||
this.maxWaitTime = 0;
|
||||
}
|
||||
|
||||
@ -176,6 +178,17 @@ public class LocationRequest extends AutoSafeParcelable {
|
||||
return interval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum wait time in milliseconds for location updates. If the wait time is smaller than the interval
|
||||
* requested with {@link #setInterval(long)}, then the interval will be used instead.
|
||||
*
|
||||
* @return maximum wait time in milliseconds, inexact
|
||||
* @see #setMaxWaitTime(long)
|
||||
*/
|
||||
public long getMaxWaitTime() {
|
||||
return maxWaitTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of updates requested.
|
||||
* <p/>
|
||||
@ -204,8 +217,8 @@ public class LocationRequest extends AutoSafeParcelable {
|
||||
*
|
||||
* @return minimum displacement between location updates in meters
|
||||
*/
|
||||
public float getSmallestDesplacement() {
|
||||
return smallestDesplacement;
|
||||
public float getSmallestDisplacement() {
|
||||
return smallestDisplacement;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -231,7 +244,7 @@ public class LocationRequest extends AutoSafeParcelable {
|
||||
return false;
|
||||
if (priority != that.priority)
|
||||
return false;
|
||||
if (Float.compare(that.smallestDesplacement, smallestDesplacement) != 0)
|
||||
if (Float.compare(that.smallestDisplacement, smallestDisplacement) != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -240,11 +253,28 @@ public class LocationRequest extends AutoSafeParcelable {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(
|
||||
new Object[] { priority, interval, fastestInterval, explicitFastestInterval,
|
||||
explicitFastestInterval, numUpdates, smallestDesplacement, maxWaitTime
|
||||
new Object[]{priority, interval, fastestInterval, explicitFastestInterval,
|
||||
explicitFastestInterval, numUpdates, smallestDisplacement, maxWaitTime
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the fastest interval was explicitly specified for the location request.
|
||||
*
|
||||
* @return True if the fastest interval was explicitly set for the location request; false otherwise
|
||||
*/
|
||||
public boolean isFastestIntervalExplicitlySet() {
|
||||
return explicitFastestInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the location services will wait a few seconds initially for accurate locations, if accurate
|
||||
* locations cannot be computed on the device for {@link #PRIORITY_HIGH_ACCURACY} requests.
|
||||
*/
|
||||
public boolean isWaitForAccurateLocation() {
|
||||
return waitForAccurateLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the duration of this request, in milliseconds.
|
||||
* <p/>
|
||||
@ -312,6 +342,7 @@ public class LocationRequest extends AutoSafeParcelable {
|
||||
if (millis < 0)
|
||||
throw new IllegalArgumentException("interval must not be negative");
|
||||
fastestInterval = millis;
|
||||
explicitFastestInterval = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -348,6 +379,27 @@ public class LocationRequest extends AutoSafeParcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum wait time in milliseconds for location updates.
|
||||
* <p>
|
||||
* If you pass a value at least 2x larger than the interval specified with {@link #setInterval(long)}, then
|
||||
* location delivery may be delayed and multiple locations can be delivered at once. Locations are determined at
|
||||
* the {@link #setInterval(long)} rate, but can be delivered in batch after the interval you set in this method.
|
||||
* This can consume less battery and give more accurate locations, depending on the device's hardware capabilities.
|
||||
* You should set this value to be as large as possible for your needs if you don't need immediate location
|
||||
* delivery.
|
||||
*
|
||||
* @param millis desired maximum wait time in millisecond, inexact
|
||||
* @return the same object, so that setters can be chained
|
||||
* @throws IllegalArgumentException if the interval is less than zero
|
||||
*/
|
||||
public LocationRequest setMaxWaitTime(long millis) throws IllegalArgumentException {
|
||||
if (millis < 0)
|
||||
throw new IllegalArgumentException("interval must not be negative");
|
||||
maxWaitTime = millis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of location updates.
|
||||
* <p/>
|
||||
@ -417,22 +469,58 @@ public class LocationRequest extends AutoSafeParcelable {
|
||||
public LocationRequest setSmallestDisplacement(float smallestDisplacementMeters) {
|
||||
if (smallestDisplacementMeters < 0)
|
||||
throw new IllegalArgumentException("smallestDisplacementMeters must not be negative");
|
||||
this.smallestDesplacement = smallestDisplacementMeters;
|
||||
this.smallestDisplacement = smallestDisplacementMeters;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the client wants the locations services to wait a few seconds for accurate locations initially,
|
||||
* when accurate locations could not be computed on the device immediately after {@link #PRIORITY_HIGH_ACCURACY}
|
||||
* request is made. By default the location services will wait for accurate locations.
|
||||
* <p>
|
||||
* Note that this only applies to clients with {@link #PRIORITY_HIGH_ACCURACY} requests.
|
||||
* <p>
|
||||
* Also note this only applies to the initial locations computed right after the location request is added. The
|
||||
* following inaccurate locations may still be delivered to the clients without delay.
|
||||
*/
|
||||
public LocationRequest setWaitForAccurateLocation(boolean waitForAccurateLocation) {
|
||||
this.waitForAccurateLocation = waitForAccurateLocation;
|
||||
return this;
|
||||
}
|
||||
|
||||
private static String priorityToString(int priority) {
|
||||
switch (priority) {
|
||||
case PRIORITY_HIGH_ACCURACY:
|
||||
return "PRIORITY_HIGH_ACCURACY";
|
||||
case PRIORITY_BALANCED_POWER_ACCURACY:
|
||||
return "PRIORITY_BALANCED_POWER_ACCURACY";
|
||||
case PRIORITY_LOW_POWER:
|
||||
return "PRIORITY_LOW_POWER";
|
||||
case PRIORITY_NO_POWER:
|
||||
return "PRIORITY_NO_POWER";
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LocationRequest{" +
|
||||
"priority=" + priority +
|
||||
", interval=" + interval +
|
||||
", fastestInterval=" + fastestInterval +
|
||||
", explicitFastestInterval=" + explicitFastestInterval +
|
||||
", expirationTime=" + expirationTime +
|
||||
", numUpdates=" + numUpdates +
|
||||
", smallestDesplacement=" + smallestDesplacement +
|
||||
", maxWaitTime=" + maxWaitTime +
|
||||
'}';
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Request[");
|
||||
sb.append(priorityToString(priority));
|
||||
if (priority != PRIORITY_NO_POWER)
|
||||
sb.append(" requested=").append(interval).append("ms");
|
||||
sb.append(" fastest=").append(fastestInterval).append("ms");
|
||||
if (maxWaitTime > interval)
|
||||
sb.append(" maxWait=").append(maxWaitTime).append("ms");
|
||||
if (smallestDisplacement > 0)
|
||||
sb.append(" smallestDisplacement=").append(smallestDisplacement).append("m");
|
||||
if (expirationTime != Long.MAX_VALUE)
|
||||
sb.append(" expireIn=").append(SystemClock.elapsedRealtime() - expirationTime).append("ms");
|
||||
if (numUpdates != Integer.MAX_VALUE)
|
||||
sb.append(" num=").append(numUpdates);
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static final Creator<LocationRequest> CREATOR = new AutoCreator<LocationRequest>(LocationRequest.class);
|
||||
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.location.internal;
|
||||
|
||||
import com.google.android.gms.location.DeviceOrientationRequest;
|
||||
|
||||
import org.microg.safeparcel.AutoSafeParcelable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DeviceOrientationRequestInternal extends AutoSafeParcelable {
|
||||
|
||||
@Field(1)
|
||||
public DeviceOrientationRequest request;
|
||||
|
||||
@Field(value = 2, subClass = ClientIdentity.class)
|
||||
public List<ClientIdentity> clients;
|
||||
|
||||
@Field(3)
|
||||
public String tag;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DeviceOrientationRequestInternal{" +
|
||||
"request=" + request +
|
||||
", clients=" + clients +
|
||||
", tag='" + tag + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static final Creator<DeviceOrientationRequestInternal> CREATOR = new AutoCreator<DeviceOrientationRequestInternal>(DeviceOrientationRequestInternal.class);
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.location.internal;
|
||||
|
||||
import com.google.android.gms.location.IDeviceOrientationListener;
|
||||
|
||||
import org.microg.safeparcel.AutoSafeParcelable;
|
||||
|
||||
public class DeviceOrientationRequestUpdateData extends AutoSafeParcelable {
|
||||
public static final int REQUEST_UPDATES = 1;
|
||||
public static final int REMOVE_UPDATES = 2;
|
||||
|
||||
@Field(1)
|
||||
public int opCode;
|
||||
|
||||
@Field(2)
|
||||
public DeviceOrientationRequestInternal request;
|
||||
|
||||
@Field(3)
|
||||
public IDeviceOrientationListener listener;
|
||||
|
||||
@Field(4)
|
||||
public IFusedLocationProviderCallback fusedLocationProviderCallback;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DeviceOrientationRequestUpdateData{" +
|
||||
"opCode=" + opCode +
|
||||
", request=" + request +
|
||||
", listener=" + (listener != null ? listener.asBinder() : null) +
|
||||
", fusedLocationProviderCallback=" + (fusedLocationProviderCallback != null ? fusedLocationProviderCallback.asBinder() : null) +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static final Creator<DeviceOrientationRequestUpdateData> CREATOR = new AutoCreator<DeviceOrientationRequestUpdateData>(DeviceOrientationRequestUpdateData.class);
|
||||
}
|
@ -25,39 +25,48 @@ import java.util.List;
|
||||
|
||||
public class LocationRequestInternal extends AutoSafeParcelable {
|
||||
|
||||
@SafeParceled(1000)
|
||||
@Field(1000)
|
||||
private int versionCode = 1;
|
||||
|
||||
@SafeParceled(1)
|
||||
@Field(1)
|
||||
public LocationRequest request;
|
||||
|
||||
@SafeParceled(2)
|
||||
@Field(2) @Deprecated
|
||||
public boolean requestNlpDebugInfo;
|
||||
|
||||
@SafeParceled(3)
|
||||
@Field(3) @Deprecated
|
||||
public boolean restorePendingIntentListeners;
|
||||
|
||||
@SafeParceled(4)
|
||||
@Field(4) @Deprecated
|
||||
public boolean triggerUpdate;
|
||||
|
||||
@SafeParceled(value = 5, subClass = ClientIdentity.class)
|
||||
@Field(value = 5, subClass = ClientIdentity.class)
|
||||
public List<ClientIdentity> clients;
|
||||
|
||||
@SafeParceled(6)
|
||||
@Field(6)
|
||||
public String tag;
|
||||
|
||||
@SafeParceled(7)
|
||||
@Field(7)
|
||||
public boolean hideFromAppOps;
|
||||
|
||||
@SafeParceled(8)
|
||||
@Field(8)
|
||||
public boolean forceCoarseLocation;
|
||||
|
||||
@SafeParceled(9)
|
||||
@Field(9)
|
||||
public boolean exemptFromThrottle;
|
||||
|
||||
@SafeParceled(10)
|
||||
@Field(10)
|
||||
public String moduleId;
|
||||
|
||||
@Field(11)
|
||||
public boolean locationSettingsIgnored;
|
||||
|
||||
@Field(12)
|
||||
public boolean inaccurateLocationsDelayed;
|
||||
|
||||
@Field(13)
|
||||
public String contextAttributeTag;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LocationRequestInternal{" +
|
||||
@ -71,6 +80,9 @@ public class LocationRequestInternal extends AutoSafeParcelable {
|
||||
", forceCoarseLocation=" + forceCoarseLocation +
|
||||
", exemptFromThrottle=" + exemptFromThrottle +
|
||||
", moduleId=" + moduleId +
|
||||
", locationSettingsIgnored=" + locationSettingsIgnored +
|
||||
", inaccurateLocationsDelayed=" + inaccurateLocationsDelayed +
|
||||
", contextAttributeTag=" + contextAttributeTag +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
@ -8,19 +8,16 @@ apply plugin: 'kotlin-android'
|
||||
|
||||
dependencies {
|
||||
api project(':play-services-location-api')
|
||||
|
||||
implementation "androidx.lifecycle:lifecycle-service:$lifecycleVersion"
|
||||
|
||||
implementation project(':play-services-base-core')
|
||||
implementation "org.microg.nlp:geocode-v1:$nlpVersion"
|
||||
implementation "org.microg.nlp:location-v2:$nlpVersion"
|
||||
implementation "org.microg.nlp:location-v3:$nlpVersion"
|
||||
implementation "org.microg.nlp:service:$nlpVersion"
|
||||
|
||||
runtimeOnly "org.microg.nlp:service:$nlpVersion"
|
||||
api "org.microg.nlp:client:$nlpVersion"
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutineVersion"
|
||||
api "org.microg.nlp:client:$nlpVersion"
|
||||
api "org.microg.nlp:ui:$nlpVersion"
|
||||
implementation "androidx.lifecycle:lifecycle-service:$lifecycleVersion"
|
||||
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion"
|
||||
}
|
||||
|
||||
android {
|
||||
|
@ -27,6 +27,7 @@ import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.location.ILocationListener;
|
||||
import com.google.android.gms.location.LocationRequest;
|
||||
import com.google.android.gms.location.internal.FusedLocationProviderResult;
|
||||
@ -35,6 +36,7 @@ import com.google.android.gms.location.internal.LocationRequestUpdateData;
|
||||
import org.microg.gms.common.PackageUtils;
|
||||
import org.microg.gms.common.Utils;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -45,8 +47,10 @@ import static android.location.LocationManager.GPS_PROVIDER;
|
||||
import static com.google.android.gms.location.LocationRequest.PRIORITY_HIGH_ACCURACY;
|
||||
import static com.google.android.gms.location.LocationRequest.PRIORITY_NO_POWER;
|
||||
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
|
||||
public class GoogleLocationManager implements LocationChangeListener {
|
||||
private static final String TAG = "GmsLocManager";
|
||||
private static final String TAG = "LocationManager";
|
||||
private static final String MOCK_PROVIDER = "mock";
|
||||
private static final long VERIFY_CURRENT_REQUESTS_INTERVAL_MS = 5000; // 5 seconds
|
||||
private static final long SWITCH_ON_FRESHNESS_CLIFF_MS = 30000; // 30 seconds
|
||||
@ -60,7 +64,8 @@ public class GoogleLocationManager implements LocationChangeListener {
|
||||
private final MockLocationProvider mockProvider;
|
||||
private final List<LocationRequestHelper> currentRequests = new ArrayList<LocationRequestHelper>();
|
||||
|
||||
public GoogleLocationManager(Context context) {
|
||||
public GoogleLocationManager(Context context, Lifecycle lifecycle) {
|
||||
long callingIdentity = Binder.clearCallingIdentity();
|
||||
this.context = context;
|
||||
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
||||
if (Utils.hasSelfPermissionOrNotify(context, Manifest.permission.ACCESS_FINE_LOCATION)) {
|
||||
@ -69,12 +74,13 @@ public class GoogleLocationManager implements LocationChangeListener {
|
||||
this.gpsProvider = null;
|
||||
}
|
||||
if (Utils.hasSelfPermissionOrNotify(context, Manifest.permission.ACCESS_COARSE_LOCATION)) {
|
||||
this.networkProvider = new UnifiedLocationProvider(context, this);
|
||||
this.networkProvider = new UnifiedLocationProvider(context, this, lifecycle);
|
||||
} else {
|
||||
this.networkProvider = null;
|
||||
}
|
||||
mockProvider = new MockLocationProvider(this);
|
||||
handler = new Handler(Looper.getMainLooper());
|
||||
Binder.restoreCallingIdentity(callingIdentity);
|
||||
}
|
||||
|
||||
public void invokeOnceReady(Runnable runnable) {
|
||||
@ -140,19 +146,29 @@ public class GoogleLocationManager implements LocationChangeListener {
|
||||
}
|
||||
}
|
||||
if (old != null) {
|
||||
Log.d(TAG, "Removing replaced location request: " + old);
|
||||
currentRequests.remove(old);
|
||||
}
|
||||
currentRequests.add(request);
|
||||
if (gpsProvider != null && request.hasFinePermission() && request.locationRequest.getPriority() == PRIORITY_HIGH_ACCURACY) {
|
||||
Log.d(TAG, "Registering request with high accuracy location provider");
|
||||
gpsProvider.addRequest(request);
|
||||
} else if (gpsProvider != null && old != null) {
|
||||
Log.d(TAG, "Unregistering request with high accuracy location provider");
|
||||
gpsProvider.removeRequest(old);
|
||||
} else {
|
||||
Log.w(TAG, "Not providing high accuracy location: missing permission");
|
||||
}
|
||||
if (networkProvider != null && request.hasCoarsePermission() && request.locationRequest.getPriority() != PRIORITY_NO_POWER) {
|
||||
Log.d(TAG, "Registering request with low accuracy location provider");
|
||||
networkProvider.addRequest(request);
|
||||
} else if (networkProvider != null && old != null) {
|
||||
Log.d(TAG, "Unregistering request with low accuracy location provider");
|
||||
networkProvider.removeRequest(old);
|
||||
} else {
|
||||
Log.w(TAG, "Not providing low accuracy location: missing permission");
|
||||
}
|
||||
handler.postDelayed(this::onLocationChanged, request.locationRequest.getFastestInterval());
|
||||
}
|
||||
|
||||
public void requestLocationUpdates(LocationRequest request, ILocationListener listener, String packageName) {
|
||||
@ -188,28 +204,43 @@ public class GoogleLocationManager implements LocationChangeListener {
|
||||
}
|
||||
|
||||
public void updateLocationRequest(LocationRequestUpdateData data) {
|
||||
String packageName = PackageUtils.getCallingPackage(context);
|
||||
if (data.pendingIntent != null)
|
||||
packageName = PackageUtils.packageFromPendingIntent(data.pendingIntent);
|
||||
if (data.opCode == LocationRequestUpdateData.REQUEST_UPDATES) {
|
||||
requestLocationUpdates(new LocationRequestHelper(context, packageName, Binder.getCallingUid(), data));
|
||||
} else if (data.opCode == LocationRequestUpdateData.REMOVE_UPDATES) {
|
||||
for (int i = 0; i < currentRequests.size(); i++) {
|
||||
if (currentRequests.get(i).respondsTo(data.listener)
|
||||
|| currentRequests.get(i).respondsTo(data.pendingIntent)
|
||||
|| currentRequests.get(i).respondsTo(data.callback)) {
|
||||
removeLocationUpdates(currentRequests.get(i));
|
||||
i--;
|
||||
try {
|
||||
Log.d(TAG, "updateLocationRequest: " + data);
|
||||
String packageName = PackageUtils.getCallingPackage(context);
|
||||
if (data.pendingIntent != null)
|
||||
packageName = PackageUtils.packageFromPendingIntent(data.pendingIntent);
|
||||
Log.d(TAG, "Using source package: " + packageName);
|
||||
if (data.opCode == LocationRequestUpdateData.REQUEST_UPDATES) {
|
||||
requestLocationUpdates(new LocationRequestHelper(context, packageName, Binder.getCallingUid(), data));
|
||||
} else if (data.opCode == LocationRequestUpdateData.REMOVE_UPDATES) {
|
||||
for (int i = 0; i < currentRequests.size(); i++) {
|
||||
if (currentRequests.get(i).respondsTo(data.listener)
|
||||
|| currentRequests.get(i).respondsTo(data.pendingIntent)
|
||||
|| currentRequests.get(i).respondsTo(data.callback)) {
|
||||
removeLocationUpdates(currentRequests.get(i));
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "Updated current requests, verifying");
|
||||
verifyCurrentRequests();
|
||||
if (data.fusedLocationProviderCallback != null) {
|
||||
try {
|
||||
Log.d(TAG, "Send success result to " + packageName);
|
||||
data.fusedLocationProviderCallback.onFusedLocationProviderResult(FusedLocationProviderResult.SUCCESS);
|
||||
} catch (RemoteException ignored) {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Exception in updateLocationRequest", e);
|
||||
if (data.fusedLocationProviderCallback != null) {
|
||||
try {
|
||||
Log.d(TAG, "Send internal error result");
|
||||
data.fusedLocationProviderCallback.onFusedLocationProviderResult(FusedLocationProviderResult.create(Status.INTERNAL_ERROR));
|
||||
} catch (RemoteException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (data.fusedLocationProviderCallback != null) {
|
||||
try {
|
||||
data.fusedLocationProviderCallback.onFusedLocationProviderResult(FusedLocationProviderResult.SUCCESS);
|
||||
} catch (RemoteException ignored) {
|
||||
}
|
||||
}
|
||||
verifyCurrentRequests();
|
||||
}
|
||||
|
||||
public void setMockMode(boolean mockMode) {
|
||||
@ -250,4 +281,13 @@ public class GoogleLocationManager implements LocationChangeListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void dump(PrintWriter writer) {
|
||||
if (gpsProvider != null) gpsProvider.dump(writer);
|
||||
if (networkProvider != null) networkProvider.dump(writer);
|
||||
writer.println(currentRequests.size() + " requests:");
|
||||
for (LocationRequestHelper request : currentRequests) {
|
||||
writer.println(" " + request.id + " package=" + request.packageName + " interval=" + request.locationRequest.getInterval() + " smallestDisplacement=" + request.locationRequest.getSmallestDisplacement());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,11 +27,14 @@ import com.google.android.gms.common.internal.IGmsCallbacks;
|
||||
import org.microg.gms.BaseService;
|
||||
import org.microg.gms.common.GmsService;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class GoogleLocationManagerService extends BaseService {
|
||||
private GoogleLocationManagerServiceImpl impl = new GoogleLocationManagerServiceImpl(this);
|
||||
private GoogleLocationManagerServiceImpl impl = new GoogleLocationManagerServiceImpl(this, getLifecycle());
|
||||
|
||||
public GoogleLocationManagerService() {
|
||||
super("GmsLocManagerSvc", GmsService.LOCATION_MANAGER, GmsService.GEODATA, GmsService.PLACE_DETECTION);
|
||||
super("LocationManager", GmsService.LOCATION_MANAGER, GmsService.GEODATA, GmsService.PLACE_DETECTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -49,4 +52,9 @@ public class GoogleLocationManagerService extends BaseService {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
|
||||
impl.getLocationManager().dump(writer);
|
||||
}
|
||||
}
|
||||
|
@ -20,12 +20,19 @@ import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Parcel;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.common.api.internal.IStatusCallback;
|
||||
import com.google.android.gms.location.ActivityRecognitionResult;
|
||||
import com.google.android.gms.location.GeofencingRequest;
|
||||
import com.google.android.gms.location.GestureRequest;
|
||||
@ -35,6 +42,7 @@ import com.google.android.gms.location.LocationRequest;
|
||||
import com.google.android.gms.location.LocationSettingsRequest;
|
||||
import com.google.android.gms.location.LocationSettingsResult;
|
||||
import com.google.android.gms.location.LocationSettingsStates;
|
||||
import com.google.android.gms.location.internal.DeviceOrientationRequestUpdateData;
|
||||
import com.google.android.gms.location.internal.IGeofencerCallbacks;
|
||||
import com.google.android.gms.location.internal.IGoogleLocationManagerService;
|
||||
import com.google.android.gms.location.internal.ISettingsCallbacks;
|
||||
@ -58,23 +66,31 @@ import org.microg.gms.common.PackageUtils;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerService.Stub {
|
||||
public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerService.Stub implements LifecycleOwner {
|
||||
private static final String TAG = "GmsLocManagerSvcImpl";
|
||||
|
||||
private final Context context;
|
||||
private final Lifecycle lifecycle;
|
||||
private GoogleLocationManager locationManager;
|
||||
|
||||
public GoogleLocationManagerServiceImpl(Context context) {
|
||||
public GoogleLocationManagerServiceImpl(Context context, Lifecycle lifecycle) {
|
||||
this.context = context;
|
||||
this.lifecycle = lifecycle;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Lifecycle getLifecycle() {
|
||||
return lifecycle;
|
||||
}
|
||||
|
||||
public void invokeOnceReady(Runnable runnable) {
|
||||
getLocationManager().invokeOnceReady(runnable);
|
||||
}
|
||||
|
||||
private GoogleLocationManager getLocationManager() {
|
||||
public synchronized GoogleLocationManager getLocationManager() {
|
||||
if (locationManager == null)
|
||||
locationManager = new GoogleLocationManager(context);
|
||||
locationManager = new GoogleLocationManager(context, lifecycle);
|
||||
return locationManager;
|
||||
}
|
||||
|
||||
@ -123,18 +139,6 @@ public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerServ
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Status iglms65(PendingIntent pendingIntent) throws RemoteException {
|
||||
Log.d(TAG, "iglms65");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Status iglms66(PendingIntent pendingIntent) throws RemoteException {
|
||||
Log.d(TAG, "iglms66");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Status requestGestureUpdates(GestureRequest request, PendingIntent pendingIntent) throws RemoteException {
|
||||
Log.d(TAG, "requestGestureUpdates");
|
||||
@ -199,6 +203,11 @@ public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerServ
|
||||
getLocationManager().setMockLocation(mockLocation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectLocation(Location mockLocation, int injectionType) throws RemoteException {
|
||||
Log.d(TAG, "injectLocation[" + injectionType + "]: " + mockLocation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iglms14(LatLngBounds var1, int var2, PlaceFilter var3, PlacesParams var4,
|
||||
IPlacesCallbacks var5) throws RemoteException {
|
||||
@ -250,13 +259,14 @@ public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerServ
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iglms25(PlaceReport var1, PlacesParams var2) throws RemoteException {
|
||||
Log.d(TAG, "iglms25: " + var1);
|
||||
public Location getLastLocationWith(String s) throws RemoteException {
|
||||
Log.d(TAG, "getLastLocationWith: " + s);
|
||||
return getLastLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iglms26(Location var1, int var2) throws RemoteException {
|
||||
Log.d(TAG, "iglms26: " + var1);
|
||||
public void iglms25(PlaceReport var1, PlacesParams var2) throws RemoteException {
|
||||
Log.d(TAG, "iglms25: " + var1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -266,6 +276,11 @@ public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerServ
|
||||
return new LocationAvailability();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSleepSegmentUpdates(PendingIntent pendingIntent, IStatusCallback callback) throws RemoteException {
|
||||
Log.d(TAG, "removeSleepSegmentUpdates");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iglms42(String var1, PlacesParams var2, IPlacesCallbacks var3)
|
||||
throws RemoteException {
|
||||
@ -311,7 +326,29 @@ public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerServ
|
||||
public void requestLocationSettingsDialog(LocationSettingsRequest settingsRequest, ISettingsCallbacks callback, String packageName) throws RemoteException {
|
||||
Log.d(TAG, "requestLocationSettingsDialog: " + settingsRequest);
|
||||
PackageUtils.getAndCheckCallingPackage(context, packageName);
|
||||
callback.onLocationSettingsResult(new LocationSettingsResult(new LocationSettingsStates(true, true, false, true, true, false), Status.SUCCESS));
|
||||
(new Handler(Looper.getMainLooper())).post(() -> {
|
||||
try {
|
||||
callback.onLocationSettingsResult(new LocationSettingsResult(new LocationSettingsStates(true, true, true, true, true, true), Status.SUCCESS));
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeActivityTransitionUpdates(PendingIntent pendingIntent, IStatusCallback callback) throws RemoteException {
|
||||
Log.d(TAG, "removeActivityTransitionUpdates");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDeviceOrientationRequest(DeviceOrientationRequestUpdateData request) throws RemoteException {
|
||||
Log.d(TAG, "updateDeviceOrientationRequest: " + request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setActivityRecognitionMode(int mode) throws RemoteException {
|
||||
Log.d(TAG, "setActivityRecognitionMode: " + mode);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -352,6 +389,37 @@ public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerServ
|
||||
Log.d(TAG, "iglms58: " + var1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iglms65(PendingIntent pendingIntent, IStatusCallback callback) throws RemoteException {
|
||||
Log.d(TAG, "iglms65");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iglms66(PendingIntent pendingIntent, IStatusCallback callback) throws RemoteException {
|
||||
Log.d(TAG, "iglms66");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iglms68(PendingIntent pendingIntent, IStatusCallback callback) throws RemoteException {
|
||||
Log.d(TAG, "iglms68");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iglms71(IStatusCallback callback) throws RemoteException {
|
||||
Log.d(TAG, "iglms71");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iglms76(PendingIntent pendingIntent) throws RemoteException {
|
||||
Log.d(TAG, "iglms76");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int iglms78() throws RemoteException {
|
||||
Log.d(TAG, "iglms78");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
|
||||
if (super.onTransact(code, data, reply, flags)) return true;
|
||||
|
@ -17,7 +17,6 @@
|
||||
package org.microg.gms.location;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AppOpsManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
@ -35,12 +34,9 @@ import com.google.android.gms.location.LocationRequest;
|
||||
import com.google.android.gms.location.LocationResult;
|
||||
import com.google.android.gms.location.internal.LocationRequestUpdateData;
|
||||
|
||||
import org.microg.gms.common.PackageUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static android.Manifest.permission.ACCESS_BACKGROUND_LOCATION;
|
||||
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
|
||||
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
|
||||
|
||||
@ -56,6 +52,7 @@ public class LocationRequestHelper {
|
||||
public ILocationListener listener;
|
||||
public PendingIntent pendingIntent;
|
||||
public ILocationCallback callback;
|
||||
public String id = UUID.randomUUID().toString();
|
||||
|
||||
private Location lastReport;
|
||||
private int numReports = 0;
|
||||
@ -117,10 +114,13 @@ public class LocationRequestHelper {
|
||||
if (location == null) return true;
|
||||
if (!isActive()) return false;
|
||||
if (lastReport != null) {
|
||||
if (location.equals(lastReport)) {
|
||||
return true;
|
||||
}
|
||||
if (location.getTime() - lastReport.getTime() < locationRequest.getFastestInterval()) {
|
||||
return true;
|
||||
}
|
||||
if (location.distanceTo(lastReport) < locationRequest.getSmallestDesplacement()) {
|
||||
if (location.distanceTo(lastReport) < locationRequest.getSmallestDisplacement()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import android.os.Bundle;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@ -44,7 +45,12 @@ public class RealLocationProvider {
|
||||
private LocationListener listener = new LocationListener() {
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
lastLocation = location;
|
||||
lastLocation = new Location(location);
|
||||
try {
|
||||
lastLocation.getExtras().keySet(); // call to unparcel()
|
||||
} catch (Exception e) {
|
||||
// Sometimes we need to define the correct ClassLoader before unparcel(). Ignore those.
|
||||
}
|
||||
changeListener.onLocationChanged();
|
||||
}
|
||||
|
||||
@ -121,7 +127,7 @@ public class RealLocationProvider {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (LocationRequestHelper request : requests) {
|
||||
minTime = Math.min(request.locationRequest.getInterval(), minTime);
|
||||
minDistance = Math.min(request.locationRequest.getSmallestDesplacement(), minDistance);
|
||||
minDistance = Math.min(request.locationRequest.getSmallestDisplacement(), minDistance);
|
||||
if (sb.length() != 0) sb.append(", ");
|
||||
sb.append(request.packageName).append(":").append(request.locationRequest.getInterval()).append("ms");
|
||||
}
|
||||
@ -146,4 +152,16 @@ public class RealLocationProvider {
|
||||
connectedMinDistance = minDistance;
|
||||
}
|
||||
}
|
||||
|
||||
public void dump(PrintWriter writer) {
|
||||
if (writer != null) {
|
||||
writer.println(name + " provider:");
|
||||
writer.println(" last location: " + lastLocation);
|
||||
writer.println(" active: " + connected.get());
|
||||
if (connected.get()) {
|
||||
writer.println(" interval: " + connectedMinTime);
|
||||
writer.println(" distance: " + connectedMinDistance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.microg.gms.location;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.os.Parcel;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
@ -58,4 +59,15 @@ public class ReportingServiceImpl extends IReportingService.Stub {
|
||||
Log.d(TAG, "reportDeviceAtPlace");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
|
||||
if (super.onTransact(code, data, reply, flags)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Log.d(TAG, "onTransact [unknown]: " + code + ", " + data + ", " + flags);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2,32 +2,54 @@ package org.microg.gms.location
|
||||
|
||||
import android.content.Context
|
||||
import android.location.Location
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.microg.nlp.client.UnifiedLocationClient
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import org.microg.nlp.client.LocationClient
|
||||
import org.microg.nlp.service.api.Constants
|
||||
import org.microg.nlp.service.api.ILocationListener
|
||||
import org.microg.nlp.service.api.LocationRequest
|
||||
import java.io.PrintWriter
|
||||
import java.lang.Exception
|
||||
import java.util.*
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class UnifiedLocationProvider(context: Context?, changeListener: LocationChangeListener) {
|
||||
private val client: UnifiedLocationClient
|
||||
private var connectedMinTime: Long = 0
|
||||
class UnifiedLocationProvider(private val context: Context, private val changeListener: LocationChangeListener, private val lifecycle: Lifecycle): LifecycleOwner {
|
||||
private val client: LocationClient = LocationClient(context, lifecycle)
|
||||
private var lastLocation: Location? = null
|
||||
private val connected = AtomicBoolean(false)
|
||||
private val changeListener: LocationChangeListener
|
||||
private val requests: MutableList<LocationRequestHelper> = ArrayList()
|
||||
private val listener: UnifiedLocationClient.LocationListener = object : UnifiedLocationClient.LocationListener {
|
||||
override fun onLocation(location: Location) {
|
||||
lastLocation = location
|
||||
changeListener.onLocationChanged()
|
||||
private val activeRequestIds = hashSetOf<String>()
|
||||
private val activeRequestMutex = Mutex(false)
|
||||
private val listener: ILocationListener = object : ILocationListener.Stub() {
|
||||
override fun onLocation(statusCode: Int, location: Location?) {
|
||||
if (statusCode == Constants.STATUS_OK && location != null) {
|
||||
lastLocation = Location(location)
|
||||
try {
|
||||
for (key in lastLocation?.extras?.keySet()?.toList().orEmpty()) {
|
||||
if (key?.startsWith("org.microg.nlp.") == true) {
|
||||
lastLocation?.extras?.remove(key)
|
||||
}
|
||||
}
|
||||
} catch (e:Exception){
|
||||
// Sometimes we need to define the correct ClassLoader before unparcel(). Ignore those.
|
||||
}
|
||||
changeListener.onLocationChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
private var ready = false
|
||||
private val invokeOnceReady = hashSetOf<Runnable>()
|
||||
|
||||
init {
|
||||
updateLastLocation()
|
||||
}
|
||||
|
||||
private fun updateLastLocation() {
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
lifecycleScope.launchWhenStarted {
|
||||
Log.d(TAG, "unified network: requesting last location")
|
||||
val lastLocation = client.getLastLocation()
|
||||
Log.d(TAG, "unified network: got last location: $lastLocation")
|
||||
@ -78,42 +100,40 @@ class UnifiedLocationProvider(context: Context?, changeListener: LocationChangeL
|
||||
|
||||
@Synchronized
|
||||
private fun updateConnection() {
|
||||
if (connected.get() && requests.isEmpty()) {
|
||||
Log.d(TAG, "unified network: no longer requesting location update")
|
||||
client.removeLocationUpdates(listener)
|
||||
connected.set(false)
|
||||
} else if (requests.isNotEmpty()) {
|
||||
var minTime = Long.MAX_VALUE
|
||||
var maxUpdates = Int.MAX_VALUE
|
||||
val sb = StringBuilder()
|
||||
var opPackageName: String? = null
|
||||
for (request in requests) {
|
||||
if (request.locationRequest.interval < minTime) {
|
||||
opPackageName = request.packageName
|
||||
minTime = request.locationRequest.interval
|
||||
maxUpdates = request.locationRequest.numUpdates
|
||||
lifecycleScope.launchWhenStarted {
|
||||
activeRequestMutex.withLock {
|
||||
if (activeRequestIds.isNotEmpty() && requests.isEmpty()) {
|
||||
Log.d(TAG, "unified network: no longer requesting location update")
|
||||
for (id in activeRequestIds) {
|
||||
client.cancelLocationRequestById(id)
|
||||
}
|
||||
activeRequestIds.clear()
|
||||
} else if (requests.isNotEmpty()) {
|
||||
val requests = ArrayList(requests).filter { it.isActive }
|
||||
for (id in activeRequestIds.filter { id -> requests.none { it.id == id } }) {
|
||||
client.cancelLocationRequestById(id)
|
||||
}
|
||||
for (request in requests.filter { it.id !in activeRequestIds }) {
|
||||
client.updateLocationRequest(LocationRequest(listener, request.locationRequest.interval, request.locationRequest.numUpdates, request.id), Bundle().apply {
|
||||
putString("packageName", request.packageName)
|
||||
putString("source", "GoogleLocationManager")
|
||||
})
|
||||
activeRequestIds.add(request.id)
|
||||
}
|
||||
}
|
||||
if (sb.isNotEmpty()) sb.append(", ")
|
||||
sb.append("${request.packageName}:${request.locationRequest.interval}ms")
|
||||
}
|
||||
client.opPackageName = opPackageName
|
||||
if (minTime <= 0) {
|
||||
client.forceNextUpdate = true
|
||||
}
|
||||
Log.d(TAG, "unified network: requesting location updates with interval ${minTime}ms ($sb)")
|
||||
client.requestLocationUpdates(listener, minTime, maxUpdates)
|
||||
connected.set(true)
|
||||
connectedMinTime = minTime
|
||||
}
|
||||
}
|
||||
|
||||
override fun getLifecycle(): Lifecycle = lifecycle
|
||||
|
||||
fun dump(writer: PrintWriter) {
|
||||
writer.println("network provider (via direct client):")
|
||||
writer.println(" last location: $lastLocation")
|
||||
writer.println(" ready: $ready")
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG = "GmsLocProviderU"
|
||||
}
|
||||
|
||||
init {
|
||||
client = UnifiedLocationClient[context!!]
|
||||
this.changeListener = changeListener
|
||||
updateLastLocation()
|
||||
}
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ public class NativeLocationClientImpl {
|
||||
i.putExtras(bundle);
|
||||
pendingCount.put(pendingIntent, request.getNumUpdates());
|
||||
nativePendingMap.put(pendingIntent, PendingIntent.getActivity(context, 0, i, 0));
|
||||
locationManager.requestLocationUpdates(request.getInterval(), request.getSmallestDesplacement(),
|
||||
locationManager.requestLocationUpdates(request.getInterval(), request.getSmallestDisplacement(),
|
||||
makeNativeCriteria(request), nativePendingMap.get(pendingIntent));
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ public class NativeLocationClientImpl {
|
||||
}
|
||||
nativeListenerMap.put(listener, new NativeListener(listener, request.getNumUpdates()));
|
||||
locationManager.requestLocationUpdates(request.getInterval(),
|
||||
request.getSmallestDesplacement(), makeNativeCriteria(request),
|
||||
request.getSmallestDisplacement(), makeNativeCriteria(request),
|
||||
nativeListenerMap.get(listener), looper);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user