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

Commit d73c0299 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "GNSS HAL & VTS for Duty Cycling & Low Power APIs."

parents a76deb57 f0b07077
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ hidl_interface {
    srcs: [
        "IGnss.hal",
        "IGnssCallback.hal",
        "IGnssMeasurement.hal",
    ],
    interfaces: [
        "android.hardware.gnss@1.0",
+41 −2
Original line number Diff line number Diff line
@@ -18,17 +18,56 @@ package android.hardware.gnss@1.1;

import @1.0::IGnss;

import IGnssMeasurement;
import IGnssCallback;

/** Represents the standard GNSS (Global Navigation Satellite System) interface. */
interface IGnss extends @1.0::IGnss {
    /**
     * Opens the interface and provides the callback routines
     * to the implementation of this interface.
     * Opens the interface and provides the callback routines to the implementation of this
     * interface.
     *
     * @param callback Callback interface for IGnss.
     *
     * @return success Returns true on success.
     */
    setCallback_1_1(IGnssCallback callback) generates (bool success);

    /**
     * Sets the GnssPositionMode parameter, its associated recurrence value,
     * the time between fixes, requested fix accuracy, time to first fix.
     *
     * @param mode Parameter must be one of MS_BASED or STANDALONE. It is allowed by the platform
     *     (and it is recommended) to fallback to MS_BASED if MS_ASSISTED is passed in, and MS_BASED
     *     is supported.
     * @param recurrence GNSS postion recurrence value, either periodic or single.
     * @param minIntervalMs Represents the time between fixes in milliseconds.
     * @param preferredAccuracyMeters Represents the requested fix accuracy in meters.
     * @param preferredTimeMs Represents the requested time to first fix in milliseconds.
     * @param lowPowerMode When true, HAL must make strong tradeoffs to substantially restrict power
     *     use. Specifically, in the case of a several second long minIntervalMs, the GNSS chipset
     *     must not, on average, run power hungry operations like RF and signal searches for more
     *     than one second per interval, and must make exactly one call to gnssSvStatusCb(), and
     *     either zero or one call to GnssLocationCb() at each interval. When false, HAL must
     *     operate in the nominal mode (similar to V1.0 where this flag wasn't present) and is
     *     expected to make power and performance tradoffs such as duty-cycling when signal
     *     conditions are good and more active searches to reacquire GNSS signals when no signals
     *     are present.
     *
     * @return success Returns true if successful.
     */
    setPositionMode_1_1(GnssPositionMode mode,
                        GnssPositionRecurrence recurrence,
                        uint32_t minIntervalMs,
                        uint32_t preferredAccuracyMeters,
                        uint32_t preferredTimeMs,
                        bool lowPowerMode)
             generates (bool success);

   /**
    * This method returns the IGnssMeasurement interface.
    *
    * @return gnssMeasurementIface Handle to the IGnssMeasurement interface.
    */
    getExtensionGnssMeasurement_1_1() generates (IGnssMeasurement gnssMeasurementIface);
};
 No newline at end of file
+49 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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 android.hardware.gnss@1.1;

import @1.0::IGnssMeasurement;
import @1.0::IGnssMeasurementCallback;

/**
 * Extended interface for GNSS Measurements support.
 */
interface IGnssMeasurement extends @1.0::IGnssMeasurement {

    /**
     * Initializes the interface and registers the callback routines with the HAL. After a
     * successful call to 'setCallback_1_1' the HAL must begin to provide updates at an average
     * output rate of 1Hz (occasional intra-measurement time offsets in the range from 0-2000msec
     * can be tolerated.)
     *
     * @param callback Handle to GnssMeasurement callback interface.
     * @param enableFullTracking If true, GNSS chipset must switch off duty cycling. In such mode
     *     no clock discontinuities are expected and, when supported, carrier phase should be
     *     continuous in good signal conditions. All constellations and frequency bands that the
     *     chipset supports must be reported in this mode. The GNSS chipset is allowed to consume
     *     more power in this mode. If false, API must behave as in HAL V1_0, optimizing power via
     *     duty cycling, constellations and frequency limits, etc.
     *
     * @return initRet Returns SUCCESS if successful. Returns ERROR_ALREADY_INIT if a callback has
     *     already been registered without a corresponding call to 'close'. Returns ERROR_GENERIC
     *     for any other error. The HAL must not generate any other updates upon returning this
     *     error code.
     */
    setCallback_1_1(IGnssMeasurementCallback callback, bool enableFullTracking)
         generates (GnssMeasurementStatus initRet);

};
+23 −4
Original line number Diff line number Diff line
@@ -22,7 +22,12 @@
#include <chrono>

// Implementations for the main test class for GNSS HAL
GnssHalTest::GnssHalTest() : info_called_count_(0), name_called_count_(0), notify_count_(0) {}
GnssHalTest::GnssHalTest()
    : info_called_count_(0),
      capabilities_called_count_(0),
      location_called_count_(0),
      name_called_count_(0),
      notify_count_(0) {}

void GnssHalTest::SetUp() {
    gnss_hal_ = ::testing::VtsHalHidlTargetTestBase::getService<IGnss>();
@@ -56,7 +61,6 @@ std::cv_status GnssHalTest::wait(int timeoutSeconds) {
    return status;
}

// Actual (test) callback handlers
Return<void> GnssHalTest::GnssCallback::gnssSetSystemInfoCb(
    const IGnssCallback::GnssSystemInfo& info) {
    ALOGI("Info received, year %d", info.yearOfHw);
@@ -66,7 +70,14 @@ Return<void> GnssHalTest::GnssCallback::gnssSetSystemInfoCb(
    return Void();
}

// Actual (test) callback handlers
Return<void> GnssHalTest::GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
    ALOGI("Capabilities received %d", capabilities);
    parent_.capabilities_called_count_++;
    parent_.last_capabilities_ = capabilities;
    parent_.notify();
    return Void();
}

Return<void> GnssHalTest::GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
    ALOGI("Name received: %s", name.c_str());
    parent_.name_called_count_++;
@@ -74,3 +85,11 @@ Return<void> GnssHalTest::GnssCallback::gnssNameCb(const android::hardware::hidl
    parent_.notify();
    return Void();
}

Return<void> GnssHalTest::GnssCallback::gnssLocationCb(const GnssLocation& location) {
    ALOGI("Location received");
    parent_.location_called_count_++;
    parent_.last_location_ = location;
    parent_.notify();
    return Void();
}
+129 −3
Original line number Diff line number Diff line
@@ -31,8 +31,9 @@ using android::hardware::gnss::V1_0::GnssLocation;

using android::hardware::gnss::V1_1::IGnss;
using android::hardware::gnss::V1_1::IGnssCallback;

using android::hardware::gnss::V1_0::GnssLocationFlags;
using android::sp;
#define TIMEOUT_SEC 2  // for basic commands/responses

// The main test class for GNSS HAL.
class GnssHalTest : public ::testing::VtsHalHidlTargetTestBase {
@@ -72,13 +73,134 @@ class GnssHalTest : public ::testing::VtsHalHidlTargetTestBase {
        Return<void> gnssAcquireWakelockCb() override { return Void(); }
        Return<void> gnssReleaseWakelockCb() override { return Void(); }
        Return<void> gnssRequestTimeCb() override { return Void(); }
        Return<void> gnssLocationCb(const GnssLocation& /* location */) override { return Void(); }
        Return<void> gnssSetCapabilitesCb(uint32_t /* capabilities */) override { return Void(); }
        // Actual (test) callback handlers
        Return<void> gnssLocationCb(const GnssLocation& location) override;
        Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
        Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
        Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
    };

    /*
     * StartAndGetSingleLocation:
     * Helper function to get one Location and check fields
     *
     * returns  true if a location was successfully generated
     */
    bool StartAndGetSingleLocation(bool checkAccuracies) {
        auto result = gnss_hal_->start();

        EXPECT_TRUE(result.isOk());
        EXPECT_TRUE(result);

        /*
         * GPS signals initially optional for this test, so don't expect fast fix,
         * or no timeout, unless signal is present
         */
        int firstGnssLocationTimeoutSeconds = 15;

        wait(firstGnssLocationTimeoutSeconds);
        EXPECT_EQ(location_called_count_, 1);

        if (location_called_count_ > 0) {
            // don't require speed on first fix
            CheckLocation(last_location_, checkAccuracies, false);
            return true;
        }
        return false;
    }

    /*
     * CheckLocation:
     *   Helper function to vet Location fields when calling setPositionMode_1_1()
     */
    void CheckLocation(GnssLocation& location, bool checkAccuracies, bool checkSpeed) {
        EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
        EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
        if (checkSpeed) {
            EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED);
        }
        EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY);
        // New uncertainties available in O must be provided,
        // at least when paired with modern hardware (2017+)
        if (checkAccuracies) {
            EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY);
            if (checkSpeed) {
                EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY);
                if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
                    EXPECT_TRUE(location.gnssLocationFlags &
                                GnssLocationFlags::HAS_BEARING_ACCURACY);
                }
            }
        }
        EXPECT_GE(location.latitudeDegrees, -90.0);
        EXPECT_LE(location.latitudeDegrees, 90.0);
        EXPECT_GE(location.longitudeDegrees, -180.0);
        EXPECT_LE(location.longitudeDegrees, 180.0);
        EXPECT_GE(location.altitudeMeters, -1000.0);
        EXPECT_LE(location.altitudeMeters, 30000.0);
        if (checkSpeed) {
            EXPECT_GE(location.speedMetersPerSec, 0.0);
            EXPECT_LE(location.speedMetersPerSec, 5.0);  // VTS tests are stationary.

            // Non-zero speeds must be reported with an associated bearing
            if (location.speedMetersPerSec > 0.0) {
                EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING);
            }
        }

        /*
         * Tolerating some especially high values for accuracy estimate, in case of
         * first fix with especially poor geometry (happens occasionally)
         */
        EXPECT_GT(location.horizontalAccuracyMeters, 0.0);
        EXPECT_LE(location.horizontalAccuracyMeters, 250.0);

        /*
         * Some devices may define bearing as -180 to +180, others as 0 to 360.
         * Both are okay & understandable.
         */
        if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
            EXPECT_GE(location.bearingDegrees, -180.0);
            EXPECT_LE(location.bearingDegrees, 360.0);
        }
        if (location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
            EXPECT_GT(location.verticalAccuracyMeters, 0.0);
            EXPECT_LE(location.verticalAccuracyMeters, 500.0);
        }
        if (location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
            EXPECT_GT(location.speedAccuracyMetersPerSecond, 0.0);
            EXPECT_LE(location.speedAccuracyMetersPerSecond, 50.0);
        }
        if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
            EXPECT_GT(location.bearingAccuracyDegrees, 0.0);
            EXPECT_LE(location.bearingAccuracyDegrees, 360.0);
        }

        // Check timestamp > 1.48e12 (47 years in msec - 1970->2017+)
        EXPECT_GT(location.timestamp, 1.48e12);
    }

    /*
     * StopAndClearLocations:
     * Helper function to stop locations
     *
     * returns  true if a location was successfully generated
     */
    void StopAndClearLocations() {
        auto result = gnss_hal_->stop();

        EXPECT_TRUE(result.isOk());
        EXPECT_TRUE(result);

        /*
         * Clear notify/waiting counter, allowing up till the timeout after
         * the last reply for final startup messages to arrive (esp. system
         * info.)
         */
        while (wait(TIMEOUT_SEC) == std::cv_status::no_timeout) {
        }
    }

    sp<IGnss> gnss_hal_;         // GNSS HAL to call into
    sp<IGnssCallback> gnss_cb_;  // Primary callback interface

@@ -87,6 +209,10 @@ class GnssHalTest : public ::testing::VtsHalHidlTargetTestBase {
     */
    int info_called_count_;
    IGnssCallback::GnssSystemInfo last_info_;
    uint32_t last_capabilities_;
    int capabilities_called_count_;
    int location_called_count_;
    GnssLocation last_location_;

    int name_called_count_;
    android::hardware::hidl_string last_name_;
Loading