Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/device/device/google/contexthub/sensorhal/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 13 kB image not shown  

Quelle  sensors.cpp

  Sprache: C
 

/*
 * Copyright (C) 2015 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.
 */


#define LOG_TAG "sensors"
#define LOG_NDEBUG  1
#include <utils/Log.h>

#include "hubconnection.h"
#include "sensorlist.h"
#include "sensors.h"

#include <cutils/ashmem.h>
#include <errno.h>
#include <math.h>
#include <media/stagefright/foundation/ADebug.h>
#include <string.h>
#include <sys/mman.h>
#include <stdlib.h>

#ifdef DYNAMIC_SENSOR_EXT_ENABLED
#include <DynamicSensorManager.h>
#include <SensorEventCallback.h>
#endif

#ifdef LEFTY_SERVICE_ENABLED
#include "lefty_service.h"
#endif

using namespace android;

////////////////////////////////////////////////////////////////////////////////

SensorContext::SensorContext(const struct hw_module_t *module)
        : mSensorList(kSensorList, kSensorList + kSensorCount),
          mHubConnection(HubConnection::getInstance()) {
    memset(&device, 0sizeof(device));

    device.common.tag = HARDWARE_DEVICE_TAG;
    device.common.version = SENSORS_DEVICE_API_VERSION_1_4;
    device.common.module = const_cast<hw_module_t *>(module);
    device.common.close = CloseWrapper;
    device.activate = ActivateWrapper;
    device.setDelay = SetDelayWrapper;
    device.poll = PollWrapper;
    device.batch = BatchWrapper;
    device.flush = FlushWrapper;
    device.inject_sensor_data = InjectSensorDataWrapper;
    mHubConnection->setRawScale(kScaleAccel, kScaleMag);
    if (mHubConnection->isDirectReportSupported()) {
        device.register_direct_channel = RegisterDirectChannelWrapper;
        device.config_direct_report = ConfigDirectReportWrapper;
    }

    mOperationHandler.emplace_back(new HubConnectionOperation(mHubConnection));

    initializeHalExtension();
}

int SensorContext::close() {
    ALOGV("close");

    delete this;

    return 0;
}

int SensorContext::activate(int handle, int enabled) {
    ALOGV("activate");

    for (auto &h : mOperationHandler) {
        if (h->owns(handle)) {
            return h->activate(handle, enabled);
        }
    }
    return INVALID_OPERATION;
}

int SensorContext::setDelay(int handle, int64_t delayNs) {
    ALOGV("setDelay");

    for (auto &h: mOperationHandler) {
        if (h->owns(handle)) {
            return h->setDelay(handle, delayNs);
        }
    }
    return INVALID_OPERATION;
}

int SensorContext::poll(sensors_event_t *data, int count) {
    ALOGV("poll");

    // Release wakelock if held and no more events in ring buffer
    mHubConnection->releaseWakeLockIfAppropriate();

    return mHubConnection->read(data, count);
}

int SensorContext::batch(
        int handle,
        int64_t sampling_period_ns,
        int64_t max_report_latency_ns) {
    ALOGV("batch");

    for (auto &h : mOperationHandler) {
        if (h->owns(handle)) {
            return h->batch(handle, sampling_period_ns, max_report_latency_ns);
        }
    }
    return INVALID_OPERATION;
}

int SensorContext::flush(int handle) {
    ALOGV("flush");

    for (auto &h : mOperationHandler) {
        if (h->owns(handle)) {
            return h->flush(handle);
        }
    }
    return INVALID_OPERATION;
}

int SensorContext::register_direct_channel(
        const struct sensors_direct_mem_t *mem, int32_t channel_handle) {
    if (mem) {
        //add
        return mHubConnection->addDirectChannel(mem);
    } else {
        //remove
        mHubConnection->removeDirectChannel(channel_handle);
        return NO_ERROR;
    }
}

int SensorContext::config_direct_report(
        int32_t sensor_handle, int32_t channel_handle, const struct sensors_direct_cfg_t * config) {
    int rate_level = config->rate_level;
    return mHubConnection->configDirectReport(sensor_handle, channel_handle, rate_level);
}

// static
int SensorContext::CloseWrapper(struct hw_device_t *dev) {
    return reinterpret_cast<SensorContext *>(dev)->close();
}

// static
int SensorContext::ActivateWrapper(
        struct sensors_poll_device_t *dev, int handle, int enabled) {
    return reinterpret_cast<SensorContext *>(dev)->activate(handle, enabled);
}

// static
int SensorContext::SetDelayWrapper(
        struct sensors_poll_device_t *dev, int handle, int64_t delayNs) {
    return reinterpret_cast<SensorContext *>(dev)->setDelay(handle, delayNs);
}

