/*
 * 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.location.LocationManager.GPS_PROVIDER;

import android.Manifest;
import android.annotation.Nullable;
import android.content.Context;
import android.location.GnssMeasurementCorrections;
import android.location.GnssRequest;
import android.location.IBatchedLocationCallback;
import android.location.IGnssAntennaInfoListener;
import android.location.IGnssMeasurementsListener;
import android.location.IGnssNavigationMessageListener;
import android.location.IGnssStatusListener;
import android.location.IGpsGeofenceHardware;
import android.location.INetInitiatedListener;
import android.location.Location;
import android.location.LocationManagerInternal;
import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Process;
import android.os.RemoteException;
import android.stats.location.LocationStatsEnums;
import android.util.ArrayMap;
import android.util.Log;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.location.AppForegroundHelper;
import com.android.server.location.AppOpsHelper;
import com.android.server.location.CallerIdentity;
import com.android.server.location.LocationManagerServiceUtils.LinkedListener;
import com.android.server.location.LocationManagerServiceUtils.LinkedListenerBase;
import com.android.server.location.LocationUsageLogger;
import com.android.server.location.RemoteListenerHelper;
import com.android.server.location.SettingsHelper;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;

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

    private static final String TAG = "GnssManagerService";

    public static boolean isGnssSupported() {
        return GnssLocationProvider.isSupported();
    }

    private final Context mContext;
    private final AppOpsHelper mAppOpsHelper;
    private final SettingsHelper mSettingsHelper;
    private final AppForegroundHelper mAppForegroundHelper;
    private final LocationUsageLogger mLocationUsageLogger;

    private final GnssLocationProvider mGnssLocationProvider;
    private final GnssStatusListenerHelper mGnssStatusProvider;
    private final GnssMeasurementsProvider mGnssMeasurementsProvider;
    private final GnssMeasurementCorrectionsProvider mGnssMeasurementCorrectionsProvider;
    private final GnssAntennaInfoProvider mGnssAntennaInfoProvider;
    private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
    private final GnssLocationProvider.GnssSystemInfoProvider mGnssSystemInfoProvider;
    private final GnssLocationProvider.GnssMetricsProvider mGnssMetricsProvider;
    private final GnssCapabilitiesProvider mGnssCapabilitiesProvider;
    private final GnssBatchingProvider mGnssBatchingProvider;
    private final INetInitiatedListener mNetInitiatedListener;
    private final IGpsGeofenceHardware mGpsGeofenceProxy;

    @GuardedBy("mGnssMeasurementsListeners")
    private final ArrayMap<IBinder, LinkedListener<GnssRequest, IGnssMeasurementsListener>>
            mGnssMeasurementsListeners = new ArrayMap<>();

    @GuardedBy("mGnssAntennaInfoListeners")
    private final ArrayMap<IBinder,
            LinkedListener<Void, IGnssAntennaInfoListener>>
            mGnssAntennaInfoListeners = new ArrayMap<>();

    @GuardedBy("mGnssNavigationMessageListeners")
    private final ArrayMap<IBinder, LinkedListener<Void, IGnssNavigationMessageListener>>
            mGnssNavigationMessageListeners = new ArrayMap<>();

    @GuardedBy("mGnssStatusListeners")
    private final ArrayMap<IBinder, LinkedListener<Void, IGnssStatusListener>>
            mGnssStatusListeners = new ArrayMap<>();

    @GuardedBy("this")
    @Nullable private LocationManagerInternal mLocationManagerInternal;

    private final Object mGnssBatchingLock = new Object();

    @GuardedBy("mGnssBatchingLock")
    @Nullable private IBatchedLocationCallback mGnssBatchingCallback;

    @GuardedBy("mGnssBatchingLock")
    @Nullable
    private LinkedListener<Void, IBatchedLocationCallback> mGnssBatchingDeathCallback;

    @GuardedBy("mGnssBatchingLock")
    private boolean mGnssBatchingInProgress = false;

    public GnssManagerService(Context context, AppOpsHelper appOpsHelper,
            SettingsHelper settingsHelper, AppForegroundHelper appForegroundHelper,
            LocationUsageLogger locationUsageLogger) {
        this(context, appOpsHelper, settingsHelper, appForegroundHelper, locationUsageLogger, null);
    }

    // Can use this constructor to inject GnssLocationProvider for testing
    @VisibleForTesting
    GnssManagerService(Context context, AppOpsHelper appOpsHelper, SettingsHelper settingsHelper,
            AppForegroundHelper appForegroundHelper, LocationUsageLogger locationUsageLogger,
            GnssLocationProvider gnssLocationProvider) {
        Preconditions.checkState(isGnssSupported());

        mContext = context;
        mAppOpsHelper = appOpsHelper;
        mSettingsHelper = settingsHelper;
        mAppForegroundHelper = appForegroundHelper;
        mLocationUsageLogger = locationUsageLogger;

        if (gnssLocationProvider == null) {
            gnssLocationProvider = new GnssLocationProvider(mContext);
        }

        mGnssLocationProvider = gnssLocationProvider;
        mGnssStatusProvider = mGnssLocationProvider.getGnssStatusProvider();
        mGnssMeasurementsProvider = mGnssLocationProvider.getGnssMeasurementsProvider();
        mGnssAntennaInfoProvider = mGnssLocationProvider.getGnssAntennaInfoProvider();
        mGnssMeasurementCorrectionsProvider =
                mGnssLocationProvider.getGnssMeasurementCorrectionsProvider();
        mGnssNavigationMessageProvider = mGnssLocationProvider.getGnssNavigationMessageProvider();
        mGnssSystemInfoProvider = mGnssLocationProvider.getGnssSystemInfoProvider();
        mGnssMetricsProvider = mGnssLocationProvider.getGnssMetricsProvider();
        mGnssCapabilitiesProvider = mGnssLocationProvider.getGnssCapabilitiesProvider();
        mGnssBatchingProvider = mGnssLocationProvider.getGnssBatchingProvider();
        mNetInitiatedListener = mGnssLocationProvider.getNetInitiatedListener();
        mGpsGeofenceProxy = mGnssLocationProvider.getGpsGeofenceProxy();
    }

    /** Called when system is ready. */
    public synchronized void onSystemReady() {
        if (mLocationManagerInternal != null) {
            return;
        }

        mAppOpsHelper.onSystemReady();
        mSettingsHelper.onSystemReady();
        mAppForegroundHelper.onSystemReady();

        mLocationManagerInternal = LocalServices.getService(LocationManagerInternal.class);

        mAppForegroundHelper.addListener(this::onAppForegroundChanged);
    }

    /** Retrieve the GnssLocationProvider. */
    public GnssLocationProvider getGnssLocationProvider() {
        return mGnssLocationProvider;
    }

    /** Retrieve the IGpsGeofenceHardware. */
    public IGpsGeofenceHardware getGpsGeofenceProxy() {
        return mGpsGeofenceProxy;
    }

    /**
     * Get year of GNSS hardware.
     */
    public int getGnssYearOfHardware() {
        return mGnssSystemInfoProvider.getGnssYearOfHardware();
    }

    /**
     * Get model name of GNSS hardware.
     */
    @Nullable
    public String getGnssHardwareModelName() {
        return mGnssSystemInfoProvider.getGnssHardwareModelName();
    }

    /**
     * Get GNSS hardware capabilities. The capabilities returned are a bitfield as described in
     * {@link android.location.GnssCapabilities}.
     */
    public long getGnssCapabilities() {
        return mGnssCapabilitiesProvider.getGnssCapabilities();
    }

    /**
     * Get size of GNSS batch (GNSS location results are batched together for power savings).
     */
    public int getGnssBatchSize(String packageName) {
        mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, null);
        mContext.enforceCallingPermission(Manifest.permission.ACCESS_FINE_LOCATION, null);

        synchronized (mGnssBatchingLock) {
            return mGnssBatchingProvider.getBatchSize();
        }
    }

    /**
     * Starts GNSS batch collection. GNSS positions are collected in a batch before being delivered
     * as a collection.
     */
    public boolean startGnssBatch(long periodNanos, boolean wakeOnFifoFull, String packageName,
            String featureId) {
        mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, null);
        mContext.enforceCallingPermission(Manifest.permission.ACCESS_FINE_LOCATION, null);

        CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, featureId);
        if (!mAppOpsHelper.checkLocationAccess(identity)) {
            return false;
        }

        synchronized (mGnssBatchingLock) {
            if (mGnssBatchingInProgress) {
                // Current design does not expect multiple starts to be called repeatedly
                Log.e(TAG, "startGnssBatch unexpectedly called w/o stopping prior batch");
                stopGnssBatch();
            }

            mGnssBatchingInProgress = true;
            return mGnssBatchingProvider.start(periodNanos, wakeOnFifoFull);
        }
    }

    /**
     * Adds a GNSS batching callback for delivering GNSS location batch results.
     */
    public boolean addGnssBatchingCallback(IBatchedLocationCallback callback, String packageName,
            @Nullable String featureId) {
        mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, null);
        mContext.enforceCallingPermission(Manifest.permission.ACCESS_FINE_LOCATION, null);

        CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, featureId);

        synchronized (mGnssBatchingLock) {
            mGnssBatchingCallback = callback;
            mGnssBatchingDeathCallback =
                    new LinkedListener<>(
                            /* request= */ null,
                            callback,
                            identity,
                            (IBatchedLocationCallback listener) -> {
                                stopGnssBatch();
                                removeGnssBatchingCallback();
                            });

            return mGnssBatchingDeathCallback.linkToListenerDeathNotificationLocked(
                    callback.asBinder());
        }
    }

    /**
     * Force flush GNSS location results from batch.
     *
     * @param packageName name of requesting package
     */
    public void flushGnssBatch(String packageName) {
        mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, null);
        mContext.enforceCallingPermission(Manifest.permission.ACCESS_FINE_LOCATION, null);

        synchronized (mGnssBatchingLock) {
            mGnssBatchingProvider.flush();
        }
    }

    /**
     * Removes GNSS batching callback.
     */
    public void removeGnssBatchingCallback() {
        mContext.enforceCallingPermission(android.Manifest.permission.LOCATION_HARDWARE, null);

        synchronized (mGnssBatchingLock) {
            mGnssBatchingDeathCallback.unlinkFromListenerDeathNotificationLocked(
                    mGnssBatchingCallback.asBinder());
            mGnssBatchingCallback = null;
            mGnssBatchingDeathCallback = null;
        }
    }

    /**
     * Stop GNSS batch collection.
     */
    public boolean stopGnssBatch() {
        mContext.enforceCallingPermission(android.Manifest.permission.LOCATION_HARDWARE, null);

        synchronized (mGnssBatchingLock) {
            mGnssBatchingInProgress = false;
            return mGnssBatchingProvider.stop();
        }
    }

    private void onAppForegroundChanged(int uid, boolean foreground) {
        synchronized (mGnssMeasurementsListeners) {
            updateListenersOnForegroundChangedLocked(
                    mGnssMeasurementsListeners,
                    mGnssMeasurementsProvider,
                    IGnssMeasurementsListener.Stub::asInterface,
                    uid,
                    foreground);
        }
        synchronized (mGnssNavigationMessageListeners) {
            updateListenersOnForegroundChangedLocked(
                    mGnssNavigationMessageListeners,
                    mGnssNavigationMessageProvider,
                    IGnssNavigationMessageListener.Stub::asInterface,
                    uid,
                    foreground);
        }
        synchronized (mGnssStatusListeners) {
            updateListenersOnForegroundChangedLocked(
                    mGnssStatusListeners,
                    mGnssStatusProvider,
                    IGnssStatusListener.Stub::asInterface,
                    uid,
                    foreground);
        }
        synchronized (mGnssAntennaInfoListeners) {
            updateListenersOnForegroundChangedLocked(
                    mGnssAntennaInfoListeners,
                    mGnssAntennaInfoProvider,
                    IGnssAntennaInfoListener.Stub::asInterface,
                    uid,
                    foreground);
        }
    }

    private <TRequest, TListener extends IInterface> void updateListenersOnForegroundChangedLocked(
            Map<IBinder, LinkedListener<TRequest, TListener>> gnssDataListeners,
            RemoteListenerHelper<TRequest, TListener> gnssDataProvider,
            Function<IBinder, TListener> mapBinderToListener,
            int uid,
            boolean foreground) {
        for (Map.Entry<IBinder, LinkedListener<TRequest, TListener>> entry :
                gnssDataListeners.entrySet()) {
            LinkedListener<TRequest, TListener> linkedListener = entry.getValue();
            CallerIdentity callerIdentity = linkedListener.getCallerIdentity();
            TRequest request = linkedListener.getRequest();
            if (callerIdentity.uid != uid) {
                continue;
            }

            TListener listener = mapBinderToListener.apply(entry.getKey());
            if (foreground || isThrottlingExempt(callerIdentity)) {
                gnssDataProvider.addListener(request, listener, callerIdentity);
            } else {
                gnssDataProvider.removeListener(listener);
            }
        }
    }

    private <TListener extends IInterface, TRequest> boolean addGnssDataListenerLocked(
            @Nullable TRequest request,
            TListener listener,
            String packageName,
            @Nullable String featureId,
            RemoteListenerHelper<TRequest, TListener> gnssDataProvider,
            ArrayMap<IBinder,
                    LinkedListener<TRequest, TListener>> gnssDataListeners,
            Consumer<TListener> binderDeathCallback) {
        mContext.enforceCallingPermission(Manifest.permission.ACCESS_FINE_LOCATION, null);

        CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, featureId);
        if (!mAppOpsHelper.checkLocationAccess(identity)) {
            return false;
        }

        LinkedListener<TRequest, TListener> linkedListener = new LinkedListener<>(request, listener,
                identity, binderDeathCallback);
        IBinder binder = listener.asBinder();
        if (!linkedListener.linkToListenerDeathNotificationLocked(binder)) {
            return false;
        }

        gnssDataListeners.put(binder, linkedListener);
        if (gnssDataProvider == mGnssMeasurementsProvider
                || gnssDataProvider == mGnssStatusProvider) {
            mLocationUsageLogger.logLocationApiUsage(
                    LocationStatsEnums.USAGE_STARTED,
                    gnssDataProvider == mGnssMeasurementsProvider
                            ? LocationStatsEnums.API_ADD_GNSS_MEASUREMENTS_LISTENER
                            : LocationStatsEnums.API_REGISTER_GNSS_STATUS_CALLBACK,
                    packageName,
                    /* LocationRequest= */ null,
                    /* hasListener= */ true,
                    /* hasIntent= */ false,
                    /* geofence= */ null,
                    mAppForegroundHelper.getImportance(identity.uid));
        }
        if (mAppForegroundHelper.isAppForeground(identity.uid)
                || isThrottlingExempt(identity)) {
            gnssDataProvider.addListener(request, listener, identity);
        }
        return true;
    }

    private <TRequest, TListener extends IInterface> void removeGnssDataListenerLocked(
            TListener listener,
            RemoteListenerHelper<TRequest, TListener> gnssDataProvider,
            ArrayMap<IBinder, LinkedListener<TRequest, TListener>> gnssDataListeners) {
        if (gnssDataProvider == null) {
            Log.e(
                    TAG,
                    "Can not remove GNSS data listener. GNSS data provider "
                            + "not available.");
            return;
        }

        IBinder binder = listener.asBinder();
        LinkedListener<TRequest, TListener> linkedListener =
                gnssDataListeners.remove(binder);
        if (linkedListener == null) {
            return;
        }
        if (gnssDataProvider == mGnssMeasurementsProvider
                || gnssDataProvider == mGnssStatusProvider) {
            mLocationUsageLogger.logLocationApiUsage(
                    LocationStatsEnums.USAGE_ENDED,
                    gnssDataProvider == mGnssMeasurementsProvider
                            ? LocationStatsEnums.API_ADD_GNSS_MEASUREMENTS_LISTENER
                            : LocationStatsEnums.API_REGISTER_GNSS_STATUS_CALLBACK,
                    linkedListener.getCallerIdentity().packageName,
                    /* LocationRequest= */ null,
                    /* hasListener= */ true,
                    /* hasIntent= */ false,
                    /* geofence= */ null,
                    mAppForegroundHelper.getImportance(Binder.getCallingUid()));
        }
        linkedListener.unlinkFromListenerDeathNotificationLocked(binder);
        gnssDataProvider.removeListener(listener);
    }

    /**
     * Registers listener for GNSS status changes.
     */
    public boolean registerGnssStatusCallback(IGnssStatusListener listener, String packageName,
            @Nullable String featureId) {
        synchronized (mGnssStatusListeners) {
            return addGnssDataListenerLocked(
                    /* request= */ null,
                    listener,
                    packageName,
                    featureId,
                    mGnssStatusProvider,
                    mGnssStatusListeners,
                    this::unregisterGnssStatusCallback);
        }
    }

    /**
     * Unregisters listener for GNSS status changes.
     */
    public void unregisterGnssStatusCallback(IGnssStatusListener listener) {
        synchronized (mGnssStatusListeners) {
            removeGnssDataListenerLocked(listener, mGnssStatusProvider, mGnssStatusListeners);
        }
    }

    /**
     * Adds a GNSS measurements listener.
     */
    public boolean addGnssMeasurementsListener(@Nullable GnssRequest request,
            IGnssMeasurementsListener listener, String packageName,
            @Nullable String featureId) {
        if (request != null && request.isFullTracking()) {
            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.LOCATION_HARDWARE,
                    null);
        }
        synchronized (mGnssMeasurementsListeners) {
            return addGnssDataListenerLocked(
                    request,
                    listener,
                    packageName,
                    featureId,
                    mGnssMeasurementsProvider,
                    mGnssMeasurementsListeners,
                    this::removeGnssMeasurementsListener);
        }
    }

    /**
     * Injects GNSS measurement corrections.
     */
    public void injectGnssMeasurementCorrections(
            GnssMeasurementCorrections measurementCorrections, String packageName) {
        mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE, null);
        mContext.enforceCallingPermission(Manifest.permission.ACCESS_FINE_LOCATION, null);

        mGnssMeasurementCorrectionsProvider.injectGnssMeasurementCorrections(
                measurementCorrections);
    }

    /**
     * Removes a GNSS measurements listener.
     */
    public void removeGnssMeasurementsListener(IGnssMeasurementsListener listener) {
        synchronized (mGnssMeasurementsListeners) {
            removeGnssDataListenerLocked(listener, mGnssMeasurementsProvider,
                    mGnssMeasurementsListeners);
        }
    }

    /**
     * Adds a GNSS Antenna Info listener.
     *
     * @param listener    called when GNSS antenna info is received
     * @param packageName name of requesting package
     */
    public boolean addGnssAntennaInfoListener(
            IGnssAntennaInfoListener listener, String packageName,
            @Nullable String featureId) {
        synchronized (mGnssAntennaInfoListeners) {
            return addGnssDataListenerLocked(
                    /* request= */ null,
                    listener,
                    packageName,
                    featureId,
                    mGnssAntennaInfoProvider,
                    mGnssAntennaInfoListeners,
                    this::removeGnssAntennaInfoListener);
        }
    }

    /**
     * Removes a GNSS Antenna Info listener.
     *
     * @param listener called when GNSS antenna info is received
     */
    public void removeGnssAntennaInfoListener(IGnssAntennaInfoListener listener) {
        synchronized (mGnssAntennaInfoListeners) {
            removeGnssDataListenerLocked(
                    listener, mGnssAntennaInfoProvider, mGnssAntennaInfoListeners);
        }
    }

    /**
     * Adds a GNSS navigation message listener.
     */
    public boolean addGnssNavigationMessageListener(
            IGnssNavigationMessageListener listener, String packageName,
            @Nullable String featureId) {
        synchronized (mGnssNavigationMessageListeners) {
            return addGnssDataListenerLocked(
                    /* request= */ null,
                    listener,
                    packageName,
                    featureId,
                    mGnssNavigationMessageProvider,
                    mGnssNavigationMessageListeners,
                    this::removeGnssNavigationMessageListener);
        }
    }

    /**
     * Removes a GNSS navigation message listener.
     */
    public void removeGnssNavigationMessageListener(IGnssNavigationMessageListener listener) {
        synchronized (mGnssNavigationMessageListeners) {
            removeGnssDataListenerLocked(
                    listener, mGnssNavigationMessageProvider, mGnssNavigationMessageListeners);
        }
    }

    /**
     * Send Ni Response, indicating a location request initiated by a network carrier.
     */
    public void sendNiResponse(int notifId, int userResponse) {
        try {
            mNetInitiatedListener.sendNiResponse(notifId, userResponse);
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException in LocationManagerService.sendNiResponse");
        }
    }

    /**
     * Report location results to GNSS batching listener.
     */
    public void onReportLocation(List<Location> locations) {
        IBatchedLocationCallback gnssBatchingCallback;
        LinkedListener<Void, IBatchedLocationCallback> gnssBatchingDeathCallback;
        synchronized (mGnssBatchingLock) {
            gnssBatchingCallback = mGnssBatchingCallback;
            gnssBatchingDeathCallback = mGnssBatchingDeathCallback;
        }

        if (gnssBatchingCallback == null || gnssBatchingDeathCallback == null) {
            return;
        }

        int userId = gnssBatchingDeathCallback.getCallerIdentity().userId;
        if (!mLocationManagerInternal.isProviderEnabledForUser(GPS_PROVIDER, userId)) {
            Log.w(TAG, "reportLocationBatch() called without user permission");
            return;
        }

        try {
            gnssBatchingCallback.onLocationBatch(locations);
        } catch (RemoteException e) {
            Log.e(TAG, "reportLocationBatch() failed", e);
        }
    }

    private boolean isThrottlingExempt(CallerIdentity callerIdentity) {
        if (callerIdentity.uid == Process.SYSTEM_UID) {
            return true;
        }

        if (mSettingsHelper.getBackgroundThrottlePackageWhitelist().contains(
                callerIdentity.packageName)) {
            return true;
        }

        synchronized (this) {
            Preconditions.checkState(mLocationManagerInternal != null);
        }
        return mLocationManagerInternal.isProviderPackage(callerIdentity.packageName);
    }

    /**
     * Dump info for debugging.
     */
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");

        if (args.length > 0 && args[0].equals("--gnssmetrics")) {
            if (mGnssMetricsProvider != null) {
                pw.append(mGnssMetricsProvider.getGnssMetricsAsProtoString());
            }
            return;
        }

        ipw.println("GnssMeasurement Listeners:");
        ipw.increaseIndent();
        synchronized (mGnssMeasurementsListeners) {
            for (LinkedListenerBase listener : mGnssMeasurementsListeners.values()) {
                ipw.println(listener);
            }
        }
        ipw.decreaseIndent();

        ipw.println("GnssNavigationMessage Listeners:");
        ipw.increaseIndent();
        synchronized (mGnssNavigationMessageListeners) {
            for (LinkedListenerBase listener : mGnssNavigationMessageListeners.values()) {
                ipw.println(listener);
            }
        }
        ipw.decreaseIndent();

        ipw.println("GnssStatus Listeners:");
        ipw.increaseIndent();
        synchronized (mGnssStatusListeners) {
            for (LinkedListenerBase listener : mGnssStatusListeners.values()) {
                ipw.println(listener);
            }
        }
        ipw.decreaseIndent();

        synchronized (mGnssBatchingLock) {
            if (mGnssBatchingInProgress) {
                ipw.println("GNSS batching in progress");
            }
        }
    }
}
