method public void onGnssMeasurementsReceived(android.location.GnssMeasurementsEvent);
method public void onStatusChanged(int);
field public static final int STATUS_LOCATION_DISABLED = 2; // 0x2
+ field public static final int STATUS_NOT_ALLOWED = 3; // 0x3
field public static final int STATUS_NOT_SUPPORTED = 0; // 0x0
field public static final int STATUS_READY = 1; // 0x1
}
method public int getQuality();
method public float getSmallestDisplacement();
method public android.os.WorkSource getWorkSource();
+ method public boolean isLowPowerMode();
method public android.location.LocationRequest setExpireAt(long);
method public android.location.LocationRequest setExpireIn(long);
method public android.location.LocationRequest setFastestInterval(long);
method public void setHideFromAppOps(boolean);
method public android.location.LocationRequest setInterval(long);
+ method public android.location.LocationRequest setLowPowerMode(boolean);
method public android.location.LocationRequest setNumUpdates(int);
method public android.location.LocationRequest setProvider(java.lang.String);
method public android.location.LocationRequest setQuality(int);
*/
public static final String NOTIFICATION_SNOOZE_OPTIONS =
"notification_snooze_options";
+
+ /**
+ * Enable GNSS Raw Measurements Full Tracking?
+ * 0 = no
+ * 1 = yes
+ * @hide
+ */
+ public static final String ENABLE_GNSS_RAW_MEAS_FULL_TRACKING =
+ "enable_gnss_raw_meas_full_tracking";
}
/**
optional SettingProto enable_cache_quota_calculation = 339;
optional SettingProto enable_deletion_helper_no_threshold_toggle = 340;
optional SettingProto notification_snooze_options = 341;
+ optional SettingProto enable_gnss_raw_meas_full_tracking = 346;
- // Next tag = 346;
+ // Next tag = 347;
}
message SecureSettingsProto {
Settings.Global.ENABLE_GPU_DEBUG_LAYERS,
Settings.Global.GPU_DEBUG_APP,
Settings.Global.GPU_DEBUG_LAYERS,
+ Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING,
Settings.Global.NETWORK_ACCESS_TIMEOUT_MS,
Settings.Global.WARNING_TEMPERATURE,
Settings.Global.WEBVIEW_DATA_REDUCTION_PROXY_KEY,
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
- @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_LOCATION_DISABLED})
+ @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_LOCATION_DISABLED, STATUS_NOT_ALLOWED})
public @interface GnssMeasurementsStatus {}
/**
public static final int STATUS_LOCATION_DISABLED = 2;
/**
+ * The client is not allowed to register for GNSS Measurements in general or in the
+ * requested mode.
+ */
+ public static final int STATUS_NOT_ALLOWED = 3;
+
+ /**
* Reports the latest collected GNSS Measurements.
*/
public void onGnssMeasurementsReceived(GnssMeasurementsEvent eventArgs) {}
package android.location;
-import com.android.internal.util.Preconditions;
-
import android.annotation.NonNull;
import android.content.Context;
import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;
+import com.android.internal.util.Preconditions;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
mTag = name;
}
+ /**
+ * Adds a {@param listener} to the list of listeners on which callbacks will be executed. The
+ * execution will happen on the {@param handler} thread or alternatively in the callback thread
+ * if a {@code null} handler value is passed.
+ */
public boolean add(@NonNull TListener listener, Handler handler) {
Preconditions.checkNotNull(listener);
synchronized (mListeners) {
private int mQuality = POWER_LOW;
private long mInterval = 60 * 60 * 1000; // 60 minutes
- private long mFastestInterval = (long)(mInterval / FASTEST_INTERVAL_FACTOR); // 10 minutes
+ private long mFastestInterval = (long) (mInterval / FASTEST_INTERVAL_FACTOR); // 10 minutes
private boolean mExplicitFastestInterval = false;
private long mExpireAt = Long.MAX_VALUE; // no expiry
private int mNumUpdates = Integer.MAX_VALUE; // no expiry
private WorkSource mWorkSource = null;
private boolean mHideFromAppOps = false; // True if this request shouldn't be counted by AppOps
- private String mProvider = LocationManager.FUSED_PROVIDER; // for deprecated APIs that explicitly request a provider
+ private String mProvider = LocationManager.FUSED_PROVIDER;
+ // for deprecated APIs that explicitly request a provider
+
+ /** If true, GNSS chipset will make strong tradeoffs to substantially restrict power use */
+ private boolean mLowPowerMode = false;
/**
* Create a location request with default parameters.
}
LocationRequest request = new LocationRequest()
- .setProvider(provider)
- .setQuality(quality)
- .setInterval(minTime)
- .setFastestInterval(minTime)
- .setSmallestDisplacement(minDistance);
+ .setProvider(provider)
+ .setQuality(quality)
+ .setInterval(minTime)
+ .setFastestInterval(minTime)
+ .setSmallestDisplacement(minDistance);
if (singleShot) request.setNumUpdates(1);
return request;
}
}
LocationRequest request = new LocationRequest()
- .setQuality(quality)
- .setInterval(minTime)
- .setFastestInterval(minTime)
- .setSmallestDisplacement(minDistance);
+ .setQuality(quality)
+ .setInterval(minTime)
+ .setFastestInterval(minTime)
+ .setSmallestDisplacement(minDistance);
if (singleShot) request.setNumUpdates(1);
return request;
}
/** @hide */
- public LocationRequest() { }
+ public LocationRequest() {
+ }
/** @hide */
public LocationRequest(LocationRequest src) {
mProvider = src.mProvider;
mWorkSource = src.mWorkSource;
mHideFromAppOps = src.mHideFromAppOps;
+ mLowPowerMode = src.mLowPowerMode;
}
/**
* on a location request.
*
* @param quality an accuracy or power constant
- * @throws InvalidArgumentException if the quality constant is not valid
* @return the same object, so that setters can be chained
+ * @throws InvalidArgumentException if the quality constant is not valid
*/
public LocationRequest setQuality(int quality) {
checkQuality(quality);
* on a location request.
*
* @param millis desired interval in millisecond, inexact
- * @throws InvalidArgumentException if the interval is less than zero
* @return the same object, so that setters can be chained
+ * @throws InvalidArgumentException if the interval is less than zero
*/
public LocationRequest setInterval(long millis) {
checkInterval(millis);
mInterval = millis;
if (!mExplicitFastestInterval) {
- mFastestInterval = (long)(mInterval / FASTEST_INTERVAL_FACTOR);
+ mFastestInterval = (long) (mInterval / FASTEST_INTERVAL_FACTOR);
}
return this;
}
return mInterval;
}
+
+ /**
+ * Requests the GNSS chipset to run in a low power mode and make strong tradeoffs to
+ * substantially restrict power.
+ *
+ * <p>In this mode, the GNSS chipset will not, on average, run power hungry operations like RF &
+ * signal searches for more than one second per interval {@link #mInterval}
+ *
+ * @param enabled Enable or disable low power mode
+ * @return the same object, so that setters can be chained
+ * @hide
+ */
+ @SystemApi
+ public LocationRequest setLowPowerMode(boolean enabled) {
+ mLowPowerMode = enabled;
+ return this;
+ }
+
+ /**
+ * Returns true if low power mode is enabled.
+ *
+ * @hide
+ */
+ @SystemApi
+ public boolean isLowPowerMode() {
+ return mLowPowerMode;
+ }
+
/**
* Explicitly set the fastest interval for location updates, in
* milliseconds.
* then your effective fastest interval is {@link #setInterval}.
*
* @param millis fastest interval for updates in milliseconds, exact
- * @throws InvalidArgumentException if the interval is less than zero
* @return the same object, so that setters can be chained
+ * @throws InvalidArgumentException if the interval is less than zero
*/
public LocationRequest setFastestInterval(long millis) {
checkInterval(millis);
// Check for > Long.MAX_VALUE overflow (elapsedRealtime > 0):
if (millis > Long.MAX_VALUE - elapsedRealtime) {
- mExpireAt = Long.MAX_VALUE;
+ mExpireAt = Long.MAX_VALUE;
} else {
- mExpireAt = millis + elapsedRealtime;
+ mExpireAt = millis + elapsedRealtime;
}
if (mExpireAt < 0) mExpireAt = 0;
* to the location manager.
*
* @param numUpdates the number of location updates requested
- * @throws InvalidArgumentException if numUpdates is 0 or less
* @return the same object, so that setters can be chained
+ * @throws InvalidArgumentException if numUpdates is 0 or less
*/
public LocationRequest setNumUpdates(int numUpdates) {
- if (numUpdates <= 0) throw new IllegalArgumentException("invalid numUpdates: " + numUpdates);
+ if (numUpdates <= 0) {
+ throw new IllegalArgumentException(
+ "invalid numUpdates: " + numUpdates);
+ }
mNumUpdates = numUpdates;
return this;
}
*
* <p>By default this is {@link Integer#MAX_VALUE}, which indicates that
* locations are updated until the request is explicitly removed.
+ *
* @return number of updates
*/
public int getNumUpdates() {
* doesn't have the {@link android.Manifest.permission#UPDATE_APP_OPS_STATS} permission.
*
* @param hideFromAppOps If true AppOps won't keep track of this location request.
- * @see android.app.AppOpsManager
* @hide
+ * @see android.app.AppOpsManager
*/
@SystemApi
public void setHideFromAppOps(boolean hideFromAppOps) {
public static final Parcelable.Creator<LocationRequest> CREATOR =
new Parcelable.Creator<LocationRequest>() {
- @Override
- public LocationRequest createFromParcel(Parcel in) {
- LocationRequest request = new LocationRequest();
- request.setQuality(in.readInt());
- request.setFastestInterval(in.readLong());
- request.setInterval(in.readLong());
- request.setExpireAt(in.readLong());
- request.setNumUpdates(in.readInt());
- request.setSmallestDisplacement(in.readFloat());
- request.setHideFromAppOps(in.readInt() != 0);
- String provider = in.readString();
- if (provider != null) request.setProvider(provider);
- WorkSource workSource = in.readParcelable(null);
- if (workSource != null) request.setWorkSource(workSource);
- return request;
- }
- @Override
- public LocationRequest[] newArray(int size) {
- return new LocationRequest[size];
- }
- };
+ @Override
+ public LocationRequest createFromParcel(Parcel in) {
+ LocationRequest request = new LocationRequest();
+ request.setQuality(in.readInt());
+ request.setFastestInterval(in.readLong());
+ request.setInterval(in.readLong());
+ request.setExpireAt(in.readLong());
+ request.setNumUpdates(in.readInt());
+ request.setSmallestDisplacement(in.readFloat());
+ request.setHideFromAppOps(in.readInt() != 0);
+ request.setLowPowerMode(in.readInt() != 0);
+ String provider = in.readString();
+ if (provider != null) request.setProvider(provider);
+ WorkSource workSource = in.readParcelable(null);
+ if (workSource != null) request.setWorkSource(workSource);
+ return request;
+ }
+
+ @Override
+ public LocationRequest[] newArray(int size) {
+ return new LocationRequest[size];
+ }
+ };
@Override
public int describeContents() {
parcel.writeInt(mNumUpdates);
parcel.writeFloat(mSmallestDisplacement);
parcel.writeInt(mHideFromAppOps ? 1 : 0);
+ parcel.writeInt(mLowPowerMode ? 1 : 0);
parcel.writeString(mProvider);
parcel.writeParcelable(mWorkSource, 0);
}
s.append(" expireIn=");
TimeUtils.formatDuration(expireIn, s);
}
- if (mNumUpdates != Integer.MAX_VALUE){
+ if (mNumUpdates != Integer.MAX_VALUE) {
s.append(" num=").append(mNumUpdates);
}
+ s.append(" lowPowerMode=").append(mLowPowerMode);
s.append(']');
return s.toString();
}
public long interval = Long.MAX_VALUE;
/**
+ * Whether provider shall make stronger than normal tradeoffs to substantially restrict power
+ * use.
+ */
+ public boolean lowPowerMode = false;
+
+ /**
* A more detailed set of requests.
* <p>Location Providers can optionally use this to
* fine tune location updates, for example when there
*/
public List<LocationRequest> locationRequests = new ArrayList<LocationRequest>();
- public ProviderRequest() { }
+ public ProviderRequest() {
+ }
public static final Parcelable.Creator<ProviderRequest> CREATOR =
new Parcelable.Creator<ProviderRequest>() {
- @Override
- public ProviderRequest createFromParcel(Parcel in) {
- ProviderRequest request = new ProviderRequest();
- request.reportLocation = in.readInt() == 1;
- request.interval = in.readLong();
- int count = in.readInt();
- for (int i = 0; i < count; i++) {
- request.locationRequests.add(LocationRequest.CREATOR.createFromParcel(in));
- }
- return request;
- }
- @Override
- public ProviderRequest[] newArray(int size) {
- return new ProviderRequest[size];
- }
- };
+ @Override
+ public ProviderRequest createFromParcel(Parcel in) {
+ ProviderRequest request = new ProviderRequest();
+ request.reportLocation = in.readInt() == 1;
+ request.interval = in.readLong();
+ request.lowPowerMode = in.readBoolean();
+ int count = in.readInt();
+ for (int i = 0; i < count; i++) {
+ request.locationRequests.add(LocationRequest.CREATOR.createFromParcel(in));
+ }
+ return request;
+ }
+
+ @Override
+ public ProviderRequest[] newArray(int size) {
+ return new ProviderRequest[size];
+ }
+ };
@Override
public int describeContents() {
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(reportLocation ? 1 : 0);
parcel.writeLong(interval);
+ parcel.writeBoolean(lowPowerMode);
parcel.writeInt(locationRequests.size());
for (LocationRequest request : locationRequests) {
request.writeToParcel(parcel, flags);
s.append("ON");
s.append(" interval=");
TimeUtils.formatDuration(interval, s);
+ s.append(" lowPowerMode=" + lowPowerMode);
} else {
s.append("OFF");
}
dumpSetting(s, p,
Settings.Global.GPU_DEBUG_LAYERS,
GlobalSettingsProto.GPU_DEBUG_LAYERS);
+ dumpSetting(s, p,
+ Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING,
+ GlobalSettingsProto.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING);
// Settings.Global.SHOW_PROCESSES intentionally excluded since it's deprecated.
dumpSetting(s, p,
Settings.Global.LOW_POWER_MODE,
import android.annotation.NonNull;
import android.util.ArrayMap;
import android.util.ArraySet;
+
import com.android.internal.content.PackageMonitor;
import com.android.internal.location.ProviderProperties;
import com.android.internal.location.ProviderRequest;
private static final long HIGH_POWER_INTERVAL_MS = 5 * 60 * 1000;
private static final int FOREGROUND_IMPORTANCE_CUTOFF
- = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
+ = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
// default background throttling interval if not overriden in settings
private static final long DEFAULT_BACKGROUND_THROTTLE_INTERVAL_MS = 30 * 60 * 1000;
// current active user on the device - other users are denied location data
private int mCurrentUserId = UserHandle.USER_SYSTEM;
- private int[] mCurrentUserProfiles = new int[] { UserHandle.USER_SYSTEM };
+ private int[] mCurrentUserProfiles = new int[]{UserHandle.USER_SYSTEM};
private GnssLocationProvider.GnssSystemInfoProvider mGnssSystemInfoProvider;
public LocationManagerService(Context context) {
super();
mContext = context;
- mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
+ mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
// Let the package manager query which are the default location
// providers as they get certain permissions granted by default.
}
}, UserHandle.USER_ALL);
mContext.getContentResolver().registerContentObserver(
- Settings.Global.getUriFor(
- Settings.Global.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST),
- true,
- new ContentObserver(mLocationHandler) {
- @Override
- public void onChange(boolean selfChange) {
- synchronized (mLock) {
- updateBackgroundThrottlingWhitelistLocked();
- updateProvidersLocked();
+ Settings.Global.getUriFor(
+ Settings.Global.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST),
+ true,
+ new ContentObserver(mLocationHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ synchronized (mLock) {
+ updateBackgroundThrottlingWhitelistLocked();
+ updateProvidersLocked();
+ }
}
- }
- }, UserHandle.USER_ALL);
+ }, UserHandle.USER_ALL);
mPackageMonitor.register(mContext, mLocationHandler.getLooper(), true);
// listen for user change
updateUserProfiles(mCurrentUserId);
} else if (Intent.ACTION_SHUTDOWN.equals(action)) {
// shutdown only if UserId indicates whole system, not just one user
- if(D) Log.d(TAG, "Shutdown received with UserId: " + getSendingUserId());
+ if (D) Log.d(TAG, "Shutdown received with UserId: " + getSendingUserId());
if (getSendingUserId() == UserHandle.USER_ALL) {
shutdownComponents();
}
HashSet<String> affectedProviders = new HashSet<>(mRecordsByProvider.size());
synchronized (mLock) {
for (Entry<String, ArrayList<UpdateRecord>> entry
- : mRecordsByProvider.entrySet()) {
+ : mRecordsByProvider.entrySet()) {
String provider = entry.getKey();
for (UpdateRecord record : entry.getValue()) {
if (record.mReceiver.mIdentity.mUid == uid
- && record.mIsForegroundUid != foreground) {
- if (D) Log.d(TAG, "request from uid " + uid + " is now "
- + (foreground ? "foreground" : "background)"));
+ && record.mIsForegroundUid != foreground) {
+ if (D) {
+ Log.d(TAG, "request from uid " + uid + " is now "
+ + (foreground ? "foreground" : "background)"));
+ }
record.mIsForegroundUid = foreground;
if (!isThrottlingExemptLocked(record.mReceiver.mIdentity)) {
}
for (Entry<IGnssMeasurementsListener, Identity> entry
- : mGnssMeasurementsListeners.entrySet()) {
+ : mGnssMeasurementsListeners.entrySet()) {
if (entry.getValue().mUid == uid) {
- if (D) Log.d(TAG, "gnss measurements listener from uid " + uid
- + " is now " + (foreground ? "foreground" : "background)"));
+ if (D) {
+ Log.d(TAG, "gnss measurements listener from uid " + uid
+ + " is now " + (foreground ? "foreground" : "background)"));
+ }
if (foreground || isThrottlingExemptLocked(entry.getValue())) {
mGnssMeasurementsProvider.addListener(entry.getKey());
} else {
}
for (Entry<IGnssNavigationMessageListener, Identity> entry
- : mGnssNavigationMessageListeners.entrySet()) {
+ : mGnssNavigationMessageListeners.entrySet()) {
if (entry.getValue().mUid == uid) {
- if (D) Log.d(TAG, "gnss navigation message listener from uid "
- + uid + " is now "
- + (foreground ? "foreground" : "background)"));
+ if (D) {
+ Log.d(TAG, "gnss navigation message listener from uid "
+ + uid + " is now "
+ + (foreground ? "foreground" : "background)"));
+ }
if (foreground || isThrottlingExemptLocked(entry.getValue())) {
mGnssNavigationMessageProvider.addListener(entry.getKey());
} else {
* support for components that do not wish to handle such event.
*/
private void shutdownComponents() {
- if(D) Log.d(TAG, "Shutting down components...");
+ if (D) Log.d(TAG, "Shutting down components...");
LocationProviderInterface gpsProvider = mProvidersByName.get(LocationManager.GPS_PROVIDER);
if (gpsProvider != null && gpsProvider.isEnabled()) {
// as a proxy for coreApp="true"
if (pm.checkSignatures(systemPackageName, packageName)
!= PackageManager.SIGNATURE_MATCH) {
- if (D) Log.d(TAG, "Fallback candidate not signed the same as system: "
- + packageName);
+ if (D) {
+ Log.d(TAG, "Fallback candidate not signed the same as system: "
+ + packageName);
+ }
continue;
}
ArrayList<String> providerPackageNames = new ArrayList<>();
String[] pkgs = resources.getStringArray(
com.android.internal.R.array.config_locationProviderPackageNames);
- if (D) Log.d(TAG, "certificates for location providers pulled from: " +
- Arrays.toString(pkgs));
+ if (D) {
+ Log.d(TAG, "certificates for location providers pulled from: " +
+ Arrays.toString(pkgs));
+ }
if (pkgs != null) providerPackageNames.addAll(Arrays.asList(pkgs));
ensureFallbackFusedProviderPresentLocked(providerPackageNames);
mProxyProviders.add(networkProvider);
addProviderLocked(networkProvider);
} else {
- Slog.w(TAG, "no network location provider found");
+ Slog.w(TAG, "no network location provider found");
}
// bind to fused provider
com.android.internal.R.array.config_locationProviderPackageNames,
mLocationHandler);
if (mGeocodeProvider == null) {
- Slog.e(TAG, "no geocoder provider found");
+ Slog.e(TAG, "no geocoder provider found");
}
// bind to fused hardware provider if supported
// bind to geofence provider
GeofenceProxy provider = GeofenceProxy.createAndBind(
- mContext,com.android.internal.R.bool.config_enableGeofenceOverlay,
+ mContext, com.android.internal.R.bool.config_enableGeofenceOverlay,
com.android.internal.R.string.config_geofenceProviderPackageName,
com.android.internal.R.array.config_locationProviderPackageNames,
mLocationHandler,
mGpsGeofenceProxy,
flpHardwareProvider != null ? flpHardwareProvider.getGeofenceHardware() : null);
if (provider == null) {
- Slog.d(TAG, "Unable to bind FLP Geofence proxy.");
+ Slog.d(TAG, "Unable to bind FLP Geofence proxy.");
}
// bind to hardware activity recognition
/**
* Called when the device's active user changes.
+ *
* @param userId the new active user's UserId
*/
private void switchUser(int userId) {
final boolean mHideFromAppOps; // True if AppOps should not monitor this receiver.
final Object mKey;
- final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<>();
+ final HashMap<String, UpdateRecord> mUpdateRecords = new HashMap<>();
// True if app ops has started monitoring this receiver for locations.
boolean mOpMonitoring;
/**
* Update AppOps monitoring for a single location request and op type.
*
- * @param allowMonitoring True if monitoring is allowed for this request/op.
+ * @param allowMonitoring True if monitoring is allowed for this request/op.
* @param currentlyMonitoring True if AppOps is currently monitoring this request/op.
- * @param op AppOps code for the op to update.
+ * @param op AppOps code for the op to update.
* @return True if monitoring is on for this request/op after updating.
*/
private boolean updateMonitoring(boolean allowMonitoring, boolean currentlyMonitoring,
}
} else {
Intent locationChanged = new Intent();
- locationChanged.putExtra(LocationManager.KEY_LOCATION_CHANGED, new Location(location));
+ locationChanged.putExtra(LocationManager.KEY_LOCATION_CHANGED,
+ new Location(location));
try {
synchronized (this) {
// synchronize to ensure incrementPendingBroadcastsLocked()
}
if (mGnssBatchingProvider != null) {
- mGnssBatchingProvider.flush();
+ mGnssBatchingProvider.flush();
}
}
if (mGnssBatchingProvider != null) {
mGnssBatchingInProgress = false;
return mGnssBatchingProvider.stop();
- } else {
+ } else {
return false;
}
}
* processes belonging to background users.
*
* @param provider the name of the location provider
- * @param uid the requestor's UID
+ * @param uid the requestor's UID
*/
private boolean isAllowedByUserSettingsLocked(String provider, int uid) {
if (!isCurrentProfile(UserHandle.getUserId(uid)) && !isUidALocationProvider(uid)) {
* location provider.
*
* @param allowedResolutionLevel resolution level allowed to caller
- * @param providerName the name of the location provider
+ * @param providerName the name of the location provider
*/
private void checkResolutionLevelIsSufficientForProviderUse(int allowedResolutionLevel,
String providerName) {
resolver,
Settings.Global.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS,
DEFAULT_BACKGROUND_THROTTLE_INTERVAL_MS);
+ // initialize the low power mode to true and set to false if any of the records requires
+ providerRequest.lowPowerMode = true;
if (records != null) {
for (UpdateRecord record : records) {
if (isCurrentProfile(UserHandle.getUserId(record.mReceiver.mIdentity.mUid))) {
record.mRequest = locationRequest;
providerRequest.locationRequests.add(locationRequest);
+ if (!locationRequest.isLowPowerMode()) {
+ providerRequest.lowPowerMode = false;
+ }
if (interval < providerRequest.interval) {
providerRequest.reportLocation = true;
providerRequest.interval = interval;
public String[] getBackgroundThrottlingWhitelist() {
synchronized (mLock) {
return mBackgroundThrottlePackageWhitelist.toArray(
- new String[mBackgroundThrottlePackageWhitelist.size()]);
+ new String[mBackgroundThrottlePackageWhitelist.size()]);
}
}
private void updateBackgroundThrottlingWhitelistLocked() {
String setting = Settings.Global.getString(
- mContext.getContentResolver(),
- Settings.Global.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST);
+ mContext.getContentResolver(),
+ Settings.Global.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST);
if (setting == null) {
setting = "";
}
mBackgroundThrottlePackageWhitelist.clear();
mBackgroundThrottlePackageWhitelist.addAll(
- SystemConfig.getInstance().getAllowUnthrottledLocation());
+ SystemConfig.getInstance().getAllowUnthrottledLocation());
mBackgroundThrottlePackageWhitelist.addAll(
- Arrays.asList(setting.split(",")));
+ Arrays.asList(setting.split(",")));
}
private boolean isThrottlingExemptLocked(Identity identity) {
@Override
public String toString() {
return "UpdateRecord[" + mProvider + " " + mReceiver.mIdentity.mPackageName
- + "(" + mReceiver.mIdentity.mUid + (mIsForegroundUid ? " foreground" : " background")
+ + "(" + mReceiver.mIdentity.mUid + (mIsForegroundUid ? " foreground"
+ : " background")
+ ")" + " " + mRealRequest + "]";
}
}
* @return a version of request that meets the given resolution and consistency requirements
* @hide
*/
- private LocationRequest createSanitizedRequest(LocationRequest request, int resolutionLevel) {
+ private LocationRequest createSanitizedRequest(LocationRequest request, int resolutionLevel,
+ boolean callerHasLocationHardwarePermission) {
LocationRequest sanitizedRequest = new LocationRequest(request);
+ if (!callerHasLocationHardwarePermission) {
+ // allow setting low power mode only for callers with location hardware permission
+ sanitizedRequest.setLowPowerMode(false);
+ }
if (resolutionLevel < RESOLUTION_LEVEL_FINE) {
switch (sanitizedRequest.getQuality()) {
case LocationRequest.ACCURACY_FINE:
if (hideFromAppOps) {
checkUpdateAppOpsAllowed();
}
- LocationRequest sanitizedRequest = createSanitizedRequest(request, allowedResolutionLevel);
+ boolean callerHasLocationHardwarePermission =
+ mContext.checkCallingPermission(android.Manifest.permission.LOCATION_HARDWARE)
+ == PackageManager.PERMISSION_GRANTED;
+ LocationRequest sanitizedRequest = createSanitizedRequest(request, allowedResolutionLevel,
+ callerHasLocationHardwarePermission);
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
}
UpdateRecord record = new UpdateRecord(name, request, receiver);
- if (D) Log.d(TAG, "request " + Integer.toHexString(System.identityHashCode(receiver))
- + " " + name + " " + request + " from " + packageName + "(" + uid + " "
- + (record.mIsForegroundUid ? "foreground" : "background")
- + (isThrottlingExemptLocked(receiver.mIdentity)
+ if (D) {
+ Log.d(TAG, "request " + Integer.toHexString(System.identityHashCode(receiver))
+ + " " + name + " " + request + " from " + packageName + "(" + uid + " "
+ + (record.mIsForegroundUid ? "foreground" : "background")
+ + (isThrottlingExemptLocked(receiver.mIdentity)
? " [whitelisted]" : "") + ")");
+ }
UpdateRecord oldRecord = receiver.mUpdateRecords.put(name, record);
if (oldRecord != null) {
final long identity = Binder.clearCallingIdentity();
try {
if (mBlacklist.isBlacklisted(packageName)) {
- if (D) Log.d(TAG, "not returning last loc for blacklisted app: " +
- packageName);
+ if (D) {
+ Log.d(TAG, "not returning last loc for blacklisted app: " +
+ packageName);
+ }
return null;
}
if (!reportLocationAccessNoThrow(pid, uid, packageName, allowedResolutionLevel)) {
- if (D) Log.d(TAG, "not returning last loc for no op app: " +
- packageName);
+ if (D) {
+ Log.d(TAG, "not returning last loc for no op app: " +
+ packageName);
+ }
return null;
}
return null;
}
if (allowedResolutionLevel < RESOLUTION_LEVEL_FINE) {
- Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION);
+ Location noGPSLocation = location.getExtraLocation(
+ Location.EXTRA_NO_GPS_LOCATION);
if (noGPSLocation != null) {
return new Location(mLocationFudger.getOrCreate(noGPSLocation));
}
checkPackageName(packageName);
checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel,
request.getProvider());
- LocationRequest sanitizedRequest = createSanitizedRequest(request, allowedResolutionLevel);
+ // Require that caller can manage given document
+ boolean callerHasLocationHardwarePermission =
+ mContext.checkCallingPermission(android.Manifest.permission.LOCATION_HARDWARE)
+ == PackageManager.PERMISSION_GRANTED;
+ LocationRequest sanitizedRequest = createSanitizedRequest(request, allowedResolutionLevel,
+ callerHasLocationHardwarePermission);
if (D) Log.d(TAG, "requestGeofence: " + sanitizedRequest + " " + geofence + " " + intent);
@Override
public boolean addGnssMeasurementsListener(
- IGnssMeasurementsListener listener,
- String packageName) {
+ IGnssMeasurementsListener listener, String packageName) {
if (!hasGnssPermissions(packageName) || mGnssMeasurementsProvider == null) {
return false;
}
try {
if (isThrottlingExemptLocked(callerIdentity)
|| isImportanceForeground(
- mActivityManager.getPackageImportance(packageName))) {
+ mActivityManager.getPackageImportance(packageName))) {
return mGnssMeasurementsProvider.addListener(listener);
}
} finally {
synchronized (mLock) {
Identity callerIdentity
- = new Identity(Binder.getCallingUid(), Binder.getCallingPid(), packageName);
+ = new Identity(Binder.getCallingUid(), Binder.getCallingPid(), packageName);
mGnssNavigationMessageListeners.put(listener, callerIdentity);
long identity = Binder.clearCallingIdentity();
try {
if (isThrottlingExemptLocked(callerIdentity)
|| isImportanceForeground(
- mActivityManager.getPackageImportance(packageName))) {
+ mActivityManager.getPackageImportance(packageName))) {
return mGnssNavigationMessageProvider.addListener(listener);
}
} finally {
/**
* @return null if the provider does not exist
* @throws SecurityException if the provider is not allowed to be
- * accessed by the caller
+ * accessed by the caller
*/
@Override
public ProviderProperties getProviderProperties(String provider) {
/**
* @return null if the provider does not exist
* @throws SecurityException if the provider is not allowed to be
- * accessed by the caller
+ * accessed by the caller
*/
@Override
public String getNetworkProviderPackage() {
}
if (mBlacklist.isBlacklisted(receiver.mIdentity.mPackageName)) {
- if (D) Log.d(TAG, "skipping loc update for blacklisted app: " +
- receiver.mIdentity.mPackageName);
+ if (D) {
+ Log.d(TAG, "skipping loc update for blacklisted app: " +
+ receiver.mIdentity.mPackageName);
+ }
continue;
}
receiver.mIdentity.mUid,
receiver.mIdentity.mPackageName,
receiver.mAllowedResolutionLevel)) {
- if (D) Log.d(TAG, "skipping loc update for no op app: " +
- receiver.mIdentity.mPackageName);
+ if (D) {
+ Log.d(TAG, "skipping loc update for no op app: " +
+ receiver.mIdentity.mPackageName);
+ }
continue;
}
}
pw.append(" fudger: ");
- mLocationFudger.dump(fd, pw, args);
+ mLocationFudger.dump(fd, pw, args);
if (args.length > 0 && "short".equals(args[0])) {
return;
}
- for (LocationProviderInterface provider: mProviders) {
+ for (LocationProviderInterface provider : mProviders) {
pw.print(provider.getName() + " Internal State");
if (provider instanceof LocationProviderProxy) {
LocationProviderProxy proxy = (LocationProviderProxy) provider;
private static final int AGPS_SETID_TYPE_IMSI = 1;
private static final int AGPS_SETID_TYPE_MSISDN = 2;
- private static final int GPS_GEOFENCE_UNAVAILABLE = 1<<0L;
- private static final int GPS_GEOFENCE_AVAILABLE = 1<<1L;
+ private static final int GPS_GEOFENCE_UNAVAILABLE = 1 << 0L;
+ private static final int GPS_GEOFENCE_AVAILABLE = 1 << 1L;
// GPS Geofence errors. Should match GeofenceStatus enum in IGnssGeofenceCallback.hal.
private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0;
private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100;
- private static final int GPS_GEOFENCE_ERROR_ID_EXISTS = -101;
+ private static final int GPS_GEOFENCE_ERROR_ID_EXISTS = -101;
private static final int GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102;
private static final int GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103;
private static final int GPS_GEOFENCE_ERROR_GENERIC = -149;
private static class GpsRequest {
public ProviderRequest request;
public WorkSource source;
+
public GpsRequest(ProviderRequest request, WorkSource source) {
this.request = request;
this.source = source;
// how often to request NTP time, in milliseconds
// current setting 24 hours
- private static final long NTP_INTERVAL = 24*60*60*1000;
+ private static final long NTP_INTERVAL = 24 * 60 * 60 * 1000;
// how long to wait if we have a network error in NTP or XTRA downloading
// the initial value of the exponential backoff
// current setting - 5 minutes
- private static final long RETRY_INTERVAL = 5*60*1000;
+ private static final long RETRY_INTERVAL = 5 * 60 * 1000;
// how long to wait if we have a network error in NTP or XTRA downloading
// the max value of the exponential backoff
// current setting - 4 hours
- private static final long MAX_RETRY_INTERVAL = 4*60*60*1000;
+ private static final long MAX_RETRY_INTERVAL = 4 * 60 * 60 * 1000;
// Timeout when holding wakelocks for downloading XTRA data.
private static final long DOWNLOAD_XTRA_DATA_TIMEOUT_MS = 60 * 1000;
// requested frequency of fixes, in milliseconds
private int mFixInterval = 1000;
+ // true if low power mode for the GNSS chipset is part of the latest request.
+ private boolean mLowPowerMode = false;
+
// true if we started navigation
private boolean mStarted;
private final static String LPP_PROFILE = "persist.sys.gps.lpp";
-
private final PowerManager mPowerManager;
private final AlarmManager mAlarmManager;
private final PendingIntent mWakeupIntent;
*/
private final ConnectivityManager.NetworkCallback mNetworkConnectivityCallback =
new ConnectivityManager.NetworkCallback() {
- @Override
- public void onAvailable(Network network) {
- if (mInjectNtpTimePending == STATE_PENDING_NETWORK) {
- requestUtcTime();
- }
- if (mDownloadXtraDataPending == STATE_PENDING_NETWORK) {
- if (mSupportsXtra) {
- // Download only if supported, (prevents an unneccesary on-boot download)
- xtraDownloadRequest();
+ @Override
+ public void onAvailable(Network network) {
+ if (mInjectNtpTimePending == STATE_PENDING_NETWORK) {
+ requestUtcTime();
+ }
+ if (mDownloadXtraDataPending == STATE_PENDING_NETWORK) {
+ if (mSupportsXtra) {
+ // Download only if supported, (prevents an unneccesary on-boot
+ // download)
+ xtraDownloadRequest();
+ }
+ }
+ // Always on, notify HAL so it can get data it needs
+ sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
}
- }
- // Always on, notify HAL so it can get data it needs
- sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
- }
- @Override
- public void onLost(Network network) {
- sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
- }
- };
+ @Override
+ public void onLost(Network network) {
+ sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
+ }
+ };
/**
* Callback used to listen for availability of a requested SUPL connection.
*/
private final ConnectivityManager.NetworkCallback mSuplConnectivityCallback =
new ConnectivityManager.NetworkCallback() {
- @Override
- public void onAvailable(Network network) {
- // Specific to a change to a SUPL enabled network becoming ready
- sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
- }
+ @Override
+ public void onAvailable(Network network) {
+ // Specific to a change to a SUPL enabled network becoming ready
+ sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
+ }
- @Override
- public void onLost(Network network) {
- releaseSuplConnection(GPS_RELEASE_AGPS_DATA_CONN);
- }
- };
+ @Override
+ public void onLost(Network network) {
+ releaseSuplConnection(GPS_RELEASE_AGPS_DATA_CONN);
+ }
+ };
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
- @Override public void onReceive(Context context, Intent intent) {
+ @Override
+ public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action);
if (action == null) {
private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
new OnSubscriptionsChangedListener() {
- @Override
- public void onSubscriptionsChanged() {
- sendMessage(SUBSCRIPTION_OR_SIM_CHANGED, 0, null);
- }
- };
+ @Override
+ public void onSubscriptionsChanged() {
+ sendMessage(SUBSCRIPTION_OR_SIM_CHANGED, 0, null);
+ }
+ };
private void subscriptionOrSimChanged(Context context) {
if (DEBUG) Log.d(TAG, "received SIM related action: ");
String lpp_prof = SystemProperties.get(LPP_PROFILE);
if (!TextUtils.isEmpty(lpp_prof)) {
- // override default value of this if lpp_prof is not empty
- properties.setProperty("LPP_PROFILE", lpp_prof);
+ // override default value of this if lpp_prof is not empty
+ properties.setProperty("LPP_PROFILE", lpp_prof);
}
/*
* Overlay carrier properties from a debug configuration file.
loadPropertiesFromFile(DEBUG_PROPERTIES_FILE, properties);
// TODO: we should get rid of C2K specific setting.
setSuplHostPort(properties.getProperty("SUPL_HOST"),
- properties.getProperty("SUPL_PORT"));
+ properties.getProperty("SUPL_PORT"));
mC2KServerHost = properties.getProperty("C2K_HOST");
String portString = properties.getProperty("C2K_PORT");
if (mC2KServerHost != null && portString != null) {
put("SUPL_MODE", (val) -> native_set_supl_mode(val));
put("SUPL_ES", (val) -> native_set_supl_es(val));
put("LPP_PROFILE", (val) -> native_set_lpp_profile(val));
- put("A_GLONASS_POS_PROTOCOL_SELECT", (val) -> native_set_gnss_pos_protocol_select(val));
- put("USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL", (val) -> native_set_emergency_supl_pdn(val));
+ put("A_GLONASS_POS_PROTOCOL_SELECT",
+ (val) -> native_set_gnss_pos_protocol_select(val));
+ put("USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL",
+ (val) -> native_set_emergency_supl_pdn(val));
put("GPS_LOCK", (val) -> native_set_gps_lock(val));
}
};
- for(Entry<String, SetCarrierProperty> entry : map.entrySet()) {
+ for (Entry<String, SetCarrierProperty> entry : map.entrySet()) {
String propertyName = entry.getKey();
String propertyValueString = properties.getProperty(propertyName);
if (propertyValueString != null) {
try {
- int propertyValueInt = Integer.decode(propertyValueString);
- boolean result = entry.getValue().set(propertyValueInt);
- if (result == false) {
- Log.e(TAG, "Unable to set " + propertyName);
- }
+ int propertyValueInt = Integer.decode(propertyValueString);
+ boolean result = entry.getValue().set(propertyValueInt);
+ if (result == false) {
+ Log.e(TAG, "Unable to set " + propertyName);
+ }
} catch (NumberFormatException e) {
- Log.e(TAG, "unable to parse propertyName: " + propertyValueString);
+ Log.e(TAG, "unable to parse propertyName: " + propertyValueString);
}
}
}
}
private void loadPropertiesFromResource(Context context,
- Properties properties) {
+ Properties properties) {
String[] configValues = context.getResources().getStringArray(
com.android.internal.R.array.config_gpsParameters);
for (String item : configValues) {
}
private boolean loadPropertiesFromFile(String filename,
- Properties properties) {
+ Properties properties) {
try {
File file = new File(filename);
FileInputStream stream = null;
PowerManager.PARTIAL_WAKE_LOCK, DOWNLOAD_EXTRA_WAKELOCK_KEY);
mDownloadXtraWakeLock.setReferenceCounted(true);
- mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
+ mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
- mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ mConnMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
// App ops service to keep track of who is accessing the GPS
mAppOpsService = IAppOpsService.Stub.asInterface(ServiceManager.getService(
// Create a GPS net-initiated handler.
mNIHandler = new GpsNetInitiatedHandler(context,
- mNetInitiatedListener,
- mSuplEsEnabled);
+ mNetInitiatedListener,
+ mSuplEsEnabled);
mListenerHelper = new GnssStatusListenerHelper(mHandler) {
@Override
}
@Override
- protected boolean registerWithService() {
- return native_start_measurement_collection();
+ protected int registerWithService() {
+ int devOptions = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED , 0);
+ int fullTrackingToggled = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING , 0);
+ boolean result = false;
+ if (devOptions == 1 /* Developer Mode enabled */
+ && fullTrackingToggled == 1 /* Raw Measurements Full Tracking enabled */) {
+ result = native_start_measurement_collection(true /* enableFullTracking */);
+ } else {
+ result = native_start_measurement_collection(false /* enableFullTracking */);
+ }
+ if (result) {
+ return RemoteListenerHelper.RESULT_SUCCESS;
+ } else {
+ return RemoteListenerHelper.RESULT_INTERNAL_ERROR;
+ }
}
@Override
}
@Override
- protected boolean registerWithService() {
- return native_start_navigation_message_collection();
+ protected int registerWithService() {
+ boolean result = native_start_navigation_message_collection();
+ if (result) {
+ return RemoteListenerHelper.RESULT_SUCCESS;
+ } else {
+ return RemoteListenerHelper.RESULT_INTERNAL_ERROR;
+ }
}
@Override
* Checks what SUPL mode to use, according to the AGPS mode as well as the
* allowed mode from properties.
*
- * @param properties GPS properties
+ * @param properties GPS properties
* @param agpsEnabled whether AGPS is enabled by settings value
- * @param singleShot whether "singleshot" is needed
+ * @param singleShot whether "singleshot" is needed
* @return SUPL mode (MSA vs MSB vs STANDALONE)
*/
private int getSuplMode(Properties properties, boolean agpsEnabled, boolean singleShot) {
}
private void updateStatus(int status, int svCount, int meanCn0, int maxCn0) {
- if (status != mStatus || svCount != mSvCount || meanCn0 != mMeanCn0 || maxCn0 != mMaxCn0 ) {
+ if (status != mStatus || svCount != mSvCount || meanCn0 != mMeanCn0 || maxCn0 != mMaxCn0) {
mStatus = status;
mSvCount = svCount;
mMeanCn0 = meanCn0;
updateClientUids(mWorkSource);
mFixInterval = (int) mProviderRequest.interval;
-
+ mLowPowerMode = (boolean) mProviderRequest.lowPowerMode;
// check for overflow
if (mFixInterval != mProviderRequest.interval) {
Log.w(TAG, "interval overflow: " + mProviderRequest.interval);
// apply request to GPS engine
if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) {
- // change period
+ // change period and/or lowPowerMode
if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
- mFixInterval, 0, 0)) {
- Log.e(TAG, "set_position_mode failed in setMinTime()");
+ mFixInterval, 0, 0, mLowPowerMode)) {
+ Log.e(TAG, "set_position_mode failed in updateRequirements");
}
} else if (!mStarted) {
// start GPS
// Update sources that were not previously tracked.
if (newWork != null) {
int lastuid = -1;
- for (int i=0; i<newWork.size(); i++) {
+ for (int i = 0; i < newWork.size(); i++) {
try {
int uid = newWork.get(i);
mAppOpsService.startOperation(AppOpsManager.getToken(mAppOpsService),
// Update sources that are no longer tracked.
if (goneWork != null) {
int lastuid = -1;
- for (int i=0; i<goneWork.size(); i++) {
+ for (int i = 0; i < goneWork.size(); i++) {
try {
int uid = goneWork.get(i);
mAppOpsService.finishOperation(AppOpsManager.getToken(mAppOpsService),
boolean agpsEnabled =
(Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.ASSISTED_GPS_ENABLED, 1) != 0);
+ Settings.Global.ASSISTED_GPS_ENABLED, 1) != 0);
mPositionMode = getSuplMode(mProperties, agpsEnabled, singleShot);
if (DEBUG) {
String mode;
- switch(mPositionMode) {
+ switch (mPositionMode) {
case GPS_POSITION_MODE_STANDALONE:
mode = "standalone";
break;
}
int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000);
+ mLowPowerMode = (boolean) mProviderRequest.lowPowerMode;
if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
- interval, 0, 0)) {
+ interval, 0, 0, mLowPowerMode)) {
mStarted = false;
Log.e(TAG, "set_position_mode failed in startNavigating()");
return;
mLastFixTime = SystemClock.elapsedRealtime();
// report time to first fix
if (mTimeToFirstFix == 0 && hasLatLong) {
- mTimeToFirstFix = (int)(mLastFixTime - mFixRequestTime);
+ mTimeToFirstFix = (int) (mLastFixTime - mFixRequestTime);
if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);
mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);
updateStatus(LocationProvider.AVAILABLE, mSvCount, mMeanCn0, mMaxCn0);
}
- if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
- mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {
+ if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
+ mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {
if (DEBUG) Log.d(TAG, "got fix, hibernating");
hibernate();
}
- }
+ }
/**
* called from native code to update our status
*/
private void reportSvStatus() {
int svCount = native_read_sv_status(mSvidWithFlags,
- mCn0s,
- mSvElevations,
- mSvAzimuths,
- mSvCarrierFreqs);
+ mCn0s,
+ mSvElevations,
+ mSvAzimuths,
+ mSvCarrierFreqs);
mListenerHelper.onSvStatusChanged(
svCount,
mSvidWithFlags,
if ((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
++usedInFixCount;
if (mCn0s[i] > maxCn0) {
- maxCn0 = (int)mCn0s[i];
+ maxCn0 = (int) mCn0s[i];
}
meanCn0 += mCn0s[i];
}
((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0
? "" : "U") +
((mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) == 0
- ? "" : "F"));
+ ? "" : "F"));
}
}
if (usedInFixCount > 0) {
updateStatus(mStatus, usedInFixCount, meanCn0, maxCn0);
if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
- SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) {
+ SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) {
// send an intent to notify that the GPS is no longer receiving fixes.
Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false);
* Returns the GNSS batching size
*/
int getSize();
+
/**
* Starts the hardware batching operation
*/
boolean start(long periodNanos, boolean wakeOnFifoFull);
+
/**
* Forces a flush of existing locations from the hardware batching
*/
void flush();
+
/**
* Stops the batching operation
*/
public int getSize() {
return native_get_batch_size();
}
+
@Override
public boolean start(long periodNanos, boolean wakeOnFifoFull) {
if (periodNanos <= 0) {
}
return native_start_batch(periodNanos, wakeOnFifoFull);
}
+
@Override
public void flush() {
native_flush_batch();
}
+
@Override
public boolean stop() {
return native_stop_batch();
private void enableBatching() {
if (!native_init_batching()) {
Log.e(TAG, "Failed to initialize GNSS batching");
- };
+ }
}
/**
*/
private void reportLocationBatch(Location[] locationArray) {
List<Location> locations = new ArrayList<>(Arrays.asList(locationArray));
- if(DEBUG) { Log.d(TAG, "Location batch of size " + locationArray.length + "reported"); }
+ if (DEBUG) {
+ Log.d(TAG, "Location batch of size " + locationArray.length + " reported");
+ }
try {
mILocationManager.reportLocationBatch(locations);
} catch (RemoteException e) {
* Converts the GPS HAL status to the internal Geofence Hardware status.
*/
private int getGeofenceStatus(int status) {
- switch(status) {
+ switch (status) {
case GPS_GEOFENCE_OPERATION_SUCCESS:
return GeofenceHardware.GEOFENCE_SUCCESS;
case GPS_GEOFENCE_ERROR_GENERIC:
* All geofence callbacks are called on the same thread
*/
private void reportGeofenceTransition(int geofenceId, Location location, int transition,
- long transitionTimestamp) {
+ long transitionTimestamp) {
if (mGeofenceHardwareImpl == null) {
mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
}
mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
}
int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
- if(status == GPS_GEOFENCE_AVAILABLE) {
+ if (status == GPS_GEOFENCE_AVAILABLE) {
monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE;
}
mGeofenceHardwareImpl.reportGeofenceMonitorStatus(
private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() {
// Sends a response for an NI request to HAL.
@Override
- public boolean sendNiResponse(int notificationId, int userResponse)
- {
+ public boolean sendNiResponse(int notificationId, int userResponse) {
// TODO Add Permission check
- if (DEBUG) Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
- ", response: " + userResponse);
+ if (DEBUG) {
+ Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
+ ", response: " + userResponse);
+ }
native_send_ni_response(notificationId, userResponse);
return true;
}
String text,
int requestorIdEncoding,
int textEncoding
- )
- {
+ ) {
Log.i(TAG, "reportNiNotification: entered");
Log.i(TAG, "notificationId: " + notificationId +
", niType: " + niType +
notification.niType = niType;
notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
- notification.privacyOverride = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
+ notification.privacyOverride =
+ (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
notification.timeout = timeout;
notification.defaultResponse = defaultResponse;
notification.requestorId = requestorId;
data = data_temp;
type = AGPS_SETID_TYPE_IMSI;
}
- }
- else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) {
+ } else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) {
String data_temp = phone.getLine1Number();
if (data_temp == null) {
// This means the framework does not have the SIM card ready.
if ((gsm_cell != null) && (phone.getNetworkOperator() != null)
&& (phone.getNetworkOperator().length() > 3)) {
int type;
- int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0,3));
+ int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0, 3));
int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3));
int networkType = phone.getNetworkType();
if (networkType == TelephonyManager.NETWORK_TYPE_UMTS
- || networkType == TelephonyManager.NETWORK_TYPE_HSDPA
- || networkType == TelephonyManager.NETWORK_TYPE_HSUPA
- || networkType == TelephonyManager.NETWORK_TYPE_HSPA
- || networkType == TelephonyManager.NETWORK_TYPE_HSPAP) {
+ || networkType == TelephonyManager.NETWORK_TYPE_HSDPA
+ || networkType == TelephonyManager.NETWORK_TYPE_HSUPA
+ || networkType == TelephonyManager.NETWORK_TYPE_HSPA
+ || networkType == TelephonyManager.NETWORK_TYPE_HSPAP) {
type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID;
} else {
type = AGPS_REF_LOCATION_TYPE_GSM_CELLID;
native_agps_set_ref_location_cellid(type, mcc, mnc,
gsm_cell.getLac(), gsm_cell.getCid());
} else {
- Log.e(TAG,"Error getting cell location info.");
+ Log.e(TAG, "Error getting cell location info.");
}
} else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
Log.e(TAG, "CDMA not supported.");
* restart.
*/
boolean isInitialized = native_init();
- if(!isInitialized) {
+ if (!isInitialized) {
Log.w(TAG, "Native initialization failed at bootup");
} else {
native_cleanup();
reloadGpsProperties(mContext, mProperties);
// TODO: When this object "finishes" we should unregister by invoking
- // SubscriptionManager.getInstance(mContext).unregister(mOnSubscriptionsChangedListener);
+ // SubscriptionManager.getInstance(mContext).unregister
+ // (mOnSubscriptionsChangedListener);
// This is not strictly necessary because it will be unregistered if the
// notification fails but it is good form.
handleUpdateLocation(location);
}
}
+
@Override
- public void onStatusChanged(String provider, int status, Bundle extras) { }
+ public void onStatusChanged(String provider, int status, Bundle extras) {
+ }
+
@Override
- public void onProviderEnabled(String provider) { }
+ public void onProviderEnabled(String provider) {
+ }
+
@Override
- public void onProviderDisabled(String provider) { }
+ public void onProviderDisabled(String provider) {
+ }
}
private String getSelectedApn() {
try {
cursor = mContext.getContentResolver().query(
uri,
- new String[] { "apn" },
+ new String[]{"apn"},
null /* selection */,
null /* selectionArgs */,
Carriers.DEFAULT_SORT_ORDER);
try {
cursor = mContext.getContentResolver().query(
Carriers.CONTENT_URI,
- new String[] { Carriers.PROTOCOL },
+ new String[]{Carriers.PROTOCOL},
selection,
null,
Carriers.DEFAULT_SORT_ORDER);
/**
* @return {@code true} if there is a data network available for outgoing connections,
- * {@code false} otherwise.
+ * {@code false} otherwise.
*/
private boolean isDataNetworkConnected() {
NetworkInfo activeNetworkInfo = mConnMgr.getActiveNetworkInfo();
* @return A string representing the current state stored in {@link #mAGpsDataConnectionState}.
*/
private String agpsDataConnStateAsString() {
- switch(mAGpsDataConnectionState) {
+ switch (mAGpsDataConnectionState) {
case AGPS_DATA_CONNECTION_CLOSED:
return "CLOSED";
case AGPS_DATA_CONNECTION_OPEN:
}
-
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
StringBuilder s = new StringBuilder();
s.append(" mStarted=").append(mStarted).append('\n');
s.append(" mFixInterval=").append(mFixInterval).append('\n');
+ s.append(" mLowPowerMode=").append(mLowPowerMode).append('\n');
s.append(" mDisableGps (battery saver mode)=").append(mDisableGps).append('\n');
s.append(" mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities));
s.append(" ( ");
// preallocated to avoid memory allocation in reportNmea()
private byte[] mNmeaBuffer = new byte[120];
- static { class_init_native(); }
+ static {
+ class_init_native();
+ }
+
private static native void class_init_native();
+
private static native boolean native_is_supported();
+
private static native boolean native_is_agps_ril_supported();
+
private static native boolean native_is_gnss_configuration_supported();
private native boolean native_init();
+
private native void native_cleanup();
+
private native boolean native_set_position_mode(int mode, int recurrence, int min_interval,
- int preferred_accuracy, int preferred_time);
+ int preferred_accuracy, int preferred_time, boolean lowPowerMode);
+
private native boolean native_start();
+
private native boolean native_stop();
+
private native void native_delete_aiding_data(int flags);
+
// returns number of SVs
// mask[0] is ephemeris mask and mask[1] is almanac mask
private native int native_read_sv_status(int[] prnWithFlags, float[] cn0s, float[] elevations,
float[] azimuths, float[] carrierFrequencies);
+
private native int native_read_nmea(byte[] buffer, int bufferSize);
+
private native void native_inject_location(double latitude, double longitude, float accuracy);
// XTRA Support
private native void native_inject_time(long time, long timeReference, int uncertainty);
+
private native boolean native_supports_xtra();
+
private native void native_inject_xtra_data(byte[] data, int length);
// DEBUG Support
// AGPS Support
private native void native_agps_data_conn_open(String apn, int apnIpType);
+
private native void native_agps_data_conn_closed();
+
private native void native_agps_data_conn_failed();
- private native void native_agps_ni_message(byte [] msg, int length);
+
+ private native void native_agps_ni_message(byte[] msg, int length);
+
private native void native_set_agps_server(int type, String hostname, int port);
// Network-initiated (NI) Support
// AGPS ril suport
private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc,
int lac, int cid);
+
private native void native_agps_set_id(int type, String setid);
private native void native_update_network_state(boolean connected, int type,
// Hardware Geofence support.
private static native boolean native_is_geofence_supported();
+
private static native boolean native_add_geofence(int geofenceId, double latitude,
- double longitude, double radius, int lastTransition,int monitorTransitions,
+ double longitude, double radius, int lastTransition, int monitorTransitions,
int notificationResponsivenes, int unknownTimer);
+
private static native boolean native_remove_geofence(int geofenceId);
+
private static native boolean native_resume_geofence(int geofenceId, int transitions);
+
private static native boolean native_pause_geofence(int geofenceId);
// Gps Hal measurements support.
private static native boolean native_is_measurement_supported();
- private native boolean native_start_measurement_collection();
+
+ private native boolean native_start_measurement_collection(boolean enableFullTracking);
+
private native boolean native_stop_measurement_collection();
// Gps Navigation message support.
private static native boolean native_is_navigation_message_supported();
+
private native boolean native_start_navigation_message_collection();
+
private native boolean native_stop_navigation_message_collection();
// GNSS Configuration
private static native boolean native_set_supl_version(int version);
+
private static native boolean native_set_supl_mode(int mode);
+
private static native boolean native_set_supl_es(int es);
+
private static native boolean native_set_lpp_profile(int lppProfile);
+
private static native boolean native_set_gnss_pos_protocol_select(int gnssPosProtocolSelect);
+
private static native boolean native_set_gps_lock(int gpsLock);
+
private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn);
// GNSS Batching
private static native int native_get_batch_size();
+
private static native boolean native_start_batch(long periodNanos, boolean wakeOnFifoFull);
+
private static native void native_flush_batch();
+
private static native boolean native_stop_batch();
+
private static native boolean native_init_batching();
+
private static native void native_cleanup_batching();
}
public void onMeasurementsAvailable(final GnssMeasurementsEvent event) {
ListenerOperation<IGnssMeasurementsListener> operation =
new ListenerOperation<IGnssMeasurementsListener>() {
- @Override
- public void execute(IGnssMeasurementsListener listener) throws RemoteException {
- listener.onGnssMeasurementsReceived(event);
- }
- };
+ @Override
+ public void execute(IGnssMeasurementsListener listener) throws RemoteException {
+ listener.onGnssMeasurementsReceived(event);
+ }
+ };
foreach(operation);
}
case RESULT_INTERNAL_ERROR:
status = GnssMeasurementsEvent.Callback.STATUS_NOT_SUPPORTED;
break;
+ case RESULT_NOT_ALLOWED:
+ status = GnssMeasurementsEvent.Callback.STATUS_NOT_ALLOWED;
+ break;
case RESULT_GPS_LOCATION_DISABLED:
status = GnssMeasurementsEvent.Callback.STATUS_LOCATION_DISABLED;
break;
}
@Override
- protected boolean registerWithService() {
- return true;
+ protected int registerWithService() {
+ return RemoteListenerHelper.RESULT_SUCCESS;
}
@Override
package com.android.server.location;
-import com.android.internal.util.Preconditions;
-
import android.annotation.NonNull;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
-import java.lang.Runnable;
+import com.android.internal.util.Preconditions;
+
import java.util.HashMap;
import java.util.Map;
protected static final int RESULT_GPS_LOCATION_DISABLED = 3;
protected static final int RESULT_INTERNAL_ERROR = 4;
protected static final int RESULT_UNKNOWN = 5;
+ protected static final int RESULT_NOT_ALLOWED = 6;
private final Handler mHandler;
private final String mTag;
protected abstract boolean isAvailableInPlatform();
protected abstract boolean isGpsEnabled();
- protected abstract boolean registerWithService(); // must access only on handler thread
+ // must access only on handler thread
+ protected abstract int registerWithService();
protected abstract void unregisterFromService(); // must access only on handler thread
protected abstract ListenerOperation<TListener> getHandlerOperation(int result);
private void tryRegister() {
mHandler.post(new Runnable() {
+ int registrationState = RESULT_INTERNAL_ERROR;
@Override
public void run() {
if (!mIsRegistered) {
- mIsRegistered = registerWithService();
+ registrationState = registerWithService();
+ mIsRegistered = registrationState == RESULT_SUCCESS;
}
if (!mIsRegistered) {
// post back a failure
@Override
public void run() {
synchronized (mListenerMap) {
- ListenerOperation<TListener> operation = getHandlerOperation(RESULT_INTERNAL_ERROR);
+ ListenerOperation<TListener> operation = getHandlerOperation(registrationState);
foreachUnsafe(operation);
}
}
#define LOG_NDEBUG 0
+#include <android/hardware/gnss/1.0/IGnss.h>
#include <android/hardware/gnss/1.1/IGnss.h>
+#include <android/hardware/gnss/1.0/IGnssMeasurement.h>
+#include <android/hardware/gnss/1.1/IGnssMeasurement.h>
#include <nativehelper/JNIHelp.h>
#include "jni.h"
#include "hardware_legacy/power.h"
using android::hardware::hidl_vec;
using android::hardware::hidl_death_recipient;
using android::hidl::base::V1_0::IBase;
-
using android::hardware::gnss::V1_0::GnssLocation;
using android::hardware::gnss::V1_0::GnssLocationFlags;
-
+using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
+using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
+using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
+using android::hardware::gnss::V1_0::IGnss;
using android::hardware::gnss::V1_0::IAGnss;
using android::hardware::gnss::V1_0::IAGnssCallback;
using android::hardware::gnss::V1_0::IAGnssCallback;
using android::hardware::gnss::V1_0::IAGnssRil;
using android::hardware::gnss::V1_0::IAGnssRilCallback;
-using android::hardware::gnss::V1_0::IGnss;
using android::hardware::gnss::V1_0::IGnssBatching;
using android::hardware::gnss::V1_0::IGnssBatchingCallback;
using android::hardware::gnss::V1_0::IGnssConfiguration;
using android::hardware::gnss::V1_0::IGnssDebug;
using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
using android::hardware::gnss::V1_0::IGnssGeofencing;
-using android::hardware::gnss::V1_0::IGnssMeasurement;
using android::hardware::gnss::V1_0::IGnssMeasurementCallback;
using android::hardware::gnss::V1_0::IGnssNavigationMessage;
using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
using android::hardware::gnss::V1_0::IGnssNiCallback;
using android::hardware::gnss::V1_0::IGnssXtra;
using android::hardware::gnss::V1_0::IGnssXtraCallback;
-
-using IGnssV1_1 = android::hardware::gnss::V1_1::IGnss;
using android::hardware::gnss::V1_1::IGnssCallback;
struct GnssDeathRecipient : virtual public hidl_death_recipient
sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
sp<IGnss> gnssHal = nullptr;
-sp<IGnssV1_1> gnssHalV1_1 = nullptr;
+sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
sp<IGnssXtra> gnssXtraIface = nullptr;
sp<IAGnssRil> agnssRilIface = nullptr;
sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
sp<IGnssDebug> gnssDebugIface = nullptr;
sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
sp<IGnssNi> gnssNiIface = nullptr;
-sp<IGnssMeasurement> gnssMeasurementIface = nullptr;
+sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
+sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
#define WAKE_LOCK_NAME "GPS"
LOG_ALWAYS_FATAL("Unable to get Java VM. Error: %d", jvmStatus);
}
- gnssHal = gnssHalV1_1 = IGnssV1_1::getService();
-
- if (gnssHal == nullptr) {
+ // TODO(b/31632518)
+ gnssHal_V1_1 = IGnss_V1_1::getService();
+ if (gnssHal_V1_1 == nullptr) {
ALOGD("gnssHal 1.1 was null, trying 1.0");
gnssHal = IGnss::getService();
+ } else {
+ gnssHal = gnssHal_V1_1;
}
if (gnssHal != nullptr) {
gnssNavigationMessageIface = gnssNavigationMessage;
}
- auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement();
- if (!gnssMeasurement.isOk()) {
- ALOGD("Unable to get a handle to GnssMeasurement");
+ if (gnssHal_V1_1 != nullptr) {
+ auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
+ if (!gnssMeasurement.isOk()) {
+ ALOGD("Unable to get a handle to GnssMeasurement");
+ } else {
+ gnssMeasurementIface_V1_1 = gnssMeasurement;
+ gnssMeasurementIface = gnssMeasurementIface_V1_1;
+ }
} else {
- gnssMeasurementIface = gnssMeasurement;
+ auto gnssMeasurement_V1_0 = gnssHal->getExtensionGnssMeasurement();
+ if (!gnssMeasurement_V1_0.isOk()) {
+ ALOGD("Unable to get a handle to GnssMeasurement");
+ } else {
+ gnssMeasurementIface = gnssMeasurement_V1_0;
+ }
}
auto gnssDebug = gnssHal->getExtensionGnssDebug();
sp<IGnssCallback> gnssCbIface = new GnssCallback();
Return<bool> result = false;
- if (gnssHalV1_1 != nullptr) {
- result = gnssHalV1_1->setCallback_1_1(gnssCbIface);
+ if (gnssHal_V1_1 != nullptr) {
+ result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
} else {
result = gnssHal->setCallback(gnssCbIface);
}
static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
- jint preferred_time) {
- if (gnssHal != nullptr) {
- auto result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
- static_cast<IGnss::GnssPositionRecurrence>(recurrence),
- min_interval,
- preferred_accuracy,
- preferred_time);
- if (!result.isOk()) {
- ALOGE("%s: GNSS setPositionMode failed\n", __func__);
- return JNI_FALSE;
- } else {
- return result;
- }
+ jint preferred_time, jboolean low_power_mode) {
+ Return<bool> result = false;
+ if (gnssHal_V1_1 != nullptr) {
+ result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss::GnssPositionMode>(mode),
+ static_cast<IGnss::GnssPositionRecurrence>(recurrence),
+ min_interval,
+ preferred_accuracy,
+ preferred_time,
+ low_power_mode);
+ } else if (gnssHal != nullptr) {
+ result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
+ static_cast<IGnss::GnssPositionRecurrence>(recurrence),
+ min_interval,
+ preferred_accuracy,
+ preferred_time);
+ }
+ if (!result.isOk()) {
+ ALOGE("%s: GNSS setPositionMode failed\n", __func__);
+ return JNI_FALSE;
} else {
- return JNI_FALSE;
+ return result;
}
}
}
static jboolean android_location_GnssLocationProvider_start_measurement_collection(
- JNIEnv* env,
- jobject obj) {
+ JNIEnv* /* env */,
+ jobject /* obj */,
+ jboolean enableFullTracking) {
if (gnssMeasurementIface == nullptr) {
ALOGE("GNSS Measurement interface is not available.");
return JNI_FALSE;
}
sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
- IGnssMeasurement::GnssMeasurementStatus result = gnssMeasurementIface->setCallback(cbIface);
- if (result != IGnssMeasurement::GnssMeasurementStatus::SUCCESS) {
+ IGnssMeasurement_V1_0::GnssMeasurementStatus result =
+ IGnssMeasurement_V1_0::GnssMeasurementStatus::ERROR_GENERIC;;
+ if (gnssMeasurementIface_V1_1 != nullptr) {
+ result = gnssMeasurementIface_V1_1->setCallback_1_1(cbIface,
+ enableFullTracking);
+ } else {
+ if (enableFullTracking == JNI_TRUE) {
+ // full tracking mode not supported in 1.0 HAL
+ return JNI_FALSE;
+ }
+ result = gnssMeasurementIface->setCallback(cbIface);
+ }
+
+ if (result != IGnssMeasurement_V1_0::GnssMeasurementStatus::SUCCESS) {
ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
static_cast<int32_t>(result));
return JNI_FALSE;
{"native_cleanup", "()V", reinterpret_cast<void *>(
android_location_GnssLocationProvider_cleanup)},
{"native_set_position_mode",
- "(IIIII)Z",
- reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
+ "(IIIIIZ)Z",
+ reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
{"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
{"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
{"native_delete_aiding_data",
reinterpret_cast<void *>(
android_location_GnssLocationProvider_is_measurement_supported)},
{"native_start_measurement_collection",
- "()Z",
+ "(Z)Z",
reinterpret_cast<void *>(
android_location_GnssLocationProvider_start_measurement_collection)},
{"native_stop_measurement_collection",