Add IGnssPowerIndication AIDL HAL (framework/base)

Bug: 168123084
Bug: 171821213
Test: on Cuttlefish
Change-Id: I077d66294f5c679094672327da0fb2ab174f448c
This commit is contained in:
Yu-Han Yang
2020-10-30 14:00:17 -07:00
parent 115861dac3
commit e4bcffd2a2
8 changed files with 423 additions and 31 deletions

View File

@@ -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",

View File

@@ -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");
}
}

View File

@@ -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()

View File

@@ -333,6 +333,11 @@ public class GnssManagerService implements GnssNative.Callbacks {
mGnssLocationProvider.reportNavigationMessage(event);
}
@Override
public void reportGnssPowerStats(GnssPowerStats powerStats) {
mGnssLocationProvider.reportGnssPowerStats(powerStats);
}
@Override
public void setTopHalCapabilities(int topHalCapabilities) {
mGnssLocationProvider.setTopHalCapabilities(topHalCapabilities);
@@ -343,6 +348,11 @@ public class GnssManagerService implements GnssNative.Callbacks {
mGnssLocationProvider.setSubHalMeasurementCorrectionsCapabilities(subHalCapabilities);
}
@Override
public void setSubHalPowerIndicationCapabilities(int subHalCapabilities) {
mGnssLocationProvider.setSubHalPowerIndicationCapabilities(subHalCapabilities);
}
@Override
public void setGnssYearOfHardware(int yearOfHardware) {
mGnssLocationProvider.setGnssYearOfHardware(yearOfHardware);

View File

@@ -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();
@@ -178,6 +180,11 @@ class GnssNative {
mCallbacks.reportNavigationMessage(event);
}
@NativeEntryPoint
private void reportGnssPowerStats(GnssPowerStats powerStats) {
mCallbacks.reportGnssPowerStats(powerStats);
}
@NativeEntryPoint
private void setTopHalCapabilities(int topHalCapabilities) {
mCallbacks.setTopHalCapabilities(topHalCapabilities);
@@ -188,6 +195,11 @@ class GnssNative {
mCallbacks.setSubHalMeasurementCorrectionsCapabilities(subHalCapabilities);
}
@NativeEntryPoint
private void setSubHalPowerIndicationCapabilities(int subHalCapabilities) {
mCallbacks.setSubHalPowerIndicationCapabilities(subHalCapabilities);
}
@NativeEntryPoint
private void setGnssYearOfHardware(int yearOfHardware) {
mCallbacks.setGnssYearOfHardware(yearOfHardware);

View File

@@ -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();
}

View File

@@ -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());
}
}

View File

@@ -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))
@@ -933,6 +944,50 @@ Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback_V2_0::GnssSys
return Void();
}
/*
* 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",