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

Commit f9422cc2 authored by Shinru Han's avatar Shinru Han
Browse files

Add GnssAssistance JNI.

Test: atest FrameworksMockingServicesTests_location
Bug: 358381377
Flag: android.location.flags.gnss_assistance_interface_jni
Change-Id: Ifae3e1f0630841254af46a169674a9adc7da2ce0
parent b16925e3
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -186,3 +186,11 @@ flag {
    bug: "398254728"
    is_fixed_read_only: true
}

flag {
    name: "gnss_assistance_interface_jni"
    namespace: "location"
    description: "Flag for GNSS assistance interface JNI"
    bug: "209078566"
}
+40 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.hardware.location.GeofenceHardware;
import android.hardware.location.GeofenceHardwareImpl;
import android.location.FusedBatchOptions;
import android.location.GnssAntennaInfo;
import android.location.GnssAssistance;
import android.location.GnssCapabilities;
import android.location.GnssMeasurementCorrections;
import android.location.GnssMeasurementRequest;
@@ -35,6 +36,8 @@ import android.location.IGnssStatusListener;
import android.location.IGpsGeofenceHardware;
import android.location.Location;
import android.location.LocationManager;
import android.location.flags.Flags;
import android.location.provider.IGnssAssistanceCallback;
import android.location.util.identity.CallerIdentity;
import android.os.BatteryStats;
import android.os.Binder;
@@ -47,12 +50,13 @@ import com.android.internal.app.IBatteryStats;
import com.android.server.FgThread;
import com.android.server.location.gnss.hal.GnssNative;
import com.android.server.location.injector.Injector;
import com.android.server.location.provider.proxy.ProxyGnssAssistanceProvider;

import java.io.FileDescriptor;
import java.util.List;

/** Manages Gnss providers and related Gnss functions for LocationManagerService. */
public class GnssManagerService {
public class GnssManagerService implements GnssNative.GnssAssistanceCallbacks {

