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

Commit dc7a8e78 authored by Stan Rokita's avatar Stan Rokita
Browse files

MultiHal 2.0 - Get sensors list from subhals

Implement SubHal constructors. The default ctor will get the SubHal
object pointers from dynamic libraries. The test ctor will take a vector
of SubHal objects. Implment the HalProxy getSensorsList method which
will return all the sensors from the subhal objects. Create one unit
test for getSensorsList as well.

Bug: 136511617
Test: Flashed onto device and observed proper logs for both test
subhals. Also, passed getSensorsList test.

Change-Id: I6e8ca4883c50daabbd7b0955d3664f66b6cd74bf
parent 60b836b0
Loading
Loading
Loading
Loading
+59 −35
Original line number Diff line number Diff line
@@ -70,42 +70,12 @@ class SensorsCallbackProxy : public ISensorsCallback {

HalProxy::HalProxy() {
    const char* kMultiHalConfigFilePath = "/vendor/etc/sensors/hals.conf";
    std::ifstream subHalConfigStream(kMultiHalConfigFilePath);
    if (!subHalConfigStream) {
        LOG_FATAL("Failed to load subHal config file: %s", kMultiHalConfigFilePath);
    } else {
        std::string subHalLibraryFile;
        while (subHalConfigStream >> subHalLibraryFile) {
            void* handle = dlopen(subHalLibraryFile.c_str(), RTLD_NOW);
            if (handle == nullptr) {
                LOG_FATAL("dlopen failed for library: %s", subHalLibraryFile.c_str());
            } else {
                SensorsHalGetSubHalFunc* sensorsHalGetSubHalPtr =
                        (SensorsHalGetSubHalFunc*)dlsym(handle, "sensorsHalGetSubHal");
                if (sensorsHalGetSubHalPtr == nullptr) {
                    LOG_FATAL("Failed to locate sensorsHalGetSubHal function for library: %s",
                              subHalLibraryFile.c_str());
                } else {
                    std::function<SensorsHalGetSubHalFunc> sensorsHalGetSubHal =
                            *sensorsHalGetSubHalPtr;
                    uint32_t version;
                    ISensorsSubHal* subHal = sensorsHalGetSubHal(&version);
                    if (version != SUB_HAL_2_0_VERSION) {
                        LOG_FATAL("SubHal version was not 2.0 for library: %s",
                                  subHalLibraryFile.c_str());
                    } else {
                        ALOGI("Loaded SubHal from library: %s", subHalLibraryFile.c_str());
                        mSubHalList.push_back(subHal);
                    }
                }
            }
        }
    }
    // TODO: Discover sensors
    initializeSubHalListFromConfigFile(kMultiHalConfigFilePath);
    initializeSensorList();
}

HalProxy::HalProxy(std::vector<ISensorsSubHal*>& subHalList) : mSubHalList(subHalList) {
    // TODO: Perform the same steps as the empty constructor.
    initializeSensorList();
}

HalProxy::~HalProxy() {
@@ -113,8 +83,8 @@ HalProxy::~HalProxy() {
    // state.
}

Return<void> HalProxy::getSensorsList(getSensorsList_cb /* _hidl_cb */) {
    // TODO: Output sensors list created as part of HalProxy().
Return<void> HalProxy::getSensorsList(getSensorsList_cb _hidl_cb) {
    _hidl_cb(mSensorList);
    return Void();
}

@@ -217,6 +187,60 @@ Return<void> HalProxy::onDynamicSensorsDisconnected(
    return Return<void>();
}

void HalProxy::initializeSubHalListFromConfigFile(const char* configFileName) {
    std::ifstream subHalConfigStream(configFileName);
    if (!subHalConfigStream) {
        LOG_FATAL("Failed to load subHal config file: %s", configFileName);
    } else {
        std::string subHalLibraryFile;
        while (subHalConfigStream >> subHalLibraryFile) {
            void* handle = dlopen(subHalLibraryFile.c_str(), RTLD_NOW);
            if (handle == nullptr) {
                LOG_FATAL("dlopen failed for library: %s", subHalLibraryFile.c_str());
            } else {
                SensorsHalGetSubHalFunc* sensorsHalGetSubHalPtr =
                        (SensorsHalGetSubHalFunc*)dlsym(handle, "sensorsHalGetSubHal");
                if (sensorsHalGetSubHalPtr == nullptr) {
                    LOG_FATAL("Failed to locate sensorsHalGetSubHal function for library: %s",
                              subHalLibraryFile.c_str());
                } else {
                    std::function<SensorsHalGetSubHalFunc> sensorsHalGetSubHal =
                            *sensorsHalGetSubHalPtr;
                    uint32_t version;
                    ISensorsSubHal* subHal = sensorsHalGetSubHal(&version);
                    if (version != SUB_HAL_2_0_VERSION) {
                        LOG_FATAL("SubHal version was not 2.0 for library: %s",
                                  subHalLibraryFile.c_str());
                    } else {
                        ALOGV("Loaded SubHal from library: %s", subHalLibraryFile.c_str());
                        mSubHalList.push_back(subHal);
                    }
                }
            }
        }
    }
}

void HalProxy::initializeSensorList() {
    for (size_t subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
        ISensorsSubHal* subHal = mSubHalList[subHalIndex];
        auto result = subHal->getSensorsList([&](const auto& list) {
            for (SensorInfo sensor : list) {
                if ((sensor.sensorHandle & 0xFF000000) != 0) {
                    ALOGE("SubHal sensorHandle's first byte was not 0");
                } else {
                    ALOGV("Loaded sensor: %s", sensor.name.c_str());
                    sensor.sensorHandle |= (subHalIndex << 24);
                    mSensorList.push_back(sensor);
                }
            }
        });
        if (!result.isOk()) {
            ALOGE("getSensorsList call failed for SubHal: %s", subHal->getName().c_str());
        }
    }
}

ISensorsSubHal* HalProxy::getSubHalForSensorHandle(uint32_t sensorHandle) {
    return mSubHalList[static_cast<size_t>(sensorHandle >> 24)];
}
+23 −1
Original line number Diff line number Diff line
@@ -39,7 +39,8 @@ using ::android::hardware::MQDescriptor;
using ::android::hardware::Return;
using ::android::hardware::Void;

struct HalProxy : public ISensors {
class HalProxy : public ISensors {
  public:
    using Event = ::android::hardware::sensors::V1_0::Event;
    using OperationMode = ::android::hardware::sensors::V1_0::OperationMode;
    using RateLevel = ::android::hardware::sensors::V1_0::RateLevel;
@@ -119,6 +120,27 @@ struct HalProxy : public ISensors {
     */
    std::vector<ISensorsSubHal*> mSubHalList;

    /**
     * List of SensorInfo objects that contains the sensor info from subhals as
     * well as the modified sensor handle for the framework.
     *
     * The subhal index is encoded in the first byte of the sensor handle and
     * the remaining bytes are generated by the subhal.
     */
    std::vector<SensorInfo> mSensorList;

    /**
     * Initialize the list of SubHal objects in mSubHalList by reading from dynamic libraries
     * listed in a config file.
     */
    void initializeSubHalListFromConfigFile(const char* configFileName);

    /**
     * Initialize the list of SensorInfo objects in mSensorList by getting sensors from each
     * subhal.
     */
    void initializeSensorList();

    /*
     * Get the subhal pointer which can be found by indexing into the mSubHalList vector
     * using the index from the first byte of sensorHandle.
+1 −0
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ class IHalProxyCallback : public ISensorsCallback {
 * sub-HALs can continue to use the lower 3 bytes of the handle.
 */
class ISensorsSubHal : public ISensors {
  public:
    // The ISensors version of initialize isn't used for multihal. Instead, sub-HALs must implement
    // the version below to allow communciation logic to centralized in the HalProxy
    Return<Result> initialize(
+56 −4
Original line number Diff line number Diff line
@@ -18,7 +18,14 @@
#include "HalProxy.h"
#include "SensorsSubHal.h"

#include <vector>

using ::android::hardware::sensors::V1_0::SensorInfo;
using ::android::hardware::sensors::V1_0::SensorType;
using ::android::hardware::sensors::V2_0::implementation::HalProxy;
using ::android::hardware::sensors::V2_0::subhal::implementation::AllSensorsSubHal;
using ::android::hardware::sensors::V2_0::subhal::implementation::ContinuousSensorsSubHal;
using ::android::hardware::sensors::V2_0::subhal::implementation::OnChangeSensorsSubHal;
using ::android::hardware::sensors::V2_0::subhal::implementation::SensorsSubHal;

// TODO: Add more interesting tests such as
@@ -30,10 +37,55 @@ using ::android::hardware::sensors::V2_0::subhal::implementation::SensorsSubHal;
//
// See https://source.android.com/compatibility/tests/development/native-func-e2e.md for more info
// on how tests are set up and for information on the gtest framework itself.
TEST(HalProxyTest, ExampleTest) {
    SensorsSubHal subHal;
    std::vector<ISensorsSubHal*> fakeSubHals;
    fakeSubHals.push_back(&subHal);

// Helper declarations follow
void testSensorsListFromProxyAndSubHal(const std::vector<SensorInfo>& proxySensorsList,
                                       const std::vector<SensorInfo>& subHalSensorsList);

// Tests follow
TEST(HalProxyTest, GetSensorsListOneSubHalTest) {
    AllSensorsSubHal subHal;
    std::vector<ISensorsSubHal*> fakeSubHals{&subHal};
    HalProxy proxy(fakeSubHals);

    proxy.getSensorsList([&](const auto& proxySensorsList) {
        subHal.getSensorsList([&](const auto& subHalSensorsList) {
            testSensorsListFromProxyAndSubHal(proxySensorsList, subHalSensorsList);
        });
    });
}

TEST(HalProxyTest, GetSensorsListTwoSubHalTest) {
    ContinuousSensorsSubHal continuousSubHal;
    OnChangeSensorsSubHal onChangeSubHal;
    std::vector<ISensorsSubHal*> fakeSubHals;
    fakeSubHals.push_back(&continuousSubHal);
    fakeSubHals.push_back(&onChangeSubHal);
    HalProxy proxy(fakeSubHals);

    std::vector<SensorInfo> proxySensorsList, combinedSubHalSensorsList;

    proxy.getSensorsList([&](const auto& list) { proxySensorsList = list; });
    continuousSubHal.getSensorsList([&](const auto& list) {
        combinedSubHalSensorsList.insert(combinedSubHalSensorsList.end(), list.begin(), list.end());
    });
    onChangeSubHal.getSensorsList([&](const auto& list) {
        combinedSubHalSensorsList.insert(combinedSubHalSensorsList.end(), list.begin(), list.end());
    });

    testSensorsListFromProxyAndSubHal(proxySensorsList, combinedSubHalSensorsList);
}

// Helper implementations follow
void testSensorsListFromProxyAndSubHal(const std::vector<SensorInfo>& proxySensorsList,
                                       const std::vector<SensorInfo>& subHalSensorsList) {
    EXPECT_EQ(proxySensorsList.size(), subHalSensorsList.size());

    for (size_t i = 0; i < proxySensorsList.size(); i++) {
        const SensorInfo& proxySensor = proxySensorsList[i];
        const SensorInfo& subHalSensor = subHalSensorsList[i];

        EXPECT_EQ(proxySensor.type, subHalSensor.type);
        EXPECT_EQ(proxySensor.sensorHandle & 0x00FFFFFF, subHalSensor.sensorHandle);
    }
}
 No newline at end of file
+37 −16
Original line number Diff line number Diff line
@@ -20,7 +20,16 @@
#include <log/log.h>

ISensorsSubHal* sensorsHalGetSubHal(uint32_t* version) {
#if defined SUPPORT_CONTINUOUS_SENSORS && defined SUPPORT_ON_CHANGE_SENSORS
    static ::android::hardware::sensors::V2_0::subhal::implementation::AllSensorsSubHal subHal;
#elif defined SUPPORT_CONTINUOUS_SENSORS
    static ::android::hardware::sensors::V2_0::subhal::implementation::ContinuousSensorsSubHal
            subHal;
#elif defined SUPPORT_ON_CHANGE_SENSORS
    static ::android::hardware::sensors::V2_0::subhal::implementation::OnChangeSensorsSubHal subHal;
#else
    static ::android::hardware::sensors::V2_0::subhal::implementation::SensorsSubHal subHal;
#endif  // defined SUPPORT_CONTINUOUS_SENSORS && defined SUPPORT_ON_CHANGE_SENSORS
    *version = SUB_HAL_2_0_VERSION;
    return &subHal;
}
@@ -42,22 +51,7 @@ using ::android::hardware::sensors::V2_0::SensorTimeout;
using ::android::hardware::sensors::V2_0::WakeLockQueueFlagBits;
using ::android::hardware::sensors::V2_0::implementation::ScopedWakelock;

SensorsSubHal::SensorsSubHal() : mCallback(nullptr), mNextHandle(1) {
#ifdef SUPPORT_CONTINUOUS_SENSORS
    AddSensor<AccelSensor>();
    AddSensor<GyroSensor>();
    AddSensor<MagnetometerSensor>();
    AddSensor<PressureSensor>();
#endif  // SUPPORT_CONTINUOUS_SENSORS

#ifdef SUPPORT_ON_CHANGE_SENSORS
    AddSensor<AmbientTempSensor>();
    AddSensor<DeviceTempSensor>();
    AddSensor<LightSensor>();
    AddSensor<ProximitySensor>();
    AddSensor<RelativeHumiditySensor>();
#endif  // SUPPORT_ON_CHANGE_SENSORS
}
SensorsSubHal::SensorsSubHal() : mCallback(nullptr), mNextHandle(1) {}

// Methods from ::android::hardware::sensors::V2_0::ISensors follow.
Return<void> SensorsSubHal::getSensorsList(getSensorsList_cb _hidl_cb) {
@@ -171,6 +165,33 @@ void SensorsSubHal::postEvents(const std::vector<Event>& events, bool wakeup) {
    mCallback->postEvents(events, std::move(wakelock));
}

ContinuousSensorsSubHal::ContinuousSensorsSubHal() {
    AddSensor<AccelSensor>();
    AddSensor<GyroSensor>();
    AddSensor<MagnetometerSensor>();
    AddSensor<PressureSensor>();
}

OnChangeSensorsSubHal::OnChangeSensorsSubHal() {
    AddSensor<AmbientTempSensor>();
    AddSensor<DeviceTempSensor>();
    AddSensor<LightSensor>();
    AddSensor<ProximitySensor>();
    AddSensor<RelativeHumiditySensor>();
}

AllSensorsSubHal::AllSensorsSubHal() {
    AddSensor<AccelSensor>();
    AddSensor<GyroSensor>();
    AddSensor<MagnetometerSensor>();
    AddSensor<PressureSensor>();
    AddSensor<AmbientTempSensor>();
    AddSensor<DeviceTempSensor>();
    AddSensor<LightSensor>();
    AddSensor<ProximitySensor>();
    AddSensor<RelativeHumiditySensor>();
}

}  // namespace implementation
}  // namespace subhal
}  // namespace V2_0
Loading