diff options
| author | 2020-10-30 14:00:17 -0700 | |
|---|---|---|
| committer | 2020-11-16 17:21:24 -0800 | |
| commit | e4bcffd2a2832bb9abeb0200c6ff6cc8c59f86f3 (patch) | |
| tree | 179be836c940a10834aa5f012a1238d6b74f785e | |
| parent | 115861dac372a757c9a4b9993b4ff331f700f024 (diff) | |
Add IGnssPowerIndication AIDL HAL (framework/base)
Bug: 168123084
Bug: 171821213
Test: on Cuttlefish
Change-Id: I077d66294f5c679094672327da0fb2ab174f448c
8 files changed, 423 insertions, 31 deletions
diff --git a/services/core/Android.bp b/services/core/Android.bp index fb3c61bc54bc..b24dc178842d 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -83,6 +83,7 @@ java_library_static { libs: [ "services.net", "android.hardware.light-V2.0-java", + "android.hardware.gnss-java", "android.hardware.power-java", "android.hardware.power-V1.0-java", "android.hardware.vibrator-java", diff --git a/services/core/java/com/android/server/location/LocationShellCommand.java b/services/core/java/com/android/server/location/LocationShellCommand.java index 909873f07993..8c1afab00b9a 100644 --- a/services/core/java/com/android/server/location/LocationShellCommand.java +++ b/services/core/java/com/android/server/location/LocationShellCommand.java @@ -88,5 +88,6 @@ class LocationShellCommand extends BasicShellCommandHandler { pw.println(" force_time_injection - requests NTP time injection to chipset"); pw.println(" force_psds_injection - " + "requests predictive aiding data injection to chipset"); + pw.println(" request_power_stats - requests GNSS power stats update from chipset"); } } 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 593312e82f21..d27c9b4ee5ba 100644 --- a/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +++ b/services/core/java/com/android/server/location/gnss/GnssLocationProvider.java @@ -363,6 +363,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements private final GnssMeasurementCorrectionsProvider mGnssMeasurementCorrectionsProvider; private final GnssAntennaInfoProvider mGnssAntennaInfoProvider; private final GnssNavigationMessageProvider mGnssNavigationMessageProvider; + private final GnssPowerIndicationProvider mGnssPowerIndicationProvider; private final NtpTimeHelper mNtpTimeHelper; private final GnssGeofenceProvider mGnssGeofenceProvider; private final GnssCapabilitiesProvider mGnssCapabilitiesProvider; @@ -534,6 +535,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements mGnssMeasurementCorrectionsProvider = new GnssMeasurementCorrectionsProvider(mHandler); mGnssAntennaInfoProvider = new GnssAntennaInfoProvider(injector); mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(injector); + mGnssPowerIndicationProvider = new GnssPowerIndicationProvider(); mGnssMetrics = new GnssMetrics(mContext, mBatteryStats); mNtpTimeHelper = new NtpTimeHelper(mContext, mHandler.getLooper(), this); @@ -1128,6 +1130,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements downloadPsdsData(/* psdsType= */ GnssPsdsDownloader.LONG_TERM_PSDS_SERVER_INDEX); } + } else if ("request_power_stats".equals(command)) { + GnssPowerIndicationProvider.requestPowerStats(); } else { Log.w(TAG, "sendExtraCommand: unknown command " + command); } @@ -1455,6 +1459,10 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } } + void reportGnssPowerStats(GnssPowerStats powerStats) { + mHandler.post(() -> mGnssPowerIndicationProvider.onGnssPowerStatsAvailable(powerStats)); + } + void setTopHalCapabilities(int topHalCapabilities) { mHandler.post(() -> { mTopHalCapabilities = topHalCapabilities; @@ -1481,6 +1489,15 @@ public class GnssLocationProvider extends AbstractLocationProvider implements }); } + /** + * Sets the capabilities bits for IGnssPowerIndication HAL. + * + * These capabilities are defined in IGnssPowerIndicationCallback.aidl. + */ + void setSubHalPowerIndicationCapabilities(int subHalCapabilities) { + mHandler.post(() -> mGnssPowerIndicationProvider.onCapabilitiesUpdated(subHalCapabilities)); + } + private void restartRequests() { Log.i(TAG, "restartRequests"); @@ -1965,44 +1982,40 @@ public class GnssLocationProvider extends AbstractLocationProvider implements } } - StringBuilder s = new StringBuilder(); - s.append("mStarted=").append(mStarted).append(" (changed "); + pw.print("mStarted=" + mStarted + " (changed "); TimeUtils.formatDuration(SystemClock.elapsedRealtime() - - mStartedChangedElapsedRealtime, s); - s.append(" ago)").append('\n'); - s.append("mBatchingEnabled=").append(mBatchingEnabled).append('\n'); - s.append("mBatchingStarted=").append(mBatchingStarted).append('\n'); - s.append("mBatchSize=").append(getBatchSize()).append('\n'); - s.append("mFixInterval=").append(mFixInterval).append('\n'); - 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 "); - if (hasCapability(GPS_CAPABILITY_MSA)) s.append("MSA "); - if (hasCapability(GPS_CAPABILITY_SINGLE_SHOT)) s.append("SINGLE_SHOT "); - if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) s.append("ON_DEMAND_TIME "); - if (hasCapability(GPS_CAPABILITY_GEOFENCING)) s.append("GEOFENCING "); - if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) s.append("MEASUREMENTS "); - if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES "); - if (hasCapability(GPS_CAPABILITY_LOW_POWER_MODE)) s.append("LOW_POWER_MODE "); - if (hasCapability(GPS_CAPABILITY_SATELLITE_BLOCKLIST)) s.append("SATELLITE_BLOCKLIST "); + - mStartedChangedElapsedRealtime, pw); + pw.println(" ago)"); + pw.println("mBatchingEnabled=" + mBatchingEnabled); + pw.println("mBatchingStarted=" + mBatchingStarted); + pw.println("mBatchSize=" + getBatchSize()); + pw.println("mFixInterval=" + mFixInterval); + mGnssPowerIndicationProvider.dump(fd, pw, args); + pw.print("mTopHalCapabilities=0x" + Integer.toHexString(mTopHalCapabilities) + " ( "); + if (hasCapability(GPS_CAPABILITY_SCHEDULING)) pw.print("SCHEDULING "); + if (hasCapability(GPS_CAPABILITY_MSB)) pw.print("MSB "); + if (hasCapability(GPS_CAPABILITY_MSA)) pw.print("MSA "); + if (hasCapability(GPS_CAPABILITY_SINGLE_SHOT)) pw.print("SINGLE_SHOT "); + if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) pw.print("ON_DEMAND_TIME "); + if (hasCapability(GPS_CAPABILITY_GEOFENCING)) pw.print("GEOFENCING "); + if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) pw.print("MEASUREMENTS "); + if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) pw.print("NAV_MESSAGES "); + if (hasCapability(GPS_CAPABILITY_LOW_POWER_MODE)) pw.print("LOW_POWER_MODE "); + if (hasCapability(GPS_CAPABILITY_SATELLITE_BLOCKLIST)) pw.print("SATELLITE_BLOCKLIST "); if (hasCapability(GPS_CAPABILITY_MEASUREMENT_CORRECTIONS)) { - s.append("MEASUREMENT_CORRECTIONS "); + pw.print("MEASUREMENT_CORRECTIONS "); } - if (hasCapability(GPS_CAPABILITY_ANTENNA_INFO)) s.append("ANTENNA_INFO "); - s.append(")\n"); + if (hasCapability(GPS_CAPABILITY_ANTENNA_INFO)) pw.print("ANTENNA_INFO "); + pw.println(")"); if (hasCapability(GPS_CAPABILITY_MEASUREMENT_CORRECTIONS)) { - s.append("SubHal=MEASUREMENT_CORRECTIONS["); - s.append(mGnssMeasurementCorrectionsProvider.toStringCapabilities()); - s.append("]\n"); + pw.println("SubHal=MEASUREMENT_CORRECTIONS[" + + mGnssMeasurementCorrectionsProvider.toStringCapabilities() + "]"); } - s.append(mGnssMetrics.dumpGnssMetricsAsText()); + pw.print(mGnssMetrics.dumpGnssMetricsAsText()); if (dumpAll) { - s.append("native internal state: \n"); - s.append(" ").append(native_get_internal_state()); - s.append("\n"); + pw.println("native internal state: "); + pw.println(" " + native_get_internal_state()); } - pw.append(s); } // preallocated to avoid memory allocation in reportNmea() 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 47c528b68fb9..e110b8bded6f 100644 --- a/services/core/java/com/android/server/location/gnss/GnssManagerService.java +++ b/services/core/java/com/android/server/location/gnss/GnssManagerService.java @@ -334,6 +334,11 @@ public class GnssManagerService implements GnssNative.Callbacks { } @Override + public void reportGnssPowerStats(GnssPowerStats powerStats) { + mGnssLocationProvider.reportGnssPowerStats(powerStats); + } + + @Override public void setTopHalCapabilities(int topHalCapabilities) { mGnssLocationProvider.setTopHalCapabilities(topHalCapabilities); } @@ -344,6 +349,11 @@ public class GnssManagerService implements GnssNative.Callbacks { } @Override + public void setSubHalPowerIndicationCapabilities(int subHalCapabilities) { + mGnssLocationProvider.setSubHalPowerIndicationCapabilities(subHalCapabilities); + } + + @Override public void setGnssYearOfHardware(int yearOfHardware) { mGnssLocationProvider.setGnssYearOfHardware(yearOfHardware); } diff --git a/services/core/java/com/android/server/location/gnss/GnssNative.java b/services/core/java/com/android/server/location/gnss/GnssNative.java index 3933f9a6cbd0..4494c191a16b 100644 --- a/services/core/java/com/android/server/location/gnss/GnssNative.java +++ b/services/core/java/com/android/server/location/gnss/GnssNative.java @@ -48,8 +48,10 @@ class GnssNative { void reportMeasurementData(GnssMeasurementsEvent event); void reportAntennaInfo(List<GnssAntennaInfo> antennaInfos); void reportNavigationMessage(GnssNavigationMessage event); + void reportGnssPowerStats(GnssPowerStats powerStats); void setTopHalCapabilities(int topHalCapabilities); void setSubHalMeasurementCorrectionsCapabilities(int subHalCapabilities); + void setSubHalPowerIndicationCapabilities(int subHalCapabilities); void setGnssYearOfHardware(int yearOfHardware); void setGnssHardwareModelName(String modelName); void reportGnssServiceRestarted(); @@ -179,6 +181,11 @@ class GnssNative { } @NativeEntryPoint + private void reportGnssPowerStats(GnssPowerStats powerStats) { + mCallbacks.reportGnssPowerStats(powerStats); + } + + @NativeEntryPoint private void setTopHalCapabilities(int topHalCapabilities) { mCallbacks.setTopHalCapabilities(topHalCapabilities); } @@ -189,6 +196,11 @@ class GnssNative { } @NativeEntryPoint + private void setSubHalPowerIndicationCapabilities(int subHalCapabilities) { + mCallbacks.setSubHalPowerIndicationCapabilities(subHalCapabilities); + } + + @NativeEntryPoint private void setGnssYearOfHardware(int yearOfHardware) { mCallbacks.setGnssYearOfHardware(yearOfHardware); } diff --git a/services/core/java/com/android/server/location/gnss/GnssPowerIndicationProvider.java b/services/core/java/com/android/server/location/gnss/GnssPowerIndicationProvider.java new file mode 100644 index 000000000000..5941a33298dd --- /dev/null +++ b/services/core/java/com/android/server/location/gnss/GnssPowerIndicationProvider.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2020 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.gnss; + +import static android.hardware.gnss.IGnssPowerIndicationCallback.CAPABILITY_MULTIBAND_ACQUISITION; +import static android.hardware.gnss.IGnssPowerIndicationCallback.CAPABILITY_MULTIBAND_TRACKING; +import static android.hardware.gnss.IGnssPowerIndicationCallback.CAPABILITY_OTHER_MODES; +import static android.hardware.gnss.IGnssPowerIndicationCallback.CAPABILITY_SINGLEBAND_ACQUISITION; +import static android.hardware.gnss.IGnssPowerIndicationCallback.CAPABILITY_SINGLEBAND_TRACKING; +import static android.hardware.gnss.IGnssPowerIndicationCallback.CAPABILITY_TOTAL; + +import android.util.Log; + +import java.io.FileDescriptor; +import java.io.PrintWriter; + +/** + * Manages GNSS Power Indication operations. + */ +class GnssPowerIndicationProvider { + private static final String TAG = "GnssPowerIndPdr"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + private volatile int mCapabilities; + private GnssPowerStats mGnssPowerStats; + + /** + * Handles GNSS Power Indication capabilities update from the GNSS HAL callback. + */ + public void onCapabilitiesUpdated(int capabilities) { + mCapabilities = capabilities; + } + + public void onGnssPowerStatsAvailable(GnssPowerStats powerStats) { + if (DEBUG) { + Log.d(TAG, "onGnssPowerStatsAvailable: " + powerStats.toString()); + } + powerStats.validate(); + mGnssPowerStats = powerStats; + } + + /** + * Returns the GNSS Power Indication specific capabilities. + */ + public int getCapabilities() { + return mCapabilities; + } + + /** + * Requests the GNSS HAL to report {@link GnssPowerStats}. + */ + public static void requestPowerStats() { + native_request_power_stats(); + } + + private boolean hasCapability(int capability) { + return (mCapabilities & capability) != 0; + } + + /** + * Dump info for debugging. + */ + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (mGnssPowerStats == null) { + return; + } + pw.print("GnssPowerStats["); + if (mGnssPowerStats.hasElapsedRealtimeNanos()) { + pw.print("ElapsedRealtime=" + mGnssPowerStats.getElapsedRealtimeNanos()); + } + if (mGnssPowerStats.hasElapsedRealtimeUncertaintyNanos()) { + pw.print(", ElapsedRealtimeUncertaintyNanos=" + + mGnssPowerStats.getElapsedRealtimeUncertaintyNanos()); + } + if (hasCapability(CAPABILITY_TOTAL)) { + pw.print(", TotalEnergyMilliJoule=" + mGnssPowerStats.getTotalEnergyMilliJoule()); + } + if (hasCapability(CAPABILITY_SINGLEBAND_TRACKING)) { + pw.print(", SinglebandTrackingModeEnergyMilliJoule=" + + mGnssPowerStats.getSinglebandTrackingModeEnergyMilliJoule()); + } + if (hasCapability(CAPABILITY_MULTIBAND_TRACKING)) { + pw.print(", MultibandTrackingModeEnergyMilliJoule=" + + mGnssPowerStats.getMultibandTrackingModeEnergyMilliJoule()); + } + if (hasCapability(CAPABILITY_SINGLEBAND_ACQUISITION)) { + pw.print(", SinglebandAcquisitionModeEnergyMilliJoule=" + + mGnssPowerStats.getSinglebandAcquisitionModeEnergyMilliJoule()); + } + if (hasCapability(CAPABILITY_MULTIBAND_ACQUISITION)) { + pw.print(", MultibandAcquisitionModeEnergyMilliJoule=" + + mGnssPowerStats.getMultibandAcquisitionModeEnergyMilliJoule()); + } + if (hasCapability(CAPABILITY_OTHER_MODES)) { + pw.print(", OtherModesEnergyMilliJoule=["); + double[] otherModes = mGnssPowerStats.getOtherModesEnergyMilliJoule(); + for (int i = 0; i < otherModes.length; i++) { + pw.print(otherModes[i]); + if (i < otherModes.length - 1) { + pw.print(", "); + } + } + pw.print("] "); + } + pw.println(']'); + } + + private static native void native_request_power_stats(); +} diff --git a/services/core/java/com/android/server/location/gnss/GnssPowerStats.java b/services/core/java/com/android/server/location/gnss/GnssPowerStats.java new file mode 100644 index 000000000000..70ab3c647a97 --- /dev/null +++ b/services/core/java/com/android/server/location/gnss/GnssPowerStats.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2020 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.gnss; + +import static android.hardware.gnss.IGnss.ELAPSED_REALTIME_HAS_TIMESTAMP_NS; +import static android.hardware.gnss.IGnss.ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS; + +import com.android.internal.util.Preconditions; + +/** + * Represents Cumulative GNSS power statistics since boot. + */ +class GnssPowerStats { + private final int mElapsedRealtimeFlags; + private final long mElapsedRealtimeNanos; + private final double mElapsedRealtimeUncertaintyNanos; + private final double mTotalEnergyMilliJoule; + private final double mSinglebandTrackingModeEnergyMilliJoule; + private final double mMultibandTrackingModeEnergyMilliJoule; + private final double mSinglebandAcquisitionModeEnergyMilliJoule; + private final double mMultibandAcquisitionModeEnergyMilliJoule; + private final double[] mOtherModesEnergyMilliJoule; + + GnssPowerStats(int elapsedRealtimeFlags, + long elapsedRealtimeNanos, + double elapsedRealtimeUncertaintyNanos, + double totalEnergyMilliJoule, + double singlebandTrackingModeEnergyMilliJoule, + double multibandTrackingModeEnergyMilliJoule, + double singlebandAcquisitionModeEnergyMilliJoule, + double multibandAcquisitionModeEnergyMilliJoule, + double[] otherModesEnergyMilliJoule) { + mElapsedRealtimeFlags = elapsedRealtimeFlags; + mElapsedRealtimeNanos = elapsedRealtimeNanos; + mElapsedRealtimeUncertaintyNanos = elapsedRealtimeUncertaintyNanos; + mTotalEnergyMilliJoule = totalEnergyMilliJoule; + mSinglebandTrackingModeEnergyMilliJoule = singlebandTrackingModeEnergyMilliJoule; + mMultibandTrackingModeEnergyMilliJoule = multibandTrackingModeEnergyMilliJoule; + mSinglebandAcquisitionModeEnergyMilliJoule = singlebandAcquisitionModeEnergyMilliJoule; + mMultibandAcquisitionModeEnergyMilliJoule = multibandAcquisitionModeEnergyMilliJoule; + mOtherModesEnergyMilliJoule = otherModesEnergyMilliJoule; + } + + /** Returns true if {@link #getElapsedRealtimeNanos()} is available. */ + public boolean hasElapsedRealtimeNanos() { + return (mElapsedRealtimeFlags & ELAPSED_REALTIME_HAS_TIMESTAMP_NS) != 0; + } + + /** Returns true if {@link #getElapsedRealtimeUncertaintyNanos()} is available. */ + public boolean hasElapsedRealtimeUncertaintyNanos() { + return (mElapsedRealtimeFlags & ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS) != 0; + } + + /** + * Gets the elapsed realtime of the GnssPowerStats since boot in nanoseconds. + */ + public long getElapsedRealtimeNanos() { + return mElapsedRealtimeNanos; + } + + /** + * Gets the estimate of the relative precision of the alignment of the + * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in + * nanoseconds (68% confidence). + */ + public double getElapsedRealtimeUncertaintyNanos() { + return mElapsedRealtimeUncertaintyNanos; + } + + /** + * Total GNSS energy consumption in milli-joules (or mWatt-seconds). + */ + public double getTotalEnergyMilliJoule() { + return mTotalEnergyMilliJoule; + } + + /** + * Total energy consumption in milli-joules (or mWatt-seconds) for which the GNSS engine is + * tracking signals of a single frequency band. + */ + public double getSinglebandTrackingModeEnergyMilliJoule() { + return mSinglebandTrackingModeEnergyMilliJoule; + } + + /** + * Total energy consumption in milli-joules (or mWatt-seconds) for which the GNSS engine is + * tracking signals of multiple frequency bands. + */ + public double getMultibandTrackingModeEnergyMilliJoule() { + return mMultibandTrackingModeEnergyMilliJoule; + } + + /** + * Total energy consumption in milli-joules (or mWatt-seconds) for which the GNSS engine is + * acquiring signals of a single frequency band. + */ + public double getSinglebandAcquisitionModeEnergyMilliJoule() { + return mSinglebandAcquisitionModeEnergyMilliJoule; + } + + /** + * Total energy consumption in milli-joules (or mWatt-seconds) for which the GNSS engine is + * acquiring signals of multiple frequency bands. + */ + public double getMultibandAcquisitionModeEnergyMilliJoule() { + return mMultibandAcquisitionModeEnergyMilliJoule; + } + + /** + * Total energy consumption in milli-joules (or mWatt-seconds) for which the GNSS engine is + * operating in each of the vendor-specific power modes, in addition to other generic modes. + */ + public double[] getOtherModesEnergyMilliJoule() { + return mOtherModesEnergyMilliJoule; + } + + public void validate() { + Preconditions.checkArgument(hasElapsedRealtimeNanos()); + } +} diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 3bff4404754a..1a6128fa92ba 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -31,6 +31,7 @@ #include <android/hardware/gnss/2.1/IGnssMeasurement.h> #include <android/hardware/gnss/3.0/IGnssPsds.h> #include <android/hardware/gnss/BnGnss.h> +#include <android/hardware/gnss/BnGnssPowerIndicationCallback.h> #include <android/hardware/gnss/BnGnssPsdsCallback.h> #include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h> #include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.h> @@ -61,6 +62,7 @@ static jclass class_location; static jclass class_gnssNavigationMessage; static jclass class_gnssClock; static jclass class_gnssAntennaInfoBuilder; +static jclass class_gnssPowerStats; static jclass class_phaseCenterOffset; static jclass class_sphericalCorrections; static jclass class_arrayList; @@ -93,6 +95,7 @@ static jmethodID method_reportAntennaInfo; static jmethodID method_reportNavigationMessages; static jmethodID method_reportLocationBatch; static jmethodID method_reportGnssServiceDied; +static jmethodID method_reportGnssPowerStats; static jmethodID method_setSubHalMeasurementCorrectionsCapabilities; static jmethodID method_correctionsGetLatitudeDegrees; static jmethodID method_correctionsGetLongitudeDegrees; @@ -126,6 +129,7 @@ static jmethodID method_gnssNavigationMessageCtor; static jmethodID method_gnssClockCtor; static jmethodID method_gnssMeasurementCtor; static jmethodID method_gnssAntennaInfoBuilderCtor; +static jmethodID method_gnssPowerStatsCtor; static jmethodID method_phaseCenterOffsetCtor; static jmethodID method_sphericalCorrectionsCtor; static jmethodID method_arrayListCtor; @@ -135,6 +139,7 @@ static jmethodID method_gnssAntennaInfoBuilderSetPhaseCenterOffset; static jmethodID method_gnssAntennaInfoBuilderSetPhaseCenterVariationCorrections; static jmethodID method_gnssAntennaInfoBuilderSetSignalGainCorrections; static jmethodID method_gnssAntennaInfoBuilderBuild; +static jmethodID method_setSubHalPowerIndicationCapabilities; /* * Save a pointer to JavaVm to attach/detach threads executing @@ -225,6 +230,9 @@ using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlC using android::hardware::gnss::BlocklistedSource; using android::hardware::gnss::GnssConstellationType; +using android::hardware::gnss::GnssPowerStats; +using android::hardware::gnss::IGnssPowerIndication; +using android::hardware::gnss::IGnssPowerIndicationCallback; using android::hardware::gnss::PsdsType; using IGnssAidl = android::hardware::gnss::IGnss; using IGnssPsdsAidl = android::hardware::gnss::IGnssPsds; @@ -271,6 +279,7 @@ sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr; sp<IGnssMeasurement_V2_0> gnssMeasurementIface_V2_0 = nullptr; sp<IGnssMeasurement_V2_1> gnssMeasurementIface_V2_1 = nullptr; sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr; +sp<IGnssPowerIndication> gnssPowerIndicationIface = nullptr; sp<IMeasurementCorrections_V1_0> gnssCorrectionsIface_V1_0 = nullptr; sp<IMeasurementCorrections_V1_1> gnssCorrectionsIface_V1_1 = nullptr; sp<IGnssVisibilityControl> gnssVisibilityControlIface = nullptr; @@ -410,6 +419,8 @@ template<> const char *const JavaMethodHelper<bool>::signature_ = "(Z)V"; template<> const char *const JavaMethodHelper<jstring>::signature_ = "(Ljava/lang/String;)V"; +template <> +const char* const JavaMethodHelper<jdoubleArray>::signature_ = "([D)V"; #define SET(setter, value) object.callSetter("set" # setter, (value)) @@ -934,6 +945,50 @@ Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback_V2_0::GnssSys } /* + * GnssPowerIndicationCallback class implements the callback methods for the IGnssPowerIndication + * interface. + */ +struct GnssPowerIndicationCallback : public android::hardware::gnss::BnGnssPowerIndicationCallback { +public: + Status setCapabilitiesCb(const int capabilities) override; + Status gnssPowerStatsCb(const GnssPowerStats& data) override; +}; + +Status GnssPowerIndicationCallback::setCapabilitiesCb(const int capabilities) { + ALOGD("GnssPowerIndicationCallback::%s: %du\n", __func__, capabilities); + JNIEnv* env = getJniEnv(); + env->CallVoidMethod(mCallbacksObj, method_setSubHalPowerIndicationCapabilities, capabilities); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + return Status::ok(); +} + +Status GnssPowerIndicationCallback::gnssPowerStatsCb(const GnssPowerStats& data) { + JNIEnv* env = getJniEnv(); + + int size = data.otherModesEnergyMilliJoule.size(); + jdoubleArray otherModesEnergy = env->NewDoubleArray(size); + if (size > 0) { + env->SetDoubleArrayRegion(otherModesEnergy, (jsize)0, size, + &(data.otherModesEnergyMilliJoule[0])); + } + jobject gnssPowerStats = + env->NewObject(class_gnssPowerStats, method_gnssPowerStatsCtor, + data.elapsedRealtime.flags, data.elapsedRealtime.timestampNs, + data.elapsedRealtime.timeUncertaintyNs, data.totalEnergyMilliJoule, + data.singlebandTrackingModeEnergyMilliJoule, + data.multibandTrackingModeEnergyMilliJoule, + data.singlebandAcquisitionModeEnergyMilliJoule, + data.multibandAcquisitionModeEnergyMilliJoule, otherModesEnergy); + + env->CallVoidMethod(mCallbacksObj, method_reportGnssPowerStats, gnssPowerStats); + + checkAndClearExceptionFromCallback(env, __FUNCTION__); + env->DeleteLocalRef(gnssPowerStats); + env->DeleteLocalRef(otherModesEnergy); + return Status::ok(); +} + +/* * GnssPsdsCallback class implements the callback methods for the IGnssPsds * interface. */ @@ -2033,10 +2088,15 @@ static void android_location_GnssNative_class_init_once(JNIEnv* env, jclass claz method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V"); method_reportNfwNotification = env->GetMethodID(clazz, "reportNfwNotification", "(Ljava/lang/String;BLjava/lang/String;BLjava/lang/String;BZZ)V"); + method_reportGnssPowerStats = + env->GetMethodID(clazz, "reportGnssPowerStats", + "(Lcom/android/server/location/gnss/GnssPowerStats;)V"); method_isInEmergencySession = env->GetMethodID(clazz, "isInEmergencySession", "()Z"); method_setSubHalMeasurementCorrectionsCapabilities = env->GetMethodID(clazz, "setSubHalMeasurementCorrectionsCapabilities", "(I)V"); + method_setSubHalPowerIndicationCapabilities = + env->GetMethodID(clazz, "setSubHalPowerIndicationCapabilities", "(I)V"); jclass measCorrClass = env->FindClass("android/location/GnssMeasurementCorrections"); method_correctionsGetLatitudeDegrees = env->GetMethodID( @@ -2134,6 +2194,10 @@ static void android_location_GnssNative_class_init_once(JNIEnv* env, jclass claz method_sphericalCorrectionsCtor = env->GetMethodID(class_sphericalCorrections, "<init>", "([[D[[D)V"); + jclass gnssPowerStatsClass = env->FindClass("com/android/server/location/gnss/GnssPowerStats"); + class_gnssPowerStats = (jclass)env->NewGlobalRef(gnssPowerStatsClass); + method_gnssPowerStatsCtor = env->GetMethodID(class_gnssPowerStats, "<init>", "(IJDDDDDD[D)V"); + jclass locationClass = env->FindClass("android/location/Location"); class_location = (jclass) env->NewGlobalRef(locationClass); method_locationCtor = env->GetMethodID(class_location, "<init>", "(Ljava/lang/String;)V"); @@ -2424,6 +2488,14 @@ static void android_location_GnssNative_init_once(JNIEnv* env, jobject obj, } } + if (gnssHalAidl != nullptr) { + sp<IGnssPowerIndication> gnssPowerIndication; + auto status = gnssHalAidl->getExtensionGnssPowerIndication(&gnssPowerIndication); + if (checkAidlStatus(status, "Unable to get a handle to GnssPowerIndication interface.")) { + gnssPowerIndicationIface = gnssPowerIndication; + } + } + if (mCallbacksObj) { ALOGE("Callbacks already initialized"); } else { @@ -2571,6 +2643,16 @@ static jboolean android_location_GnssLocationProvider_init(JNIEnv* /* env */, jo ALOGI("Unable to find IMeasurementCorrections."); } + // Set IGnssPowerIndication.hal callback. + if (gnssPowerIndicationIface != nullptr) { + sp<IGnssPowerIndicationCallback> gnssPowerIndicationCallback = + new GnssPowerIndicationCallback(); + auto status = gnssPowerIndicationIface->setCallback(gnssPowerIndicationCallback); + if (!checkAidlStatus(status, "IGnssPowerIndication setCallback() failed.")) { + gnssPowerIndicationIface = nullptr; + } + } + return JNI_TRUE; } @@ -3024,6 +3106,15 @@ static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* return internalStateStr; } +static void android_location_GnssLocationProvider_request_power_stats(JNIEnv* env, + jobject /* obj */) { + if (gnssPowerIndicationIface == nullptr) { + return; + } + auto status = gnssPowerIndicationIface->requestGnssPowerStats(); + checkAidlStatus(status, "IGnssPowerIndication requestGnssPowerStats() failed."); +} + static jboolean android_location_GnssLocationProvider_is_gnss_visibility_control_supported( JNIEnv* /* env */, jclass /* clazz */) { return (gnssVisibilityControlIface != nullptr) ? JNI_TRUE : JNI_FALSE; @@ -3810,6 +3901,12 @@ static const JNINativeMethod sVisibilityControlMethods[] = { android_location_GnssVisibilityControl_enable_nfw_location_access)}, }; +static const JNINativeMethod sPowerIndicationMethods[] = { + /* name, signature, funcPtr */ + {"native_request_power_stats", "()V", + reinterpret_cast<void*>(android_location_GnssLocationProvider_request_power_stats)}, +}; + int register_android_server_location_GnssLocationProvider(JNIEnv* env) { jniRegisterNativeMethods(env, "com/android/server/location/gnss/GnssAntennaInfoProvider", sAntennaInfoMethods, NELEM(sAntennaInfoMethods)); @@ -3830,6 +3927,8 @@ int register_android_server_location_GnssLocationProvider(JNIEnv* env) { sConfigurationMethods, NELEM(sConfigurationMethods)); jniRegisterNativeMethods(env, "com/android/server/location/gnss/GnssVisibilityControl", sVisibilityControlMethods, NELEM(sVisibilityControlMethods)); + jniRegisterNativeMethods(env, "com/android/server/location/gnss/GnssPowerIndicationProvider", + sPowerIndicationMethods, NELEM(sPowerIndicationMethods)); jniRegisterNativeMethods(env, "com/android/server/location/gnss/GnssLocationProvider", sLocationProviderMethods, NELEM(sLocationProviderMethods)); return jniRegisterNativeMethods(env, "com/android/server/location/gnss/GnssNative", |