Loading location/java/android/location/GnssCapabilities.java +3 −4 Original line number Diff line number Diff line Loading @@ -77,15 +77,14 @@ public final class GnssCapabilities { }) public @interface Capability {} /** * @hide */ /** @hide */ public static final long INVALID_CAPABILITIES = -1; /** A bitmask of supported GNSS capabilities. */ private final long mGnssCapabilities; static GnssCapabilities of(long gnssCapabilities) { /** @hide */ public static GnssCapabilities of(long gnssCapabilities) { return new GnssCapabilities(gnssCapabilities); } Loading services/core/java/com/android/server/LocationManagerService.java +7 −4 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ import android.location.Address; import android.location.Criteria; import android.location.GeocoderParams; import android.location.Geofence; import android.location.GnssCapabilities; import android.location.GnssMeasurementCorrections; import android.location.IBatchedLocationCallback; import android.location.IGnssMeasurementsListener; Loading Loading @@ -102,6 +103,7 @@ import com.android.server.location.GeocoderProxy; import com.android.server.location.GeofenceManager; import com.android.server.location.GeofenceProxy; import com.android.server.location.GnssBatchingProvider; import com.android.server.location.GnssCapabilitiesProvider; import com.android.server.location.GnssLocationProvider; import com.android.server.location.GnssMeasurementCorrectionsProvider; import com.android.server.location.GnssMeasurementsProvider; Loading Loading @@ -249,8 +251,8 @@ public class LocationManagerService extends ILocationManager.Stub { private int[] mCurrentUserProfiles = new int[]{UserHandle.USER_SYSTEM}; private GnssLocationProvider.GnssSystemInfoProvider mGnssSystemInfoProvider; private GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider; private GnssCapabilitiesProvider mGnssCapabilitiesProvider; private GnssBatchingProvider mGnssBatchingProvider; @GuardedBy("mLock") Loading Loading @@ -773,6 +775,7 @@ public class LocationManagerService extends ILocationManager.Stub { mGnssSystemInfoProvider = gnssProvider.getGnssSystemInfoProvider(); mGnssBatchingProvider = gnssProvider.getGnssBatchingProvider(); mGnssMetricsProvider = gnssProvider.getGnssMetricsProvider(); mGnssCapabilitiesProvider = gnssProvider.getGnssCapabilitiesProvider(); mGnssStatusProvider = gnssProvider.getGnssStatusProvider(); mNetInitiatedListener = gnssProvider.getNetInitiatedListener(); mGnssMeasurementsProvider = gnssProvider.getGnssMeasurementsProvider(); Loading Loading @@ -2970,10 +2973,10 @@ public class LocationManagerService extends ILocationManager.Stub { mContext.enforceCallingPermission( android.Manifest.permission.LOCATION_HARDWARE, "Location Hardware permission not granted to obtain GNSS chipset capabilities."); if (!hasGnssPermissions(packageName) || mGnssMeasurementCorrectionsProvider == null) { return -1; if (!hasGnssPermissions(packageName) || mGnssCapabilitiesProvider == null) { return GnssCapabilities.INVALID_CAPABILITIES; } return mGnssMeasurementCorrectionsProvider.getCapabilities(); return mGnssCapabilitiesProvider.getGnssCapabilities(); } @Override Loading services/core/java/com/android/server/location/GnssCapabilitiesProvider.java 0 → 100644 +143 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.location; import android.location.GnssCapabilities; import android.util.Log; import com.android.internal.annotations.GuardedBy; /** * Provides GNSS capabilities supported by the GNSS HAL implementation. */ public class GnssCapabilitiesProvider { private static final String TAG = "GnssCapabilitiesProvider"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); // Bit masks for capabilities in {@link android.location.GnssCapabilities}. private static final long GNSS_CAPABILITY_LOW_POWER_MODE = 1L << GnssCapabilities.LOW_POWER_MODE; private static final long GNSS_CAPABILITY_SATELLITE_BLACKLIST = 1L << GnssCapabilities.SATELLITE_BLACKLIST; private static final long GNSS_CAPABILITY_GEOFENCING = 1L << GnssCapabilities.GEOFENCING; private static final long GNSS_CAPABILITY_MEASUREMENTS = 1L << GnssCapabilities.MEASUREMENTS; private static final long GNSS_CAPABILITY_NAV_MESSAGES = 1L << GnssCapabilities.NAV_MESSAGES; private static final long GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS = 1L << GnssCapabilities.MEASUREMENT_CORRECTIONS; private static final long GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_LOS_SATS = 1L << GnssCapabilities.MEASUREMENT_CORRECTIONS_LOS_SATS; private static final long GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH = 1L << GnssCapabilities.MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH; private static final long GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_REFLECTING_PLANE = 1L << GnssCapabilities.MEASUREMENT_CORRECTIONS_REFLECTING_PLANE; private static final long GNSS_CAPABILITIES_TOP_HAL = GNSS_CAPABILITY_LOW_POWER_MODE | GNSS_CAPABILITY_SATELLITE_BLACKLIST | GNSS_CAPABILITY_GEOFENCING | GNSS_CAPABILITY_MEASUREMENTS | GNSS_CAPABILITY_NAV_MESSAGES; private static final long GNSS_CAPABILITIES_SUB_HAL_MEASUREMENT_CORRECTIONS = GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS | GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_LOS_SATS | GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH | GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_REFLECTING_PLANE; // Capabilities in {@link android.location.GnssCapabilities} supported by GNSS chipset. @GuardedBy("this") private long mGnssCapabilities; /** * Returns the capabilities supported by the GNSS chipset. * * <p>The capabilities are described in {@link android.location.GnssCapabilities} and * their integer values correspond to the bit positions in the returned {@code long} value. */ public long getGnssCapabilities() { synchronized (this) { return mGnssCapabilities; } } /** * Updates the general capabilities exposed through {@link android.location.GnssCapabilities}. */ void setTopHalCapabilities(int topHalCapabilities, boolean hasGeofencingCapability, boolean hasMeasurementsCapability, boolean hasNavMessagesCapability) { long gnssCapabilities = 0; if (hasCapability(topHalCapabilities, GnssLocationProvider.GPS_CAPABILITY_LOW_POWER_MODE)) { gnssCapabilities |= GNSS_CAPABILITY_LOW_POWER_MODE; } if (hasCapability(topHalCapabilities, GnssLocationProvider.GPS_CAPABILITY_SATELLITE_BLACKLIST)) { gnssCapabilities |= GNSS_CAPABILITY_SATELLITE_BLACKLIST; } if (hasGeofencingCapability) { gnssCapabilities |= GNSS_CAPABILITY_GEOFENCING; } if (hasMeasurementsCapability) { gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENTS; } if (hasNavMessagesCapability) { gnssCapabilities |= GNSS_CAPABILITY_NAV_MESSAGES; } synchronized (this) { mGnssCapabilities &= ~GNSS_CAPABILITIES_TOP_HAL; mGnssCapabilities |= gnssCapabilities; if (DEBUG) { Log.d(TAG, "setTopHalCapabilities, mGnssCapabilities=0x" + Long.toHexString( mGnssCapabilities) + ", " + GnssCapabilities.of(mGnssCapabilities)); } } } /** * Updates the measurement corrections related capabilities exposed through * {@link android.location.GnssCapabilities}. */ void setSubHalMeasurementCorrectionsCapabilities(int measurementCorrectionsCapabilities) { long gnssCapabilities = GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS; if (hasCapability(measurementCorrectionsCapabilities, GnssMeasurementCorrectionsProvider.CAPABILITY_LOS_SATS)) { gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_LOS_SATS; } if (hasCapability(measurementCorrectionsCapabilities, GnssMeasurementCorrectionsProvider.CAPABILITY_EXCESS_PATH_LENGTH)) { gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH; } if (hasCapability(measurementCorrectionsCapabilities, GnssMeasurementCorrectionsProvider.CAPABILITY_REFLECTING_PLANE)) { gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_REFLECTING_PLANE; } synchronized (this) { mGnssCapabilities &= ~GNSS_CAPABILITIES_SUB_HAL_MEASUREMENT_CORRECTIONS; mGnssCapabilities |= gnssCapabilities; if (DEBUG) { Log.d(TAG, "setSubHalMeasurementCorrectionsCapabilities, mGnssCapabilities=0x" + Long.toHexString(mGnssCapabilities) + ", " + GnssCapabilities.of( mGnssCapabilities)); } } } private static boolean hasCapability(int halCapabilities, int capability) { return (halCapabilities & capability) != 0; } } services/core/java/com/android/server/location/GnssLocationProvider.java +52 −23 Original line number Diff line number Diff line Loading @@ -173,8 +173,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements public static final int GPS_CAPABILITY_MEASUREMENTS = 0x0000040; public static final int GPS_CAPABILITY_NAV_MESSAGES = 0x0000080; private static final int GPS_CAPABILITY_LOW_POWER_MODE = 0x0000100; private static final int GPS_CAPABILITY_SATELLITE_BLACKLIST = 0x0000200; static final int GPS_CAPABILITY_LOW_POWER_MODE = 0x0000100; static final int GPS_CAPABILITY_SATELLITE_BLACKLIST = 0x0000200; // The AGPS SUPL mode private static final int AGPS_SUPL_MODE_MSA = 0x02; Loading Loading @@ -338,8 +338,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // true if we started navigation private boolean mStarted; // capabilities of the GPS engine private volatile int mEngineCapabilities; // capabilities reported through the top level IGnssCallback.hal private volatile int mTopHalCapabilities; // true if XTRA is supported private boolean mSupportsXtra; Loading Loading @@ -385,6 +385,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private final NtpTimeHelper mNtpTimeHelper; private final GnssBatchingProvider mGnssBatchingProvider; private final GnssGeofenceProvider mGnssGeofenceProvider; private final GnssCapabilitiesProvider mGnssCapabilitiesProvider; // Available only on GNSS HAL 2.0 implementations and later. private GnssVisibilityControl mGnssVisibilityControl; Loading Loading @@ -593,10 +595,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0); mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0); mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler( context, GnssLocationProvider.this::onNetworkAvailable, looper); mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(context, GnssLocationProvider.this::onNetworkAvailable, looper); // App ops service to keep track of who is accessing the GPS mAppOps = mContext.getSystemService(AppOpsManager.class); Loading @@ -614,6 +614,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // while IO initialization and registration is delegated to our internal handler // this approach is just fine because events are posted to our handler anyway mGnssConfiguration = new GnssConfiguration(mContext); mGnssCapabilitiesProvider = new GnssCapabilitiesProvider(); // Create a GPS net-initiated handler (also needed by handleInitialize) mNIHandler = new GpsNetInitiatedHandler(context, mNetInitiatedListener, Loading Loading @@ -1280,12 +1281,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent); } public int getGnssCapabilities() { return mEngineCapabilities; } private boolean hasCapability(int capability) { return ((mEngineCapabilities & capability) != 0); return (mTopHalCapabilities & capability) != 0; } @NativeEntryPoint Loading Loading @@ -1493,27 +1490,52 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } @NativeEntryPoint private void setEngineCapabilities(final int capabilities, boolean hasSubHalCapabilityFlags) { // send to handler thread for fast native return, and in-order handling private void setTopHalCapabilities(int topHalCapabilities, boolean hasSubHalCapabilityFlags) { // The IGnssCallback.hal@2.0 removed sub-HAL capability flags from the Capabilities enum // and instead uses the sub-HAL non-null handle returned from IGnss.hal@2.0 to indicate // support. Therefore, the 'hasSubHalCapabilityFlags' parameter is needed to tell if the // 'capabilities' parameter includes the sub-HAL capability flags or not. Old HALs // which explicitly set the sub-HAL capability bits must continue to work. mHandler.post(() -> { mEngineCapabilities = capabilities; mTopHalCapabilities = topHalCapabilities; if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) { mNtpTimeHelper.enablePeriodicTimeInjection(); requestUtcTime(); } mGnssMeasurementsProvider.onCapabilitiesUpdated(capabilities, hasSubHalCapabilityFlags); mGnssNavigationMessageProvider.onCapabilitiesUpdated(capabilities, hasSubHalCapabilityFlags); boolean hasGeofencingCapability; boolean hasMeasurementsCapability; boolean hasNavMessagesCapability; if (hasSubHalCapabilityFlags) { hasGeofencingCapability = hasCapability(GPS_CAPABILITY_GEOFENCING); hasMeasurementsCapability = hasCapability(GPS_CAPABILITY_MEASUREMENTS); hasNavMessagesCapability = hasCapability(GPS_CAPABILITY_NAV_MESSAGES); } else { hasGeofencingCapability = mGnssGeofenceProvider.isHardwareGeofenceSupported(); hasMeasurementsCapability = mGnssMeasurementsProvider.isAvailableInPlatform(); hasNavMessagesCapability = mGnssNavigationMessageProvider.isAvailableInPlatform(); } mGnssMeasurementsProvider.onCapabilitiesUpdated(hasMeasurementsCapability); mGnssNavigationMessageProvider.onCapabilitiesUpdated(hasNavMessagesCapability); restartRequests(); mGnssCapabilitiesProvider.setTopHalCapabilities(topHalCapabilities, hasGeofencingCapability, hasMeasurementsCapability, hasNavMessagesCapability); }); } @NativeEntryPoint private void setMeasurementCorrectionsCapabilities(final int capabilities) { mHandler.post(() -> mGnssMeasurementCorrectionsProvider.onCapabilitiesUpdated( capabilities)); private void setSubHalMeasurementCorrectionsCapabilities(int subHalCapabilities) { mHandler.post(() -> { if (!mGnssMeasurementCorrectionsProvider.onCapabilitiesUpdated(subHalCapabilities)) { return; } mGnssCapabilitiesProvider.setSubHalMeasurementCorrectionsCapabilities( subHalCapabilities); }); } private void restartRequests() { Loading Loading @@ -1614,6 +1636,13 @@ public class GnssLocationProvider extends AbstractLocationProvider implements return () -> mGnssMetrics.dumpGnssMetricsAsProtoString(); } /** * @hide */ public GnssCapabilitiesProvider getGnssCapabilitiesProvider() { return mGnssCapabilitiesProvider; } @NativeEntryPoint private void reportLocationBatch(Location[] locationArray) { List<Location> locations = new ArrayList<>(Arrays.asList(locationArray)); Loading Loading @@ -2143,7 +2172,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements s.append(" mGnssNavigationMessageProvider.isRegistered()=") .append(mGnssNavigationMessageProvider.isRegistered()).append('\n'); s.append(" mDisableGpsForPowerManager=").append(mDisableGpsForPowerManager).append('\n'); s.append(" mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities)); s.append(" mTopHalCapabilities=0x").append(Integer.toHexString(mTopHalCapabilities)); s.append(" ( "); if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING "); if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB "); Loading services/core/java/com/android/server/location/GnssMeasurementCorrectionsProvider.java +11 −9 Original line number Diff line number Diff line Loading @@ -34,9 +34,9 @@ public class GnssMeasurementCorrectionsProvider { private static final String TAG = "GnssMeasurementCorrectionsProvider"; // These must match with the Capabilities enum in IMeasurementCorrectionsCallback.hal. private static final int CAPABILITY_LOS_SATS = 0x0000001; private static final int CAPABILITY_EXCESS_PATH_LENGTH = 0x0000002; private static final int CAPABILITY_REFLECTING_PLANE = 0x0000004; static final int CAPABILITY_LOS_SATS = 0x0000001; static final int CAPABILITY_EXCESS_PATH_LENGTH = 0x0000002; static final int CAPABILITY_REFLECTING_PLANE = 0x0000004; private static final int INVALID_CAPABILITIES = 1 << 31; Loading Loading @@ -83,21 +83,23 @@ public class GnssMeasurementCorrectionsProvider { } /** Handle measurement corrections capabilities update from the GNSS HAL implementation. */ void onCapabilitiesUpdated(int capabilities) { boolean onCapabilitiesUpdated(int capabilities) { if (hasCapability(capabilities, CAPABILITY_LOS_SATS) || hasCapability(capabilities, CAPABILITY_EXCESS_PATH_LENGTH)) { mCapabilities = capabilities; return true; } else { Log.e(TAG, "Failed to set capabilities. Received capabilities 0x" + Integer.toHexString(capabilities) + " does not contain the mandatory " + "LOS_SATS or the EXCESS_PATH_LENGTH capability."); return false; } } /** * Returns the measurement corrections specific capabilities of the GNSS HAL implementation. */ public int getCapabilities() { int getCapabilities() { return mCapabilities; } Loading @@ -122,14 +124,14 @@ public class GnssMeasurementCorrectionsProvider { return s.toString(); } private boolean isCapabilitiesReceived() { return mCapabilities != INVALID_CAPABILITIES; } private static boolean hasCapability(int halCapabilities, int capability) { return (halCapabilities & capability) != 0; } private boolean isCapabilitiesReceived() { return mCapabilities != INVALID_CAPABILITIES; } @VisibleForTesting static class GnssMeasurementCorrectionsProviderNative { public boolean isMeasurementCorrectionsSupported() { Loading Loading
location/java/android/location/GnssCapabilities.java +3 −4 Original line number Diff line number Diff line Loading @@ -77,15 +77,14 @@ public final class GnssCapabilities { }) public @interface Capability {} /** * @hide */ /** @hide */ public static final long INVALID_CAPABILITIES = -1; /** A bitmask of supported GNSS capabilities. */ private final long mGnssCapabilities; static GnssCapabilities of(long gnssCapabilities) { /** @hide */ public static GnssCapabilities of(long gnssCapabilities) { return new GnssCapabilities(gnssCapabilities); } Loading
services/core/java/com/android/server/LocationManagerService.java +7 −4 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ import android.location.Address; import android.location.Criteria; import android.location.GeocoderParams; import android.location.Geofence; import android.location.GnssCapabilities; import android.location.GnssMeasurementCorrections; import android.location.IBatchedLocationCallback; import android.location.IGnssMeasurementsListener; Loading Loading @@ -102,6 +103,7 @@ import com.android.server.location.GeocoderProxy; import com.android.server.location.GeofenceManager; import com.android.server.location.GeofenceProxy; import com.android.server.location.GnssBatchingProvider; import com.android.server.location.GnssCapabilitiesProvider; import com.android.server.location.GnssLocationProvider; import com.android.server.location.GnssMeasurementCorrectionsProvider; import com.android.server.location.GnssMeasurementsProvider; Loading Loading @@ -249,8 +251,8 @@ public class LocationManagerService extends ILocationManager.Stub { private int[] mCurrentUserProfiles = new int[]{UserHandle.USER_SYSTEM}; private GnssLocationProvider.GnssSystemInfoProvider mGnssSystemInfoProvider; private GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider; private GnssCapabilitiesProvider mGnssCapabilitiesProvider; private GnssBatchingProvider mGnssBatchingProvider; @GuardedBy("mLock") Loading Loading @@ -773,6 +775,7 @@ public class LocationManagerService extends ILocationManager.Stub { mGnssSystemInfoProvider = gnssProvider.getGnssSystemInfoProvider(); mGnssBatchingProvider = gnssProvider.getGnssBatchingProvider(); mGnssMetricsProvider = gnssProvider.getGnssMetricsProvider(); mGnssCapabilitiesProvider = gnssProvider.getGnssCapabilitiesProvider(); mGnssStatusProvider = gnssProvider.getGnssStatusProvider(); mNetInitiatedListener = gnssProvider.getNetInitiatedListener(); mGnssMeasurementsProvider = gnssProvider.getGnssMeasurementsProvider(); Loading Loading @@ -2970,10 +2973,10 @@ public class LocationManagerService extends ILocationManager.Stub { mContext.enforceCallingPermission( android.Manifest.permission.LOCATION_HARDWARE, "Location Hardware permission not granted to obtain GNSS chipset capabilities."); if (!hasGnssPermissions(packageName) || mGnssMeasurementCorrectionsProvider == null) { return -1; if (!hasGnssPermissions(packageName) || mGnssCapabilitiesProvider == null) { return GnssCapabilities.INVALID_CAPABILITIES; } return mGnssMeasurementCorrectionsProvider.getCapabilities(); return mGnssCapabilitiesProvider.getGnssCapabilities(); } @Override Loading
services/core/java/com/android/server/location/GnssCapabilitiesProvider.java 0 → 100644 +143 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.location; import android.location.GnssCapabilities; import android.util.Log; import com.android.internal.annotations.GuardedBy; /** * Provides GNSS capabilities supported by the GNSS HAL implementation. */ public class GnssCapabilitiesProvider { private static final String TAG = "GnssCapabilitiesProvider"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); // Bit masks for capabilities in {@link android.location.GnssCapabilities}. private static final long GNSS_CAPABILITY_LOW_POWER_MODE = 1L << GnssCapabilities.LOW_POWER_MODE; private static final long GNSS_CAPABILITY_SATELLITE_BLACKLIST = 1L << GnssCapabilities.SATELLITE_BLACKLIST; private static final long GNSS_CAPABILITY_GEOFENCING = 1L << GnssCapabilities.GEOFENCING; private static final long GNSS_CAPABILITY_MEASUREMENTS = 1L << GnssCapabilities.MEASUREMENTS; private static final long GNSS_CAPABILITY_NAV_MESSAGES = 1L << GnssCapabilities.NAV_MESSAGES; private static final long GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS = 1L << GnssCapabilities.MEASUREMENT_CORRECTIONS; private static final long GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_LOS_SATS = 1L << GnssCapabilities.MEASUREMENT_CORRECTIONS_LOS_SATS; private static final long GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH = 1L << GnssCapabilities.MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH; private static final long GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_REFLECTING_PLANE = 1L << GnssCapabilities.MEASUREMENT_CORRECTIONS_REFLECTING_PLANE; private static final long GNSS_CAPABILITIES_TOP_HAL = GNSS_CAPABILITY_LOW_POWER_MODE | GNSS_CAPABILITY_SATELLITE_BLACKLIST | GNSS_CAPABILITY_GEOFENCING | GNSS_CAPABILITY_MEASUREMENTS | GNSS_CAPABILITY_NAV_MESSAGES; private static final long GNSS_CAPABILITIES_SUB_HAL_MEASUREMENT_CORRECTIONS = GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS | GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_LOS_SATS | GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH | GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_REFLECTING_PLANE; // Capabilities in {@link android.location.GnssCapabilities} supported by GNSS chipset. @GuardedBy("this") private long mGnssCapabilities; /** * Returns the capabilities supported by the GNSS chipset. * * <p>The capabilities are described in {@link android.location.GnssCapabilities} and * their integer values correspond to the bit positions in the returned {@code long} value. */ public long getGnssCapabilities() { synchronized (this) { return mGnssCapabilities; } } /** * Updates the general capabilities exposed through {@link android.location.GnssCapabilities}. */ void setTopHalCapabilities(int topHalCapabilities, boolean hasGeofencingCapability, boolean hasMeasurementsCapability, boolean hasNavMessagesCapability) { long gnssCapabilities = 0; if (hasCapability(topHalCapabilities, GnssLocationProvider.GPS_CAPABILITY_LOW_POWER_MODE)) { gnssCapabilities |= GNSS_CAPABILITY_LOW_POWER_MODE; } if (hasCapability(topHalCapabilities, GnssLocationProvider.GPS_CAPABILITY_SATELLITE_BLACKLIST)) { gnssCapabilities |= GNSS_CAPABILITY_SATELLITE_BLACKLIST; } if (hasGeofencingCapability) { gnssCapabilities |= GNSS_CAPABILITY_GEOFENCING; } if (hasMeasurementsCapability) { gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENTS; } if (hasNavMessagesCapability) { gnssCapabilities |= GNSS_CAPABILITY_NAV_MESSAGES; } synchronized (this) { mGnssCapabilities &= ~GNSS_CAPABILITIES_TOP_HAL; mGnssCapabilities |= gnssCapabilities; if (DEBUG) { Log.d(TAG, "setTopHalCapabilities, mGnssCapabilities=0x" + Long.toHexString( mGnssCapabilities) + ", " + GnssCapabilities.of(mGnssCapabilities)); } } } /** * Updates the measurement corrections related capabilities exposed through * {@link android.location.GnssCapabilities}. */ void setSubHalMeasurementCorrectionsCapabilities(int measurementCorrectionsCapabilities) { long gnssCapabilities = GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS; if (hasCapability(measurementCorrectionsCapabilities, GnssMeasurementCorrectionsProvider.CAPABILITY_LOS_SATS)) { gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_LOS_SATS; } if (hasCapability(measurementCorrectionsCapabilities, GnssMeasurementCorrectionsProvider.CAPABILITY_EXCESS_PATH_LENGTH)) { gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH; } if (hasCapability(measurementCorrectionsCapabilities, GnssMeasurementCorrectionsProvider.CAPABILITY_REFLECTING_PLANE)) { gnssCapabilities |= GNSS_CAPABILITY_MEASUREMENT_CORRECTIONS_REFLECTING_PLANE; } synchronized (this) { mGnssCapabilities &= ~GNSS_CAPABILITIES_SUB_HAL_MEASUREMENT_CORRECTIONS; mGnssCapabilities |= gnssCapabilities; if (DEBUG) { Log.d(TAG, "setSubHalMeasurementCorrectionsCapabilities, mGnssCapabilities=0x" + Long.toHexString(mGnssCapabilities) + ", " + GnssCapabilities.of( mGnssCapabilities)); } } } private static boolean hasCapability(int halCapabilities, int capability) { return (halCapabilities & capability) != 0; } }
services/core/java/com/android/server/location/GnssLocationProvider.java +52 −23 Original line number Diff line number Diff line Loading @@ -173,8 +173,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements public static final int GPS_CAPABILITY_MEASUREMENTS = 0x0000040; public static final int GPS_CAPABILITY_NAV_MESSAGES = 0x0000080; private static final int GPS_CAPABILITY_LOW_POWER_MODE = 0x0000100; private static final int GPS_CAPABILITY_SATELLITE_BLACKLIST = 0x0000200; static final int GPS_CAPABILITY_LOW_POWER_MODE = 0x0000100; static final int GPS_CAPABILITY_SATELLITE_BLACKLIST = 0x0000200; // The AGPS SUPL mode private static final int AGPS_SUPL_MODE_MSA = 0x02; Loading Loading @@ -338,8 +338,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // true if we started navigation private boolean mStarted; // capabilities of the GPS engine private volatile int mEngineCapabilities; // capabilities reported through the top level IGnssCallback.hal private volatile int mTopHalCapabilities; // true if XTRA is supported private boolean mSupportsXtra; Loading Loading @@ -385,6 +385,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private final NtpTimeHelper mNtpTimeHelper; private final GnssBatchingProvider mGnssBatchingProvider; private final GnssGeofenceProvider mGnssGeofenceProvider; private final GnssCapabilitiesProvider mGnssCapabilitiesProvider; // Available only on GNSS HAL 2.0 implementations and later. private GnssVisibilityControl mGnssVisibilityControl; Loading Loading @@ -593,10 +595,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0); mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0); mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler( context, GnssLocationProvider.this::onNetworkAvailable, looper); mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(context, GnssLocationProvider.this::onNetworkAvailable, looper); // App ops service to keep track of who is accessing the GPS mAppOps = mContext.getSystemService(AppOpsManager.class); Loading @@ -614,6 +614,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements // while IO initialization and registration is delegated to our internal handler // this approach is just fine because events are posted to our handler anyway mGnssConfiguration = new GnssConfiguration(mContext); mGnssCapabilitiesProvider = new GnssCapabilitiesProvider(); // Create a GPS net-initiated handler (also needed by handleInitialize) mNIHandler = new GpsNetInitiatedHandler(context, mNetInitiatedListener, Loading Loading @@ -1280,12 +1281,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent); } public int getGnssCapabilities() { return mEngineCapabilities; } private boolean hasCapability(int capability) { return ((mEngineCapabilities & capability) != 0); return (mTopHalCapabilities & capability) != 0; } @NativeEntryPoint Loading Loading @@ -1493,27 +1490,52 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } @NativeEntryPoint private void setEngineCapabilities(final int capabilities, boolean hasSubHalCapabilityFlags) { // send to handler thread for fast native return, and in-order handling private void setTopHalCapabilities(int topHalCapabilities, boolean hasSubHalCapabilityFlags) { // The IGnssCallback.hal@2.0 removed sub-HAL capability flags from the Capabilities enum // and instead uses the sub-HAL non-null handle returned from IGnss.hal@2.0 to indicate // support. Therefore, the 'hasSubHalCapabilityFlags' parameter is needed to tell if the // 'capabilities' parameter includes the sub-HAL capability flags or not. Old HALs // which explicitly set the sub-HAL capability bits must continue to work. mHandler.post(() -> { mEngineCapabilities = capabilities; mTopHalCapabilities = topHalCapabilities; if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) { mNtpTimeHelper.enablePeriodicTimeInjection(); requestUtcTime(); } mGnssMeasurementsProvider.onCapabilitiesUpdated(capabilities, hasSubHalCapabilityFlags); mGnssNavigationMessageProvider.onCapabilitiesUpdated(capabilities, hasSubHalCapabilityFlags); boolean hasGeofencingCapability; boolean hasMeasurementsCapability; boolean hasNavMessagesCapability; if (hasSubHalCapabilityFlags) { hasGeofencingCapability = hasCapability(GPS_CAPABILITY_GEOFENCING); hasMeasurementsCapability = hasCapability(GPS_CAPABILITY_MEASUREMENTS); hasNavMessagesCapability = hasCapability(GPS_CAPABILITY_NAV_MESSAGES); } else { hasGeofencingCapability = mGnssGeofenceProvider.isHardwareGeofenceSupported(); hasMeasurementsCapability = mGnssMeasurementsProvider.isAvailableInPlatform(); hasNavMessagesCapability = mGnssNavigationMessageProvider.isAvailableInPlatform(); } mGnssMeasurementsProvider.onCapabilitiesUpdated(hasMeasurementsCapability); mGnssNavigationMessageProvider.onCapabilitiesUpdated(hasNavMessagesCapability); restartRequests(); mGnssCapabilitiesProvider.setTopHalCapabilities(topHalCapabilities, hasGeofencingCapability, hasMeasurementsCapability, hasNavMessagesCapability); }); } @NativeEntryPoint private void setMeasurementCorrectionsCapabilities(final int capabilities) { mHandler.post(() -> mGnssMeasurementCorrectionsProvider.onCapabilitiesUpdated( capabilities)); private void setSubHalMeasurementCorrectionsCapabilities(int subHalCapabilities) { mHandler.post(() -> { if (!mGnssMeasurementCorrectionsProvider.onCapabilitiesUpdated(subHalCapabilities)) { return; } mGnssCapabilitiesProvider.setSubHalMeasurementCorrectionsCapabilities( subHalCapabilities); }); } private void restartRequests() { Loading Loading @@ -1614,6 +1636,13 @@ public class GnssLocationProvider extends AbstractLocationProvider implements return () -> mGnssMetrics.dumpGnssMetricsAsProtoString(); } /** * @hide */ public GnssCapabilitiesProvider getGnssCapabilitiesProvider() { return mGnssCapabilitiesProvider; } @NativeEntryPoint private void reportLocationBatch(Location[] locationArray) { List<Location> locations = new ArrayList<>(Arrays.asList(locationArray)); Loading Loading @@ -2143,7 +2172,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements s.append(" mGnssNavigationMessageProvider.isRegistered()=") .append(mGnssNavigationMessageProvider.isRegistered()).append('\n'); s.append(" mDisableGpsForPowerManager=").append(mDisableGpsForPowerManager).append('\n'); s.append(" mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities)); s.append(" mTopHalCapabilities=0x").append(Integer.toHexString(mTopHalCapabilities)); s.append(" ( "); if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING "); if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB "); Loading
services/core/java/com/android/server/location/GnssMeasurementCorrectionsProvider.java +11 −9 Original line number Diff line number Diff line Loading @@ -34,9 +34,9 @@ public class GnssMeasurementCorrectionsProvider { private static final String TAG = "GnssMeasurementCorrectionsProvider"; // These must match with the Capabilities enum in IMeasurementCorrectionsCallback.hal. private static final int CAPABILITY_LOS_SATS = 0x0000001; private static final int CAPABILITY_EXCESS_PATH_LENGTH = 0x0000002; private static final int CAPABILITY_REFLECTING_PLANE = 0x0000004; static final int CAPABILITY_LOS_SATS = 0x0000001; static final int CAPABILITY_EXCESS_PATH_LENGTH = 0x0000002; static final int CAPABILITY_REFLECTING_PLANE = 0x0000004; private static final int INVALID_CAPABILITIES = 1 << 31; Loading Loading @@ -83,21 +83,23 @@ public class GnssMeasurementCorrectionsProvider { } /** Handle measurement corrections capabilities update from the GNSS HAL implementation. */ void onCapabilitiesUpdated(int capabilities) { boolean onCapabilitiesUpdated(int capabilities) { if (hasCapability(capabilities, CAPABILITY_LOS_SATS) || hasCapability(capabilities, CAPABILITY_EXCESS_PATH_LENGTH)) { mCapabilities = capabilities; return true; } else { Log.e(TAG, "Failed to set capabilities. Received capabilities 0x" + Integer.toHexString(capabilities) + " does not contain the mandatory " + "LOS_SATS or the EXCESS_PATH_LENGTH capability."); return false; } } /** * Returns the measurement corrections specific capabilities of the GNSS HAL implementation. */ public int getCapabilities() { int getCapabilities() { return mCapabilities; } Loading @@ -122,14 +124,14 @@ public class GnssMeasurementCorrectionsProvider { return s.toString(); } private boolean isCapabilitiesReceived() { return mCapabilities != INVALID_CAPABILITIES; } private static boolean hasCapability(int halCapabilities, int capability) { return (halCapabilities & capability) != 0; } private boolean isCapabilitiesReceived() { return mCapabilities != INVALID_CAPABILITIES; } @VisibleForTesting static class GnssMeasurementCorrectionsProviderNative { public boolean isMeasurementCorrectionsSupported() { Loading