diff options
7 files changed, 130 insertions, 0 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 4918ebaf3d43..9ac0b39aa33a 100755 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -31,6 +31,7 @@ package android { field public static final String AMBIENT_WALLPAPER = "android.permission.AMBIENT_WALLPAPER"; field public static final String APPROVE_INCIDENT_REPORTS = "android.permission.APPROVE_INCIDENT_REPORTS"; field public static final String ASSOCIATE_COMPANION_DEVICES = "android.permission.ASSOCIATE_COMPANION_DEVICES"; + field public static final String AUTOMOTIVE_GNSS_CONTROLS = "android.permission.AUTOMOTIVE_GNSS_CONTROLS"; field public static final String BACKGROUND_CAMERA = "android.permission.BACKGROUND_CAMERA"; field public static final String BACKUP = "android.permission.BACKUP"; field public static final String BATTERY_PREDICTION = "android.permission.BATTERY_PREDICTION"; @@ -5079,6 +5080,7 @@ package android.location { method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.location.Location getLastKnownLocation(@NonNull String, @NonNull android.location.LastLocationRequest); method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void injectGnssMeasurementCorrections(@NonNull android.location.GnssMeasurementCorrections); method public boolean isAdasGnssLocationEnabled(); + method @RequiresPermission(android.Manifest.permission.AUTOMOTIVE_GNSS_CONTROLS) public boolean isAutoGnssSuspended(); method public boolean isExtraLocationControllerPackageEnabled(); method public boolean isLocationEnabledForUser(@NonNull android.os.UserHandle); method public boolean isProviderEnabledForUser(@NonNull String, @NonNull android.os.UserHandle); @@ -5091,6 +5093,7 @@ package android.location { method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull java.util.concurrent.Executor, @NonNull android.location.LocationListener); method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@Nullable android.location.LocationRequest, @NonNull android.app.PendingIntent); method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setAdasGnssLocationEnabled(boolean); + method @RequiresPermission(android.Manifest.permission.AUTOMOTIVE_GNSS_CONTROLS) public void setAutoGnssSuspended(boolean); method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setExtraLocationControllerPackage(@Nullable String); method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setExtraLocationControllerPackageEnabled(boolean); method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, @NonNull android.os.UserHandle); diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index df69ed005514..1452bdfa44c3 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1751,6 +1751,13 @@ <permission android:name="android.permission.ACCESS_MOCK_LOCATION" android:protectionLevel="signature" /> + <!-- @SystemApi @hide Allows automotive applications to control location + suspend state for power management use cases. + <p>Not for use by third-party applications. + --> + <permission android:name="android.permission.AUTOMOTIVE_GNSS_CONTROLS" + android:protectionLevel="signature|privileged" /> + <!-- ======================================= --> <!-- Permissions for accessing networks --> <!-- ======================================= --> diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl index 5d5c0fc6265d..8054fd452022 100644 --- a/location/java/android/location/ILocationManager.aidl +++ b/location/java/android/location/ILocationManager.aidl @@ -125,6 +125,9 @@ interface ILocationManager boolean isAdasGnssLocationEnabledForUser(int userId); void setAdasGnssLocationEnabledForUser(boolean enabled, int userId); + boolean isAutoGnssSuspended(); + void setAutoGnssSuspended(boolean suspended); + 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/LocationManager.java b/location/java/android/location/LocationManager.java index 0681b8da43fd..2ff969316355 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -758,6 +758,51 @@ public class LocationManager { } /** + * Set whether GNSS requests are suspended on the device. + * + * This method was added to help support power management use cases on automotive devices. More + * specifically, it is being added to fix a suspend to RAM issue where the SoC can't go into + * a lower power state when applications are actively requesting GNSS updates. + * + * Ideally, the issue should be fixed at a lower layer in the stack, but this API introduces a + * workaround in the platform layer. This API allows car specific services to halt GNSS requests + * based on changes to the car power policy, which will in turn enable the device to go into + * suspend. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.AUTOMOTIVE_GNSS_CONTROLS) + public void setAutoGnssSuspended(boolean suspended) { + try { + mService.setAutoGnssSuspended(suspended); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Return whether GNSS requests are suspended or not. + * + * This method was added to help support power management use cases on automotive devices. More + * specifically, it is being added as part of the fix for a suspend to RAM issue where the SoC + * can't go into a lower power state when applications are actively requesting GNSS updates. + * + * @return true if GNSS requests are suspended and false if they aren't. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.AUTOMOTIVE_GNSS_CONTROLS) + public boolean isAutoGnssSuspended() { + try { + return mService.isAutoGnssSuspended(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Gets the last known location from the fused provider, or null if there is no last known * location. The returned location may be quite old in some circumstances, so the age of the * location should always be checked. diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java index cd26fb5c2d52..2550e3a9aede 100644 --- a/services/core/java/com/android/server/location/LocationManagerService.java +++ b/services/core/java/com/android/server/location/LocationManagerService.java @@ -39,6 +39,7 @@ import android.Manifest; import android.Manifest.permission; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.PendingIntent; @@ -1239,6 +1240,32 @@ public class LocationManagerService extends ILocationManager.Stub implements } @Override + @RequiresPermission(android.Manifest.permission.AUTOMOTIVE_GNSS_CONTROLS) + public void setAutoGnssSuspended(boolean suspended) { + mContext.enforceCallingPermission(permission.AUTOMOTIVE_GNSS_CONTROLS, null); + + if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { + throw new IllegalStateException( + "setAutoGnssSuspended only allowed on automotive devices"); + } + + mGnssManagerService.setAutoGnssSuspended(suspended); + } + + @Override + @RequiresPermission(android.Manifest.permission.AUTOMOTIVE_GNSS_CONTROLS) + public boolean isAutoGnssSuspended() { + mContext.enforceCallingPermission(permission.AUTOMOTIVE_GNSS_CONTROLS, null); + + if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { + throw new IllegalStateException( + "isAutoGnssSuspended only allowed on automotive devices"); + } + + return mGnssManagerService.isAutoGnssSuspended(); + } + + @Override public boolean geocoderIsPresent() { return mGeocodeProvider != null; } diff --git a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java index 7d0b98e26c4c..6c1df7f98da0 100644 --- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java @@ -243,6 +243,9 @@ public class GnssLocationProvider extends AbstractLocationProvider implements @GuardedBy("mLock") private boolean mBatchingEnabled; + @GuardedBy("mLock") + private boolean mAutomotiveSuspend; + private boolean mShutdown; private boolean mStarted; private boolean mBatchingStarted; @@ -721,6 +724,27 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } } + /** + * Set whether the GnssLocationProvider is suspended. This method was added to help support + * power management use cases on automotive devices. + */ + public void setAutoGnssSuspended(boolean suspended) { + synchronized (mLock) { + mAutomotiveSuspend = suspended; + } + mHandler.post(this::updateEnabled); + } + + /** + * Return whether the GnssLocationProvider is suspended or not. This method was added to help + * support power management use cases on automotive devices. + */ + public boolean isAutoGnssSuspended() { + synchronized (mLock) { + return mAutomotiveSuspend && !mGpsEnabled; + } + } + private void handleEnable() { if (DEBUG) Log.d(TAG, "handleEnable"); @@ -776,6 +800,11 @@ public class GnssLocationProvider extends AbstractLocationProvider implements && mProviderRequest.isActive() && mProviderRequest.isBypass()); + // .. disable if automotive device needs to go into suspend + synchronized (mLock) { + enabled &= !mAutomotiveSuspend; + } + // ... and, finally, disable anyway, if device is being shut down enabled &= !mShutdown; diff --git a/services/core/java/com/android/server/location/gnss/GnssManagerService.java b/services/core/java/com/android/server/location/gnss/GnssManagerService.java index 5de9cf3f5b6a..11fd727072df 100644 --- a/services/core/java/com/android/server/location/gnss/GnssManagerService.java +++ b/services/core/java/com/android/server/location/gnss/GnssManagerService.java @@ -109,6 +109,22 @@ public class GnssManagerService { return mGnssLocationProvider; } + /** + * Set whether the GnssLocationProvider is suspended on the device. This method was added to + * help support power management use cases on automotive devices. + */ + public void setAutoGnssSuspended(boolean suspended) { + mGnssLocationProvider.setAutoGnssSuspended(suspended); + } + + /** + * Return whether the GnssLocationProvider is suspended or not. This method was added to + * help support power management use cases on automotive devices. + */ + public boolean isAutoGnssSuspended() { + return mGnssLocationProvider.isAutoGnssSuspended(); + } + /** Retrieve the IGpsGeofenceHardware. */ public IGpsGeofenceHardware getGnssGeofenceProxy() { return mGnssGeofenceProxy; |