    public static final String TAG = "GnssManager";
    public static final boolean D = Log.isLoggable(TAG, Log.DEBUG);
@@ -75,6 +79,8 @@ public class GnssManagerService {

    private final GnssMetrics mGnssMetrics;

    private @Nullable ProxyGnssAssistanceProvider mProxyGnssAssistanceProvider = null;

    public GnssManagerService(Context context, Injector injector, GnssNative gnssNative) {
        mContext = context.createAttributionContext(ATTRIBUTION_ID);
        mGnssNative = gnssNative;
@@ -100,6 +106,16 @@ public class GnssManagerService {
    /** Called when system is ready. */
    public void onSystemReady() {
        mGnssLocationProvider.onSystemReady();

        if (Flags.gnssAssistanceInterfaceJni()) {
            mProxyGnssAssistanceProvider =
                    ProxyGnssAssistanceProvider.createAndRegister(mContext);
            if (mProxyGnssAssistanceProvider == null) {
                Log.e(TAG, "no gnss assistance provider found");
            } else {
                mGnssNative.setGnssAssistanceCallbacks(this);
            }
        }
    }

    /** Retrieve the GnssLocationProvider. */
@@ -323,6 +339,29 @@ public class GnssManagerService {
        }
    }

    @Override
    public void onRequestGnssAssistanceInject() {
        if (!Flags.gnssAssistanceInterfaceJni()) {
            return;
        }
        if (mProxyGnssAssistanceProvider == null) {
            Log.e(TAG, "ProxyGnssAssistanceProvider is null");
            return;
        }
        mProxyGnssAssistanceProvider.request(new IGnssAssistanceCallback.Stub() {
            @Override
            public void onError() {
                Log.e(TAG, "GnssAssistanceCallback.onError");
            }

            @Override
            public void onResult(GnssAssistance gnssAssistance) {
                Log.d(TAG, "GnssAssistanceCallback.onResult");
                mGnssNative.injectGnssAssistance(gnssAssistance);
            }
        });
    }

    private class GnssCapabilitiesHalModule implements GnssNative.BaseCallbacks {

        GnssCapabilitiesHalModule(GnssNative gnssNative) {
+46 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.location.GnssAntennaInfo;
import android.location.GnssAssistance;
import android.location.GnssCapabilities;
import android.location.GnssMeasurementCorrections;
import android.location.GnssMeasurementsEvent;
@@ -30,6 +31,7 @@ import android.location.GnssNavigationMessage;
import android.location.GnssSignalType;
import android.location.GnssStatus;
import android.location.Location;
import android.location.flags.Flags;
import android.os.Binder;
import android.os.Handler;
import android.os.SystemClock;
@@ -275,6 +277,12 @@ public class GnssNative {
        void onRequestPsdsDownload(int psdsType);
    }

    /** Callbacks for HAL requesting GNSS assistance. */
    public interface GnssAssistanceCallbacks {
        /** On request GnssAssistance injection. */
        void onRequestGnssAssistanceInject();
    }

    /** Callbacks for AGPS functionality. */
    public interface AGpsCallbacks {

@@ -400,6 +408,7 @@ public class GnssNative {
    private TimeCallbacks mTimeCallbacks;
    private LocationRequestCallbacks mLocationRequestCallbacks;
    private PsdsCallbacks mPsdsCallbacks;
    private @Nullable GnssAssistanceCallbacks mGnssAssistanceCallbacks;
    private AGpsCallbacks mAGpsCallbacks;
    private NotificationCallbacks mNotificationCallbacks;

@@ -504,6 +513,16 @@ public class GnssNative {
        mNotificationCallbacks = Objects.requireNonNull(callbacks);
    }

    /** Sets GnssAssistanceCallbacks. */
    public void setGnssAssistanceCallbacks(GnssAssistanceCallbacks callbacks) {
        if (!Flags.gnssAssistanceInterfaceJni()) {
            return;
        }
        Preconditions.checkState(!mRegistered);
        Preconditions.checkState(mGnssAssistanceCallbacks == null);
        mGnssAssistanceCallbacks = Objects.requireNonNull(callbacks);
    }

    /**
     * Registers with the HAL and allows callbacks to begin. Once registered with the native HAL,
     * no more callbacks can be added or set. Must only be called once.
@@ -1053,6 +1072,17 @@ public class GnssNative {
        mGnssHal.injectNiSuplMessageData(data, length, slotIndex);
    }

    /**
     * Injects GNSS assistance data into the GNSS HAL.
     */
    public void injectGnssAssistance(GnssAssistance assistance) {
        if (!Flags.gnssAssistanceInterfaceJni()) {
            return;
        }
        Preconditions.checkState(mRegistered);
        mGnssHal.injectGnssAssistance(assistance);
    }

    @NativeEntryPoint
    void reportGnssServiceDied() {
        // Not necessary to clear (and restore) binder identity since it runs on another thread.
@@ -1268,6 +1298,15 @@ public class GnssNative {
        Binder.withCleanCallingIdentity(() -> mPsdsCallbacks.onRequestPsdsDownload(psdsType));
    }

    @NativeEntryPoint
    void gnssAssistanceInjectRequest() {
        if (!Flags.gnssAssistanceInterfaceJni() || mGnssAssistanceCallbacks == null) {
            return;
        }
        Binder.withCleanCallingIdentity(
                () -> mGnssAssistanceCallbacks.onRequestGnssAssistanceInject());
    }

    @NativeEntryPoint
    void reportGeofenceTransition(int geofenceId, Location location, int transition,
            long transitionTimestamp) {
@@ -1569,6 +1608,10 @@ public class GnssNative {
        protected void injectNiSuplMessageData(byte[] data, int length, int slotIndex) {
            native_inject_ni_supl_message_data(data, length, slotIndex);
        }

        protected void injectGnssAssistance(GnssAssistance gnssAssistance) {
            native_inject_gnss_assistance(gnssAssistance);
        }
    }

    // basic APIs
@@ -1718,4 +1761,7 @@ public class GnssNative {
    private static native boolean native_supports_psds();

    private static native void native_inject_psds_data(byte[] data, int length, int psdsType);

    // GNSS Assistance APIs
    private static native void native_inject_gnss_assistance(GnssAssistance gnssAssistance);
}
+2 −1
Original line number Diff line number Diff line
@@ -169,7 +169,7 @@ cc_defaults {
        "android.hardware.broadcastradio@1.1",
        "android.hardware.contexthub@1.0",
        "android.hardware.common.fmq-V1-ndk",
        "android.hardware.gnss-V3-cpp",
        "android.hardware.gnss-V5-cpp",
        "android.hardware.gnss@1.0",
        "android.hardware.gnss@1.1",
        "android.hardware.gnss@2.0",
@@ -204,6 +204,7 @@ cc_defaults {
        "android.system.suspend.control-V1-cpp",
        "android.system.suspend.control.internal-cpp",
        "android.system.suspend-V1-ndk",
        "android_location_flags_c_lib",
        "server_configurable_flags",
        "service.incremental",
    ],
+34 −2
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include <android/hardware/gnss/BnGnssMeasurementCallback.h>
#include <android/hardware/gnss/BnGnssPowerIndicationCallback.h>
#include <android/hardware/gnss/BnGnssPsdsCallback.h>
#include <android_location_flags.h>
#include <binder/IServiceManager.h>
#include <nativehelper/JNIHelp.h>
#include <pthread.h>
@@ -53,6 +54,8 @@
#include "gnss/Gnss.h"
#include "gnss/GnssAntennaInfo.h"
#include "gnss/GnssAntennaInfoCallback.h"
#include "gnss/GnssAssistance.h"
#include "gnss/GnssAssistanceCallback.h"
#include "gnss/GnssBatching.h"
#include "gnss/GnssConfiguration.h"
#include "gnss/GnssDebug.h"
@@ -114,6 +117,7 @@ using android::hardware::gnss::GnssConstellationType;
using android::hardware::gnss::GnssPowerStats;
using android::hardware::gnss::IGnssPowerIndication;
using android::hardware::gnss::IGnssPowerIndicationCallback;
using android::hardware::gnss::gnss_assistance::IGnssAssistanceCallback;

using IGnssAidl = android::hardware::gnss::IGnss;
using IGnssBatchingAidl = android::hardware::gnss::IGnssBatching;
@@ -140,6 +144,9 @@ std::unique_ptr<android::gnss::GnssPsdsInterface> gnssPsdsIface = nullptr;
std::unique_ptr<android::gnss::GnssVisibilityControlInterface> gnssVisibilityControlIface = nullptr;
std::unique_ptr<android::gnss::MeasurementCorrectionsInterface> gnssMeasurementCorrectionsIface =
        nullptr;
std::unique_ptr<android::gnss::GnssAssistanceInterface> gnssAssistanceIface = nullptr;

namespace location_flags = android::location::flags;

namespace android {

@@ -229,6 +236,9 @@ static void android_location_gnss_hal_GnssNative_class_init_once(JNIEnv* env, jc
    gnss::GnssVisibilityControl_class_init_once(env, clazz);
    gnss::MeasurementCorrections_class_init_once(env, clazz);
    gnss::MeasurementCorrectionsCallback_class_init_once(env, clazz);
    if (location_flags::gnss_assistance_interface_jni()) {
        gnss::GnssAssistance_class_init_once(env, clazz);
    }
    gnss::Utils_class_init_once(env);
}

@@ -266,7 +276,9 @@ static void android_location_gnss_hal_GnssNative_init_once(JNIEnv* env, jobject
    gnssBatchingIface = gnssHal->getGnssBatchingInterface();
    gnssVisibilityControlIface = gnssHal->getGnssVisibilityControlInterface();
    gnssPowerIndicationIface = gnssHal->getGnssPowerIndicationInterface();

    if (location_flags::gnss_assistance_interface_jni()) {
        gnssAssistanceIface = gnssHal->getGnssAssistanceInterface();
    }
    if (mCallbacksObj) {
        ALOGE("Callbacks already initialized");
    } else {
@@ -355,13 +367,22 @@ static jboolean android_location_gnss_hal_GnssNative_init(JNIEnv* /* env */, jcl
    // Set IGnssPowerIndication.hal callback.
    if (gnssPowerIndicationIface != nullptr) {
        sp<IGnssPowerIndicationCallback> gnssPowerIndicationCallback =
                new GnssPowerIndicationCallback();
                sp<GnssPowerIndicationCallback>::make();
        auto status = gnssPowerIndicationIface->setCallback(gnssPowerIndicationCallback);
        if (!checkAidlStatus(status, "IGnssPowerIndication setCallback() failed.")) {
            gnssPowerIndicationIface = nullptr;
        }
    }

    // Set IGnssAssistance callback.
    if (gnssAssistanceIface != nullptr) {
        sp<IGnssAssistanceCallback> gnssAssistanceCallback =
                sp<gnss::GnssAssistanceCallback>::make();
        if (!gnssAssistanceIface->setCallback(gnssAssistanceCallback)) {
            ALOGI("IGnssAssistanceInterface setCallback() failed");
        }
    }

    return JNI_TRUE;
}

@@ -493,6 +514,15 @@ static void android_location_gnss_hal_GnssNative_inject_psds_data(JNIEnv* env, j
    gnssPsdsIface->injectPsdsData(data, length, psdsType);
}

static void android_location_gnss_hal_GnssNative_inject_gnss_assistance(JNIEnv* env, jclass,
                                                                        jobject gnssAssistanceObj) {
    if (gnssAssistanceIface == nullptr) {
        ALOGE("%s: IGnssAssistance interface not available.", __func__);
        return;
    }
    gnssAssistanceIface->injectGnssAssistance(env, gnssAssistanceObj);
}

static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open(
        JNIEnv* env, jobject /* obj */, jlong networkHandle, jstring apn, jint apnIpType) {
    if (apn == nullptr) {
@@ -937,6 +967,8 @@ static const JNINativeMethod sLocationProviderMethods[] = {
        {"native_stop_nmea_message_collection", "()Z",
         reinterpret_cast<void*>(
                 android_location_gnss_hal_GnssNative_stop_nmea_message_collection)},
        {"native_inject_gnss_assistance", "(Landroid/location/GnssAssistance;)V",
         reinterpret_cast<void*>(android_location_gnss_hal_GnssNative_inject_gnss_assistance)},
};

static const JNINativeMethod sBatchingMethods[] = {
Loading