Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6a673d4 authored by Eva Chen's avatar Eva Chen
Browse files

Implement GNSS APIs for Automotive Power Management.

Automotive Suspend to RAM doesn't work when GNSS requests are
actively running. This change introduces system APIs for suspending
and resuming GNSS.

Bug: 187348886
CTS-Coverage-Bug: 203703449
Test: Presubmits
Change-Id: If25c761e8618bebaf989392afc0a676f930dfd78
parent a913e1f4
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@ package android {
    field public static final String AMBIENT_WALLPAPER = "android.permission.AMBIENT_WALLPAPER";
    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 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 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 BACKGROUND_CAMERA = "android.permission.BACKGROUND_CAMERA";
    field public static final String BACKUP = "android.permission.BACKUP";
    field public static final String BACKUP = "android.permission.BACKUP";
    field public static final String BATTERY_PREDICTION = "android.permission.BATTERY_PREDICTION";
    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 @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 @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void injectGnssMeasurementCorrections(@NonNull android.location.GnssMeasurementCorrections);
    method public boolean isAdasGnssLocationEnabled();
    method public boolean isAdasGnssLocationEnabled();
    method @RequiresPermission(android.Manifest.permission.AUTOMOTIVE_GNSS_CONTROLS) public boolean isAutoGnssSuspended();
    method public boolean isExtraLocationControllerPackageEnabled();
    method public boolean isExtraLocationControllerPackageEnabled();
    method public boolean isLocationEnabledForUser(@NonNull android.os.UserHandle);
    method public boolean isLocationEnabledForUser(@NonNull android.os.UserHandle);
    method public boolean isProviderEnabledForUser(@NonNull String, @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 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 @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.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 setExtraLocationControllerPackage(@Nullable String);
    method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setExtraLocationControllerPackageEnabled(boolean);
    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);
    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, @NonNull android.os.UserHandle);
+7 −0
Original line number Original line Diff line number Diff line
@@ -1751,6 +1751,13 @@
    <permission android:name="android.permission.ACCESS_MOCK_LOCATION"
    <permission android:name="android.permission.ACCESS_MOCK_LOCATION"
        android:protectionLevel="signature" />
        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 -->
    <!-- Permissions for accessing networks -->
    <!-- ======================================= -->
    <!-- ======================================= -->
+3 −0
Original line number Original line Diff line number Diff line
@@ -125,6 +125,9 @@ interface ILocationManager
    boolean isAdasGnssLocationEnabledForUser(int userId);
    boolean isAdasGnssLocationEnabledForUser(int userId);
    void setAdasGnssLocationEnabledForUser(boolean enabled, int userId);
    void setAdasGnssLocationEnabledForUser(boolean enabled, int userId);


    boolean isAutoGnssSuspended();
    void setAutoGnssSuspended(boolean suspended);

    void addTestProvider(String name, in ProviderProperties properties,
    void addTestProvider(String name, in ProviderProperties properties,
        in List<String> locationTags, String packageName, @nullable String attributionTag);
        in List<String> locationTags, String packageName, @nullable String attributionTag);
    void removeTestProvider(String provider, String packageName, @nullable String attributionTag);
    void removeTestProvider(String provider, String packageName, @nullable String attributionTag);
+45 −0
Original line number Original line Diff line number Diff line
@@ -757,6 +757,51 @@ public class LocationManager {
        return false;
        return false;
    }
    }


    /**
     * 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
     * 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. The returned location may be quite old in some circumstances, so the age of the
+27 −0
Original line number Original line Diff line number Diff line
@@ -39,6 +39,7 @@ import android.Manifest;
import android.Manifest.permission;
import android.Manifest.permission;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.app.ActivityManager;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.AppOpsManager;
import android.app.PendingIntent;
import android.app.PendingIntent;
@@ -1238,6 +1239,32 @@ public class LocationManagerService extends ILocationManager.Stub implements
        return mLocalService.isProviderEnabledForUser(provider, userId);
        return mLocalService.isProviderEnabledForUser(provider, userId);
    }
    }


    @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
    @Override
    public boolean geocoderIsPresent() {
    public boolean geocoderIsPresent() {
        return mGeocodeProvider != null;
        return mGeocodeProvider != null;
Loading