diff options
author | Soonil Nagarkar <sooniln@google.com> | 2021-06-16 15:03:05 -0700 |
---|---|---|
committer | Soonil Nagarkar <sooniln@google.com> | 2021-06-23 11:11:50 -0700 |
commit | e58fea5a45586b5a81d6ef8da3bcd132206c3b9b (patch) | |
tree | 7b61c26d859ef8cd740fb3c16afb426b810fe35b /location | |
parent | d616f1ed950b62f5a6682957d483f46f9547c3ed (diff) |
Add ADAS GNSS bypass functionality
ADAS applications on automotive device require a way to access GNSS
sensors even when the master location toggle is off, so that they can
provide automotive safety services.
Bug: 156688086
Test: atest LocationProviderManagerTest
Change-Id: I438a781b2202c488da97f7ea732f87403d1068e4
Diffstat (limited to 'location')
5 files changed, 239 insertions, 12 deletions
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl index c9e4e0a9cb92..5d5c0fc6265d 100644 --- a/location/java/android/location/ILocationManager.aidl +++ b/location/java/android/location/ILocationManager.aidl @@ -122,6 +122,9 @@ interface ILocationManager boolean isLocationEnabledForUser(int userId); void setLocationEnabledForUser(boolean enabled, int userId); + boolean isAdasGnssLocationEnabledForUser(int userId); + void setAdasGnssLocationEnabledForUser(boolean enabled, int userId); + void addTestProvider(String name, in ProviderProperties properties, in List<String> locationTags, String packageName, @nullable String attributionTag); void removeTestProvider(String provider, String packageName, @nullable String attributionTag); diff --git a/location/java/android/location/LastLocationRequest.java b/location/java/android/location/LastLocationRequest.java index 9ea8048ad476..0970c1c76a36 100644 --- a/location/java/android/location/LastLocationRequest.java +++ b/location/java/android/location/LastLocationRequest.java @@ -34,12 +34,15 @@ import java.util.Objects; public final class LastLocationRequest implements Parcelable { private final boolean mHiddenFromAppOps; + private final boolean mAdasGnssBypass; private final boolean mLocationSettingsIgnored; private LastLocationRequest( boolean hiddenFromAppOps, + boolean adasGnssBypass, boolean locationSettingsIgnored) { mHiddenFromAppOps = hiddenFromAppOps; + mAdasGnssBypass = adasGnssBypass; mLocationSettingsIgnored = locationSettingsIgnored; } @@ -56,6 +59,21 @@ public final class LastLocationRequest implements Parcelable { } /** + * Returns true if this request may access GNSS even if location settings would normally deny + * this, in order to enable automotive safety features. This field is only respected on + * automotive devices, and only if the client is recognized as a legitimate ADAS (Advanced + * Driving Assistance Systems) application. + * + * @return true if all limiting factors will be ignored to satisfy GNSS request + * @hide + */ + // TODO: make this system api + public boolean isAdasGnssBypass() { + return mAdasGnssBypass; + } + + + /** * Returns true if location settings, throttling, background location limits, and any other * possible limiting factors will be ignored in order to satisfy this last location request. * @@ -65,12 +83,22 @@ public final class LastLocationRequest implements Parcelable { return mLocationSettingsIgnored; } + /** + * Returns true if any bypass flag is set on this request. For internal use only. + * + * @hide + */ + public boolean isBypass() { + return mAdasGnssBypass || mLocationSettingsIgnored; + } + public static final @NonNull Parcelable.Creator<LastLocationRequest> CREATOR = new Parcelable.Creator<LastLocationRequest>() { @Override public LastLocationRequest createFromParcel(Parcel in) { return new LastLocationRequest( /* hiddenFromAppOps= */ in.readBoolean(), + /* adasGnssBypass= */ in.readBoolean(), /* locationSettingsIgnored= */ in.readBoolean()); } @Override @@ -86,6 +114,7 @@ public final class LastLocationRequest implements Parcelable { @Override public void writeToParcel(@NonNull Parcel parcel, int flags) { parcel.writeBoolean(mHiddenFromAppOps); + parcel.writeBoolean(mAdasGnssBypass); parcel.writeBoolean(mLocationSettingsIgnored); } @@ -99,12 +128,13 @@ public final class LastLocationRequest implements Parcelable { } LastLocationRequest that = (LastLocationRequest) o; return mHiddenFromAppOps == that.mHiddenFromAppOps + && mAdasGnssBypass == that.mAdasGnssBypass && mLocationSettingsIgnored == that.mLocationSettingsIgnored; } @Override public int hashCode() { - return Objects.hash(mHiddenFromAppOps, mLocationSettingsIgnored); + return Objects.hash(mHiddenFromAppOps, mAdasGnssBypass, mLocationSettingsIgnored); } @NonNull @@ -115,8 +145,11 @@ public final class LastLocationRequest implements Parcelable { if (mHiddenFromAppOps) { s.append("hiddenFromAppOps, "); } + if (mAdasGnssBypass) { + s.append("adasGnssBypass, "); + } if (mLocationSettingsIgnored) { - s.append("locationSettingsIgnored, "); + s.append("settingsBypass, "); } if (s.length() > "LastLocationRequest[".length()) { s.setLength(s.length() - 2); @@ -131,6 +164,7 @@ public final class LastLocationRequest implements Parcelable { public static final class Builder { private boolean mHiddenFromAppOps; + private boolean mAdasGnssBypass; private boolean mLocationSettingsIgnored; /** @@ -138,6 +172,7 @@ public final class LastLocationRequest implements Parcelable { */ public Builder() { mHiddenFromAppOps = false; + mAdasGnssBypass = false; mLocationSettingsIgnored = false; } @@ -146,6 +181,7 @@ public final class LastLocationRequest implements Parcelable { */ public Builder(@NonNull LastLocationRequest lastLocationRequest) { mHiddenFromAppOps = lastLocationRequest.mHiddenFromAppOps; + mAdasGnssBypass = lastLocationRequest.mAdasGnssBypass; mLocationSettingsIgnored = lastLocationRequest.mLocationSettingsIgnored; } @@ -164,6 +200,25 @@ public final class LastLocationRequest implements Parcelable { } /** + * If set to true, indicates that the client is an ADAS (Advanced Driving Assistance + * Systems) client, which requires access to GNSS even if location settings would normally + * deny this, in order to enable auto safety features. This field is only respected on + * automotive devices, and only if the client is recognized as a legitimate ADAS + * application. Defaults to false. + * + * <p>Permissions enforcement occurs when resulting location request is actually used, not + * when this method is invoked. + * + * @hide + */ + // TODO: make this system api + @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) + public @NonNull LastLocationRequest.Builder setAdasGnssBypass(boolean adasGnssBypass) { + mAdasGnssBypass = adasGnssBypass; + return this; + } + + /** * If set to true, indicates that location settings, throttling, background location limits, * and any other possible limiting factors should be ignored in order to satisfy this * last location request. This is only intended for use in user initiated emergency @@ -186,6 +241,7 @@ public final class LastLocationRequest implements Parcelable { public @NonNull LastLocationRequest build() { return new LastLocationRequest( mHiddenFromAppOps, + mAdasGnssBypass, mLocationSettingsIgnored); } } diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index ae44c5e34521..526b84e85e38 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -315,6 +315,33 @@ public class LocationManager { public static final String EXTRA_LOCATION_ENABLED = "android.location.extra.LOCATION_ENABLED"; /** + * Broadcast intent action when the ADAS (Advanced Driving Assistance Systems) GNSS location + * enabled state changes. Includes a boolean intent extra, {@link #EXTRA_ADAS_GNSS_ENABLED}, + * with the enabled state of ADAS GNSS location. This broadcast only has meaning on automotive + * devices. + * + * @see #EXTRA_ADAS_GNSS_ENABLED + * @see #isAdasGnssLocationEnabled() + * + * @hide + */ + // TODO: @SystemApi + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_ADAS_GNSS_ENABLED_CHANGED = + "android.location.action.ADAS_GNSS_ENABLED_CHANGED"; + + /** + * Intent extra included with {@link #ACTION_ADAS_GNSS_ENABLED_CHANGED} broadcasts, containing + * the boolean enabled state of ADAS GNSS location. + * + * @see #ACTION_ADAS_GNSS_ENABLED_CHANGED + * + * @hide + */ + // TODO: @SystemApi + public static final String EXTRA_ADAS_GNSS_ENABLED = "android.location.extra.ADAS_GNSS_ENABLED"; + + /** * Broadcast intent action indicating that a high power location requests * has either started or stopped being active. The current state of * active location requests should be read from AppOpsManager using @@ -621,6 +648,42 @@ public class LocationManager { } /** + * Returns the current enabled/disabled state of ADAS (Advanced Driving Assistance Systems) + * GNSS location access for the given user. This controls safety critical automotive access to + * GNSS location. This only has meaning on automotive devices. + * + * @return true if ADAS location is enabled and false if ADAS location is disabled. + * + * @hide + */ + //TODO: @SystemApi + public boolean isAdasGnssLocationEnabled() { + try { + return mService.isAdasGnssLocationEnabledForUser(mContext.getUser().getIdentifier()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Enables or disables ADAS (Advanced Driving Assistance Systems) GNSS location access for the + * given user. This only has meaning on automotive devices. + * + * @param enabled true to enable ADAS location and false to disable ADAS location. + * + * @hide + */ + // TODO: @SystemApi + @RequiresPermission(WRITE_SECURE_SETTINGS) + public void setAdasGnssLocationEnabled(boolean enabled) { + try { + mService.setAdasGnssLocationEnabledForUser(enabled, mContext.getUser().getIdentifier()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Returns the current enabled/disabled status of the given provider. To listen for changes, see * {@link #PROVIDERS_CHANGED_ACTION}. * diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java index a3842a1ffd0a..b48e59676ac1 100644 --- a/location/java/android/location/LocationRequest.java +++ b/location/java/android/location/LocationRequest.java @@ -194,6 +194,7 @@ public final class LocationRequest implements Parcelable { private float mMinUpdateDistanceMeters; private final long mMaxUpdateDelayMillis; private boolean mHideFromAppOps; + private final boolean mAdasGnssBypass; private boolean mLocationSettingsIgnored; private boolean mLowPower; private @Nullable WorkSource mWorkSource; @@ -236,7 +237,7 @@ public final class LocationRequest implements Parcelable { if (LocationManager.PASSIVE_PROVIDER.equals(provider)) { quality = POWER_NONE; } else if (LocationManager.GPS_PROVIDER.equals(provider)) { - quality = ACCURACY_FINE; + quality = QUALITY_HIGH_ACCURACY; } else { quality = POWER_LOW; } @@ -289,6 +290,7 @@ public final class LocationRequest implements Parcelable { float minUpdateDistanceMeters, long maxUpdateDelayMillis, boolean hiddenFromAppOps, + boolean adasGnssBypass, boolean locationSettingsIgnored, boolean lowPower, WorkSource workSource) { @@ -302,8 +304,9 @@ public final class LocationRequest implements Parcelable { mMinUpdateDistanceMeters = minUpdateDistanceMeters; mMaxUpdateDelayMillis = maxUpdateDelayMillis; mHideFromAppOps = hiddenFromAppOps; - mLowPower = lowPower; + mAdasGnssBypass = adasGnssBypass; mLocationSettingsIgnored = locationSettingsIgnored; + mLowPower = lowPower; mWorkSource = Objects.requireNonNull(workSource); } @@ -339,15 +342,15 @@ public final class LocationRequest implements Parcelable { switch (quality) { case POWER_HIGH: // fall through - case ACCURACY_FINE: + case QUALITY_HIGH_ACCURACY: mQuality = QUALITY_HIGH_ACCURACY; break; - case ACCURACY_BLOCK: + case QUALITY_BALANCED_POWER_ACCURACY: mQuality = QUALITY_BALANCED_POWER_ACCURACY; break; case POWER_LOW: // fall through - case ACCURACY_CITY: + case QUALITY_LOW_POWER: mQuality = QUALITY_LOW_POWER; break; case POWER_NONE: @@ -648,6 +651,21 @@ public final class LocationRequest implements Parcelable { } /** + * Returns true if this request may access GNSS even if location settings would normally deny + * this, in order to enable automotive safety features. This field is only respected on + * automotive devices, and only if the client is recognized as a legitimate ADAS (Advanced + * Driving Assistance Systems) application. + * + * @return true if all limiting factors will be ignored to satisfy GNSS request + * + * @hide + */ + // TODO: @SystemApi + public boolean isAdasGnssBypass() { + return mAdasGnssBypass; + } + + /** * @hide * @deprecated LocationRequests should be treated as immutable. */ @@ -673,6 +691,15 @@ public final class LocationRequest implements Parcelable { } /** + * Returns true if any bypass flag is set on this request. For internal use only. + * + * @hide + */ + public boolean isBypass() { + return mAdasGnssBypass || mLocationSettingsIgnored; + } + + /** * @hide * @deprecated LocationRequests should be treated as immutable. */ @@ -749,6 +776,7 @@ public final class LocationRequest implements Parcelable { /* minUpdateDistanceMeters= */ in.readFloat(), /* maxUpdateDelayMillis= */ in.readLong(), /* hiddenFromAppOps= */ in.readBoolean(), + /* adasGnssBypass= */ in.readBoolean(), /* locationSettingsIgnored= */ in.readBoolean(), /* lowPower= */ in.readBoolean(), /* workSource= */ in.readTypedObject(WorkSource.CREATOR)); @@ -777,6 +805,7 @@ public final class LocationRequest implements Parcelable { parcel.writeFloat(mMinUpdateDistanceMeters); parcel.writeLong(mMaxUpdateDelayMillis); parcel.writeBoolean(mHideFromAppOps); + parcel.writeBoolean(mAdasGnssBypass); parcel.writeBoolean(mLocationSettingsIgnored); parcel.writeBoolean(mLowPower); parcel.writeTypedObject(mWorkSource, 0); @@ -801,6 +830,7 @@ public final class LocationRequest implements Parcelable { && Float.compare(that.mMinUpdateDistanceMeters, mMinUpdateDistanceMeters) == 0 && mMaxUpdateDelayMillis == that.mMaxUpdateDelayMillis && mHideFromAppOps == that.mHideFromAppOps + && mAdasGnssBypass == that.mAdasGnssBypass && mLocationSettingsIgnored == that.mLocationSettingsIgnored && mLowPower == that.mLowPower && Objects.equals(mProvider, that.mProvider) @@ -866,8 +896,11 @@ public final class LocationRequest implements Parcelable { if (mHideFromAppOps) { s.append(", hiddenFromAppOps"); } + if (mAdasGnssBypass) { + s.append(", adasGnssBypass"); + } if (mLocationSettingsIgnored) { - s.append(", locationSettingsIgnored"); + s.append(", settingsBypass"); } if (mWorkSource != null && !mWorkSource.isEmpty()) { s.append(", ").append(mWorkSource); @@ -889,6 +922,7 @@ public final class LocationRequest implements Parcelable { private float mMinUpdateDistanceMeters; private long mMaxUpdateDelayMillis; private boolean mHiddenFromAppOps; + private boolean mAdasGnssBypass; private boolean mLocationSettingsIgnored; private boolean mLowPower; @Nullable private WorkSource mWorkSource; @@ -908,6 +942,7 @@ public final class LocationRequest implements Parcelable { mMinUpdateDistanceMeters = 0; mMaxUpdateDelayMillis = 0; mHiddenFromAppOps = false; + mAdasGnssBypass = false; mLocationSettingsIgnored = false; mLowPower = false; mWorkSource = null; @@ -925,6 +960,7 @@ public final class LocationRequest implements Parcelable { mMinUpdateDistanceMeters = locationRequest.mMinUpdateDistanceMeters; mMaxUpdateDelayMillis = locationRequest.mMaxUpdateDelayMillis; mHiddenFromAppOps = locationRequest.mHideFromAppOps; + mAdasGnssBypass = locationRequest.mAdasGnssBypass; mLocationSettingsIgnored = locationRequest.mLocationSettingsIgnored; mLowPower = locationRequest.mLowPower; mWorkSource = locationRequest.mWorkSource; @@ -977,10 +1013,10 @@ public final class LocationRequest implements Parcelable { public @NonNull Builder setQuality(@NonNull Criteria criteria) { switch (criteria.getAccuracy()) { case Criteria.ACCURACY_COARSE: - mQuality = ACCURACY_BLOCK; + mQuality = QUALITY_BALANCED_POWER_ACCURACY; break; case Criteria.ACCURACY_FINE: - mQuality = ACCURACY_FINE; + mQuality = QUALITY_HIGH_ACCURACY; break; default: { if (criteria.getPowerRequirement() == Criteria.POWER_HIGH) { @@ -1092,6 +1128,25 @@ public final class LocationRequest implements Parcelable { } /** + * If set to true, indicates that the client is an ADAS (Advanced Driving Assistance + * Systems) client, which requires access to GNSS even if location settings would normally + * deny this, in order to enable auto safety features. This field is only respected on + * automotive devices, and only if the client is recognized as a legitimate ADAS + * application. Defaults to false. + * + * <p>Permissions enforcement occurs when resulting location request is actually used, not + * when this method is invoked. + * + * @hide + */ + // TODO: @SystemApi + @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS) + public @NonNull Builder setAdasGnssBypass(boolean adasGnssBypass) { + mAdasGnssBypass = adasGnssBypass; + return this; + } + + /** * If set to true, indicates that location settings, throttling, background location limits, * and any other possible limiting factors should be ignored in order to satisfy this * request. This is only intended for use in user initiated emergency situations, and @@ -1171,6 +1226,7 @@ public final class LocationRequest implements Parcelable { mMinUpdateDistanceMeters, mMaxUpdateDelayMillis, mHiddenFromAppOps, + mAdasGnssBypass, mLocationSettingsIgnored, mLowPower, new WorkSource(mWorkSource)); diff --git a/location/java/android/location/provider/ProviderRequest.java b/location/java/android/location/provider/ProviderRequest.java index b72d36519e72..4f33a529a812 100644 --- a/location/java/android/location/provider/ProviderRequest.java +++ b/location/java/android/location/provider/ProviderRequest.java @@ -44,12 +44,19 @@ public final class ProviderRequest implements Parcelable { public static final long INTERVAL_DISABLED = Long.MAX_VALUE; public static final @NonNull ProviderRequest EMPTY_REQUEST = new ProviderRequest( - INTERVAL_DISABLED, QUALITY_BALANCED_POWER_ACCURACY, 0, false, false, new WorkSource()); + INTERVAL_DISABLED, + QUALITY_BALANCED_POWER_ACCURACY, + 0, + false, + false, + false, + new WorkSource()); private final long mIntervalMillis; private final @Quality int mQuality; private final long mMaxUpdateDelayMillis; private final boolean mLowPower; + private final boolean mAdasGnssBypass; private final boolean mLocationSettingsIgnored; private final WorkSource mWorkSource; @@ -72,12 +79,14 @@ public final class ProviderRequest implements Parcelable { @Quality int quality, long maxUpdateDelayMillis, boolean lowPower, + boolean adasGnssBypass, boolean locationSettingsIgnored, @NonNull WorkSource workSource) { mIntervalMillis = intervalMillis; mQuality = quality; mMaxUpdateDelayMillis = maxUpdateDelayMillis; mLowPower = lowPower; + mAdasGnssBypass = adasGnssBypass; mLocationSettingsIgnored = locationSettingsIgnored; mWorkSource = Objects.requireNonNull(workSource); } @@ -126,6 +135,18 @@ public final class ProviderRequest implements Parcelable { } /** + * Returns true if this request may access GNSS even if location settings would normally deny + * this, in order to enable automotive safety features. This field is only respected on + * automotive devices, and only if the client is recognized as a legitimate ADAS (Advanced + * Driving Assistance Systems) application. + * + * @hide + */ + public boolean isAdasGnssBypass() { + return mAdasGnssBypass; + } + + /** * Whether the provider should ignore all location settings, user consents, power restrictions * or any other restricting factors and always satisfy this request to the best of their * ability. This should only be used in case of a user initiated emergency. @@ -135,6 +156,15 @@ public final class ProviderRequest implements Parcelable { } /** + * Returns true if any bypass flag is set on this request. + * + * @hide + */ + public boolean isBypass() { + return mAdasGnssBypass || mLocationSettingsIgnored; + } + + /** * The power blame for this provider request. */ public @NonNull WorkSource getWorkSource() { @@ -153,6 +183,7 @@ public final class ProviderRequest implements Parcelable { /* quality= */ in.readInt(), /* maxUpdateDelayMillis= */ in.readLong(), /* lowPower= */ in.readBoolean(), + /* adasGnssBypass= */ in.readBoolean(), /* locationSettingsIgnored= */ in.readBoolean(), /* workSource= */ in.readTypedObject(WorkSource.CREATOR)); } @@ -176,6 +207,7 @@ public final class ProviderRequest implements Parcelable { parcel.writeInt(mQuality); parcel.writeLong(mMaxUpdateDelayMillis); parcel.writeBoolean(mLowPower); + parcel.writeBoolean(mAdasGnssBypass); parcel.writeBoolean(mLocationSettingsIgnored); parcel.writeTypedObject(mWorkSource, flags); } @@ -198,6 +230,7 @@ public final class ProviderRequest implements Parcelable { && mQuality == that.mQuality && mMaxUpdateDelayMillis == that.mMaxUpdateDelayMillis && mLowPower == that.mLowPower + && mAdasGnssBypass == that.mAdasGnssBypass && mLocationSettingsIgnored == that.mLocationSettingsIgnored && mWorkSource.equals(that.mWorkSource); } @@ -229,8 +262,11 @@ public final class ProviderRequest implements Parcelable { if (mLowPower) { s.append(", lowPower"); } + if (mAdasGnssBypass) { + s.append(", adasGnssBypass"); + } if (mLocationSettingsIgnored) { - s.append(", locationSettingsIgnored"); + s.append(", settingsBypass"); } if (!mWorkSource.isEmpty()) { s.append(", ").append(mWorkSource); @@ -246,10 +282,12 @@ public final class ProviderRequest implements Parcelable { * A Builder for {@link ProviderRequest}s. */ public static final class Builder { + private long mIntervalMillis = INTERVAL_DISABLED; private int mQuality = QUALITY_BALANCED_POWER_ACCURACY; private long mMaxUpdateDelayMillis = 0; private boolean mLowPower; + private boolean mAdasGnssBypass; private boolean mLocationSettingsIgnored; private WorkSource mWorkSource = new WorkSource(); @@ -299,6 +337,16 @@ public final class ProviderRequest implements Parcelable { } /** + * Sets whether this ADAS request should bypass GNSS settings. False by default. + * + * @hide + */ + public @NonNull Builder setAdasGnssBypass(boolean adasGnssBypass) { + this.mAdasGnssBypass = adasGnssBypass; + return this; + } + + /** * Sets whether location settings should be ignored. False by default. */ public @NonNull Builder setLocationSettingsIgnored(boolean locationSettingsIgnored) { @@ -326,6 +374,7 @@ public final class ProviderRequest implements Parcelable { mQuality, mMaxUpdateDelayMillis, mLowPower, + mAdasGnssBypass, mLocationSettingsIgnored, mWorkSource); } |