// static
int SensorContext::PollWrapper(
        struct sensors_poll_device_t *dev, sensors_event_t *data, int count) {
    return reinterpret_cast<SensorContext *>(dev)->poll(data, count);
}

// static
int SensorContext::BatchWrapper(
        struct sensors_poll_device_1 *dev,
        int handle,
        int flags,
        int64_t sampling_period_ns,
        int64_t max_report_latency_ns) {
    (void) flags;
    return reinterpret_cast<SensorContext *>(dev)->batch(
            handle, sampling_period_ns, max_report_latency_ns);
}

// static
int SensorContext::FlushWrapper(struct sensors_poll_device_1 *dev, int handle) {
    return reinterpret_cast<SensorContext *>(dev)->flush(handle);
}

// static
int SensorContext::RegisterDirectChannelWrapper(struct sensors_poll_device_1 *dev,
        const struct sensors_direct_mem_t* mem, int channel_handle) {
    return reinterpret_cast<SensorContext *>(dev)->register_direct_channel(
            mem, channel_handle);
}

// static
int SensorContext::ConfigDirectReportWrapper(struct sensors_poll_device_1 *dev,
        int sensor_handle, int channel_handle, const sensors_direct_cfg_t * config) {
    return reinterpret_cast<SensorContext *>(dev)->config_direct_report(
            sensor_handle, channel_handle, config);
}

int SensorContext::inject_sensor_data(const sensors_event_t *event) {
    ALOGV("inject_sensor_data");

    // only support set operation parameter, which will have handle == 0
    if (event == nullptr || event->type != SENSOR_TYPE_ADDITIONAL_INFO) {
        return -EINVAL;
    }

    if (event->sensor != SENSORS_HANDLE_BASE - 1) {
        return -ENOSYS;
    }

    if (event->additional_info.type == AINFO_BEGIN
            || event->additional_info.type == AINFO_END) {
        return 0;
    }

    mHubConnection->setOperationParameter(event->additional_info);
    return 0;
}

// static
int SensorContext::InjectSensorDataWrapper(struct sensors_poll_device_1 *dev,
        const struct sensors_event_t *event) {
    return reinterpret_cast<SensorContext *>(dev)->inject_sensor_data(event);
}

bool SensorContext::getHubAlive() {
    return (mHubConnection->initCheck() == OK && mHubConnection->getAliveCheck() == OK);
}

size_t SensorContext::getSensorList(sensor_t const **list) {
    ALOGE("sensor p = %p, n = %zu", mSensorList.data(), mSensorList.size());
    *list = mSensorList.data();
    return mSensorList.size();
}

// HubConnectionOperation functions
SensorContext::HubConnectionOperation::HubConnectionOperation(sp<HubConnection> hubConnection)
        : mHubConnection(hubConnection) {
    for (size_t i = 0; i < kSensorCount; i++) {
        mHandles.emplace(kSensorList[i].handle);
    }
}

bool SensorContext::HubConnectionOperation::owns(int handle) {
    return mHandles.find(handle) != mHandles.end();
}

int SensorContext::HubConnectionOperation::activate(int handle, int enabled) {
    mHubConnection->queueActivate(handle, enabled);
    return 0;
}

int SensorContext::HubConnectionOperation::setDelay(int handle, int64_t delayNs) {
    // clamp sample rate based on minDelay and maxDelay defined in kSensorList
    int64_t delayNsClamped = delayNs;
    for (size_t i = 0; i < kSensorCount; i++) {
        sensor_t sensor = kSensorList[i];
        if (sensor.handle != handle) {
            continue;
        }

        if ((sensor.flags & REPORTING_MODE_MASK) == SENSOR_FLAG_CONTINUOUS_MODE) {
            if ((delayNs/1000) < sensor.minDelay) {
                delayNsClamped = sensor.minDelay * 1000;
            } else if ((delayNs/1000) > sensor.maxDelay) {
                delayNsClamped = sensor.maxDelay * 1000;
            }
        }

        break;
    }

    mHubConnection->queueSetDelay(handle, delayNsClamped);
    return 0;
}

int SensorContext::HubConnectionOperation::batch(
        int handle, int64_t sampling_period_ns,
        int64_t max_report_latency_ns) {
    // clamp sample rate based on minDelay and maxDelay defined in kSensorList
    int64_t sampling_period_ns_clamped = sampling_period_ns;
    for (size_t i = 0; i < kSensorCount; i++) {
        sensor_t sensor = kSensorList[i];
        if (sensor.handle != handle) {
            continue;
        }

        if ((sensor.flags & REPORTING_MODE_MASK) == SENSOR_FLAG_CONTINUOUS_MODE) {
            if ((sampling_period_ns/1000) < sensor.minDelay) {
                sampling_period_ns_clamped = sensor.minDelay * 1000;
            } else if ((sampling_period_ns/1000) > sensor.maxDelay) {
                sampling_period_ns_clamped = sensor.maxDelay * 1000;
            }
        }

        break;
    }

    mHubConnection->queueBatch(handle, sampling_period_ns_clamped,
                               max_report_latency_ns);
    return 0;
}

