summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yu-Han Yang <yuhany@google.com> 2020-10-30 14:00:17 -0700
committer Yu-Han Yang <yuhany@google.com> 2020-11-16 17:21:24 -0800
commite4bcffd2a2832bb9abeb0200c6ff6cc8c59f86f3 (patch)
tree179be836c940a10834aa5f012a1238d6b74f785e
parent115861dac372a757c9a4b9993b4ff331f700f024 (diff)
Add IGnssPowerIndication AIDL HAL (framework/base)
Bug: 168123084 Bug: 171821213 Test: on Cuttlefish Change-Id: I077d66294f5c679094672327da0fb2ab174f448c
-rw-r--r--services/core/Android.bp1
-rw-r--r--services/core/java/com/android/server/location/LocationShellCommand.java1
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssLocationProvider.java75
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssManagerService.java10
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssNative.java12
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssPowerIndicationProvider.java122
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssPowerStats.java134
-rw-r--r--services/core/jni/com_android_server_location_GnssLocationProvider.cpp99
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",