summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcore/api/system-current.txt3
-rw-r--r--core/res/AndroidManifest.xml7
-rw-r--r--location/java/android/location/ILocationManager.aidl3
-rw-r--r--location/java/android/location/LocationManager.java45
-rw-r--r--services/core/java/com/android/server/location/LocationManagerService.java27
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssLocationProvider.java29
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssManagerService.java16
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;