int SensorContext::HubConnectionOperation::flush(int handle) {
    mHubConnection->queueFlush(handle);
    return 0;
}

#ifdef DYNAMIC_SENSOR_EXT_ENABLED
namespace {
// adaptor class
class Callback : public SensorEventCallback {
public:
    Callback(sp<HubConnection> hubConnection) : mHubConnection(hubConnection) {}
    virtual int submitEvent(sp<BaseSensorObject> source, const sensors_event_t &e) override;
private:
    sp<HubConnection> mHubConnection;
};

int Callback::submitEvent(sp<BaseSensorObject> source, const sensors_event_t &e) {
    (void) source; // irrelavent in this context
    return (mHubConnection->write(&e, 1) == 1) ? 0 : -ENOSPC;
}
// anonymous namespace

SensorContext::DynamicSensorManagerOperation::DynamicSensorManagerOperation(DynamicSensorManager* manager)
        : mDynamicSensorManager(manager) {
}

bool SensorContext::DynamicSensorManagerOperation::owns(int handle) {
    return mDynamicSensorManager->owns(handle);
}

int SensorContext::DynamicSensorManagerOperation::activate(int handle, int enabled) {
    return mDynamicSensorManager->activate(handle, enabled);
}

int SensorContext::DynamicSensorManagerOperation::setDelay(int handle, int64_t delayNs) {
    return mDynamicSensorManager->setDelay(handle, delayNs);
}

int SensorContext::DynamicSensorManagerOperation::batch(int handle, int64_t sampling_period_ns,
        int64_t max_report_latency_ns) {
    return mDynamicSensorManager->batch(handle, sampling_period_ns, max_report_latency_ns);
}

int SensorContext::DynamicSensorManagerOperation::flush(int handle) {
    return mDynamicSensorManager->flush(handle);
}
#endif

void SensorContext::initializeHalExtension() {
#ifdef DYNAMIC_SENSOR_EXT_ENABLED
    // initialize callback and dynamic sensor manager
    mEventCallback.reset(new Callback(mHubConnection));
    DynamicSensorManager* manager = DynamicSensorManager::createInstance(
        kDynamicHandleBase, kMaxDynamicHandleCount, mEventCallback.get());

    // add meta sensor to list
    mSensorList.push_back(manager->getDynamicMetaSensor());

    // register operation
    mOperationHandler.emplace_back(new DynamicSensorManagerOperation(manager));
#endif
}

////////////////////////////////////////////////////////////////////////////////

static bool gHubAlive;
static sensor_t const *sensor_list;
static int n_sensor;

static int open_sensors(
        const struct hw_module_t *module,
        const char *,
        struct hw_device_t **dev) {
    ALOGV("open_sensors");

    SensorContext *ctx = new SensorContext(module);
    n_sensor = ctx->getSensorList(&sensor_list);
    gHubAlive = ctx->getHubAlive();
    *dev = &ctx->device.common;

#ifdef LEFTY_SERVICE_ENABLED
    register_lefty_service();
#endif
    return 0;
}

static struct hw_module_methods_t sensors_module_methods = {
    .open = open_sensors
};

static int get_sensors_list(
        struct sensors_module_t *,
        struct sensor_t const **list) {
    ALOGV("get_sensors_list");
    if (gHubAlive && sensor_list != nullptr) {
        *list = sensor_list;
        return n_sensor;
    } else {
        *list = {};
        return 0;
    }
}

static int set_operation_mode(unsigned int mode) {
    ALOGV("set_operation_mode");

    // This is no-op because there is no sensor in the hal that system can
    // inject events. Only operation parameter injection is implemented, which
    // works in both data injection and normal mode.
    (void) mode;
    return 0;
}

struct sensors_module_t HAL_MODULE_INFO_SYM = {
        .common = {
                .tag = HARDWARE_MODULE_TAG,
                .version_major = 1,
                .version_minor = 0,
                .id = SENSORS_HARDWARE_MODULE_ID,
                .name = "Google Sensor module",
                .author = "Google",
                .methods = &sensors_module_methods,
                .dso  = NULL,
                .reserved = {0},
        },
        .get_sensors_list = get_sensors_list,
        .set_operation_mode = set_operation_mode,
};

Messung V0.5 in Prozent
C=92 H=95 G=93

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet am  2026-06-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.