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

Commit 629fde97 authored by Stan Rokita's avatar Stan Rokita Committed by Android (Google) Code Review
Browse files

Merge changes I4e39ca0e,I6e8ca488

* changes:
  MultiHal 2.0 - setOperationMode and init direct channel flags
  MultiHal 2.0 - Get sensors list from subhals
parents 36e92f17 7a723546
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ cc_binary {
    ],
    init_rc: ["android.hardware.sensors@2.0-service-multihal.rc"],
    vintf_fragments: ["android.hardware.sensors@2.0-multihal.xml"],
    cflags: ["-DLOG_TAG=\"SensorsMultiHal\""],
}

cc_library_headers {
+96 −39
Original line number Diff line number Diff line
@@ -69,43 +69,13 @@ 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
    const char* kMultiHalConfigFile = "/vendor/etc/sensors/hals.conf";
    initializeSubHalListFromConfigFile(kMultiHalConfigFile);
    initializeSensorList();
}

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

HalProxy::~HalProxy() {
@@ -113,14 +83,32 @@ 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();
}

Return<Result> HalProxy::setOperationMode(OperationMode /* mode */) {
    // TODO: Proxy API call to all sub-HALs and return appropriate result.
    return Result::INVALID_OPERATION;
Return<Result> HalProxy::setOperationMode(OperationMode mode) {
    Result result = Result::OK;
    size_t subHalIndex;
    for (subHalIndex = 0; subHalIndex < mSubHalList.size(); subHalIndex++) {
        ISensorsSubHal* subHal = mSubHalList[subHalIndex];
        result = subHal->setOperationMode(mode);
        if (result != Result::OK) {
            ALOGE("setOperationMode failed for SubHal: %s", subHal->getName().c_str());
            break;
        }
    }
    if (result != Result::OK) {
        // Reset the subhal operation modes that have been flipped
        for (size_t i = 0; i < subHalIndex; i++) {
            ISensorsSubHal* subHal = mSubHalList[i];
            subHal->setOperationMode(mCurrentOperationMode);
        }
    } else {
        mCurrentOperationMode = mode;
    }
    return result;
}

Return<Result> HalProxy::activate(int32_t sensorHandle, bool enabled) {
@@ -217,6 +205,75 @@ Return<void> HalProxy::onDynamicSensorsDisconnected(
    return Return<void>();
}

void HalProxy::initializeSubHalListFromConfigFile(const char* configFileName) {
    std::ifstream subHalConfigStream(configFileName);
    if (!subHalConfigStream) {
        ALOGE("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) {
                ALOGE("dlopen failed for library: %s", subHalLibraryFile.c_str());
            } else {
                SensorsHalGetSubHalFunc* sensorsHalGetSubHalPtr =
                        (SensorsHalGetSubHalFunc*)dlsym(handle, "sensorsHalGetSubHal");
                if (sensorsHalGetSubHalPtr == nullptr) {
                    ALOGE("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) {
                        ALOGE("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);
                    setDirectChannelFlags(&sensor, subHal);
                    mSensorList.push_back(sensor);
                }
            }
        });
        if (!result.isOk()) {
            ALOGE("getSensorsList call failed for SubHal: %s", subHal->getName().c_str());
        }
    }
}

void HalProxy::setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* subHal) {
    bool sensorSupportsDirectChannel =
            (sensorInfo->flags & (V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
                                  V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL)) != 0;
    if (mDirectChannelSubHal == nullptr && sensorSupportsDirectChannel) {
        mDirectChannelSubHal = subHal;
    } else if (mDirectChannelSubHal != nullptr && subHal != mDirectChannelSubHal) {
        // disable direct channel capability for sensors in subHals that are not
        // the only one we will enable
        sensorInfo->flags &= ~(V1_0::SensorFlagBits::MASK_DIRECT_REPORT |
                               V1_0::SensorFlagBits::MASK_DIRECT_CHANNEL);
    }
}

ISensorsSubHal* HalProxy::getSubHalForSensorHandle(uint32_t sensorHandle) {
    return mSubHalList[static_cast<size_t>(sensorHandle >> 24)];
}
+40 −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,44 @@ 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 to identify the sensor.
     */
    std::vector<SensorInfo> mSensorList;

    //! The current operation mode for all subhals.
    OperationMode mCurrentOperationMode = OperationMode::NORMAL;

    //! The single subHal that supports directChannel reporting.
    ISensorsSubHal* mDirectChannelSubHal = nullptr;

    /**
     * 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();

    /**
     * Clear direct channel flags if the HalProxy has already chosen a subhal as its direct channel
     * subhal. Set the directChannelSubHal pointer to the subHal passed in if this is the first
     * direct channel enabled sensor seen.
     *
     * @param sensorInfo The SensorInfo object that may be altered to have direct channel support
     *    disabled.
     * @param subHal The subhal pointer that the current sensorInfo object came from.
     */
    void setDirectChannelFlags(SensorInfo* sensorInfo, ISensorsSubHal* subHal);

    /*
     * 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(
+0 −2
Original line number Diff line number Diff line
@@ -14,8 +14,6 @@
 * limitations under the License.
 */

#define LOG_TAG "android.hardware.sensors@2.0-service"

#include <android/hardware/sensors/2.0/ISensors.h>
#include <hidl/HidlTransportSupport.h>
#include <log/log.h>
Loading