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

Commit c7b9263a authored by Tyler Trephan's avatar Tyler Trephan
Browse files

Created new virtual LimitedAxesImuSensor.

Updated SensorService to instantiate a new virtual
LimitedAxesImuSensor instance for each physical 3D IMU sensor
available on an automotive device.

Fix: 194217520
Bug: 194217520
Test: m sensorservice
Change-Id: Iefa4acc7fd4cc729149324c50cd63039c0af5157
parent fd90d8e7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ cc_library_shared {
        "Fusion.cpp",
        "GravitySensor.cpp",
        "HidlSensorHalWrapper.cpp",
        "LimitedAxesImuSensor.cpp",
        "LinearAccelerationSensor.cpp",
        "OrientationSensor.cpp",
        "RecentEventLogger.cpp",
+134 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.
 */

#include <math.h>
#include <stdint.h>
#include <sys/types.h>

#include <utils/Errors.h>

#include <hardware/sensors.h>

#include "LimitedAxesImuSensor.h"
#include "SensorDevice.h"
#include "SensorFusion.h"
#include "SensorServiceUtils.h"

namespace android {

namespace {
const sensor_t DUMMY_SENSOR = {.name = "",
                               .vendor = "",
                               .stringType = "",
                               .requiredPermission = ""};
} // unnamed namespace

LimitedAxesImuSensor::LimitedAxesImuSensor(sensor_t const* list, size_t count,
                                           int32_t imu3dSensorType)
      : BaseSensor(DUMMY_SENSOR) {
    for (size_t i = 0; i < count; i++) {
        if (list[i].type == imu3dSensorType) {
            mImu3dSensor = Sensor(list + i);
            break;
        }
    }

    const int32_t imuLimitedAxesSensorType = convertImu3dToLimitedAxesSensorType(imu3dSensorType);

    const sensor_t sensor = {
            .name = convertLimitedAxesSensorTypeToName(imuLimitedAxesSensorType),
            .vendor = "AOSP",
            .version = 1,
            .handle = convertLimitedAxesSensorTypeToHandle(imuLimitedAxesSensorType),
            .type = imuLimitedAxesSensorType,
            .maxRange = mImu3dSensor.getMaxValue(),
            .resolution = mImu3dSensor.getResolution(),
            .power = mImu3dSensor.getPowerUsage(),
            .minDelay = mImu3dSensor.getMinDelay(),
    };
    mSensor = Sensor(&sensor);
}

bool LimitedAxesImuSensor::process(sensors_event_t* outEvent, const sensors_event_t& event) {
    if (event.type == mImu3dSensor.getType()) {
        *outEvent = event;
        size_t imu3dDataSize = SensorServiceUtil::eventSizeBySensorType(mImu3dSensor.getType());
        outEvent->data[0 + imu3dDataSize] = 1;
        outEvent->data[1 + imu3dDataSize] = 1;
        outEvent->data[2 + imu3dDataSize] = 1;
        outEvent->sensor = mSensor.getHandle();
        outEvent->type = mSensor.getType();
        return true;
    }
    return false;
}

status_t LimitedAxesImuSensor::activate(void* ident, bool enabled) {
    return mSensorDevice.activate(ident, mImu3dSensor.getHandle(), enabled);
}

status_t LimitedAxesImuSensor::setDelay(void* ident, int /*handle*/, int64_t ns) {
    return mSensorDevice.setDelay(ident, mImu3dSensor.getHandle(), ns);
}

int32_t LimitedAxesImuSensor::convertImu3dToLimitedAxesSensorType(int32_t imu3dSensorType) {
    switch (imu3dSensorType) {
        case SENSOR_TYPE_ACCELEROMETER:
            return SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES;
        case SENSOR_TYPE_GYROSCOPE:
            return SENSOR_TYPE_GYROSCOPE_LIMITED_AXES;
        case SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED:
            return SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED;
        case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
            return SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED;
        default:
            return 0;
    }
}

int32_t LimitedAxesImuSensor::convertLimitedAxesSensorTypeToHandle(
        int32_t imuLimitedAxesSensorType) {
    switch (imuLimitedAxesSensorType) {
        case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES:
            return '_ala';
        case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES:
            return '_gla';
        case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED:
            return '_alc';
        case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED:
            return '_glc';
        default:
            return 0;
    }
}

const char* LimitedAxesImuSensor::convertLimitedAxesSensorTypeToName(
        int32_t imuLimitedAxesSensorType) {
    switch (imuLimitedAxesSensorType) {
        case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES:
            return "Accelerometer Limited Axes Sensor";
        case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES:
            return "Gyroscope Limited Axes Sensor";
        case SENSOR_TYPE_ACCELEROMETER_LIMITED_AXES_UNCALIBRATED:
            return "Accelerometer Limited Axes Uncalibrated Sensor";
        case SENSOR_TYPE_GYROSCOPE_LIMITED_AXES_UNCALIBRATED:
            return "Gyroscope Limited Axes Uncalibrated Sensor";
        default:
            return "";
    }
}

}; // namespace android
+46 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.
 */

#pragma once

#include <stdint.h>
#include <sys/types.h>

#include <sensor/Sensor.h>

#include "SensorInterface.h"

namespace android {

class SensorDevice;

class LimitedAxesImuSensor : public BaseSensor {
    Sensor mImu3dSensor;

public:
    LimitedAxesImuSensor(sensor_t const* list, size_t count, int32_t imuSensorType);
    virtual bool process(sensors_event_t* outEvent, const sensors_event_t& event) override;
    virtual status_t activate(void* ident, bool enabled) override;
    virtual status_t setDelay(void* ident, int handle, int64_t ns) override;
    virtual bool isVirtual() const override { return true; }

private:
    int32_t convertImu3dToLimitedAxesSensorType(int32_t imu3dSensorType);
    int32_t convertLimitedAxesSensorTypeToHandle(int32_t imuLimitedAxesSensorType);
    const char* convertLimitedAxesSensorTypeToName(int32_t imuLimitedAxesSensorType);
};

}; // namespace android
 No newline at end of file
+62 −3
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include "BatteryService.h"
#include "CorrectedGyroSensor.h"
#include "GravitySensor.h"
#include "LimitedAxesImuSensor.h"
#include "LinearAccelerationSensor.h"
#include "OrientationSensor.h"
#include "RotationVectorSensor.h"
@@ -101,6 +102,33 @@ static const String16 sDumpPermission("android.permission.DUMP");
static const String16 sLocationHardwarePermission("android.permission.LOCATION_HARDWARE");
static const String16 sManageSensorsPermission("android.permission.MANAGE_SENSORS");

static bool isAutomotive() {
    sp<IServiceManager> serviceManager = defaultServiceManager();
    if (serviceManager.get() == nullptr) {
        ALOGE("%s: unable to access native ServiceManager", __func__);
        return false;
    }

    sp<content::pm::IPackageManagerNative> packageManager;
    sp<IBinder> binder = serviceManager->waitForService(String16("package_native"));
    packageManager = interface_cast<content::pm::IPackageManagerNative>(binder);
    if (packageManager == nullptr) {
        ALOGE("%s: unable to access native PackageManager", __func__);
        return false;
    }

    bool isAutomotive = false;
    binder::Status status =
        packageManager->hasSystemFeature(String16("android.hardware.type.automotive"), 0,
                                         &isAutomotive);
    if (!status.isOk()) {
        ALOGE("%s: hasSystemFeature failed: %s", __func__, status.exceptionMessage().c_str());
        return false;
    }

    return isAutomotive;
}

SensorService::SensorService()
    : mInitCheck(NO_INIT), mSocketBufferSize(SOCKET_BUFFER_SIZE_NON_BATCHED),
      mWakeLockAcquired(false), mLastReportedProxIsActive(false) {
@@ -165,6 +193,8 @@ void SensorService::onFirstRef() {
        ssize_t count = dev.getSensorList(&list);
        if (count > 0) {
            bool hasGyro = false, hasAccel = false, hasMag = false;
            bool hasGyroUncalibrated = false;
            bool hasAccelUncalibrated = false;
            uint32_t virtualSensorsNeeds =
                    (1<<SENSOR_TYPE_GRAVITY) |
                    (1<<SENSOR_TYPE_LINEAR_ACCELERATION) |
@@ -179,13 +209,18 @@ void SensorService::onFirstRef() {
                    case SENSOR_TYPE_ACCELEROMETER:
                        hasAccel = true;
                        break;
                    case SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED:
                        hasAccelUncalibrated = true;
                        break;
                    case SENSOR_TYPE_MAGNETIC_FIELD:
                        hasMag = true;
                        break;
                    case SENSOR_TYPE_GYROSCOPE:
                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
                        hasGyro = true;
                        break;
                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
                        hasGyroUncalibrated = true;
                        break;
                    case SENSOR_TYPE_GRAVITY:
                    case SENSOR_TYPE_LINEAR_ACCELERATION:
                    case SENSOR_TYPE_ROTATION_VECTOR:
@@ -216,7 +251,7 @@ void SensorService::onFirstRef() {
            // registered)
            SensorFusion::getInstance();

            if (hasGyro && hasAccel && hasMag) {
            if ((hasGyro || hasGyroUncalibrated) && hasAccel && hasMag) {
                // Add Android virtual sensors if they're not already
                // available in the HAL
                bool needRotationVector =
@@ -230,7 +265,7 @@ void SensorService::onFirstRef() {
                registerSensor( new GyroDriftSensor(), true, true);
            }

            if (hasAccel && hasGyro) {
            if (hasAccel && (hasGyro || hasGyroUncalibrated)) {
                bool needGravitySensor = (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) != 0;
                registerSensor(new GravitySensor(list, count), !needGravitySensor, true);

@@ -250,6 +285,30 @@ void SensorService::onFirstRef() {
                registerSensor(new GeoMagRotationVectorSensor(), !needGeoMagRotationVector, true);
            }

            if (isAutomotive()) {
                if (hasAccel) {
                   registerSensor(new LimitedAxesImuSensor(list, count, SENSOR_TYPE_ACCELEROMETER),
                                  /*isDebug=*/false, /*isVirtual=*/true);
               }

               if (hasGyro) {
                   registerSensor(new LimitedAxesImuSensor(list, count, SENSOR_TYPE_GYROSCOPE),
                                  /*isDebug=*/false, /*isVirtual=*/true);
               }

               if (hasAccelUncalibrated) {
                   registerSensor(new LimitedAxesImuSensor(list, count,
                                                           SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED),
                                  /*isDebug=*/false, /*isVirtual=*/true);
               }

               if (hasGyroUncalibrated) {
                   registerSensor(new LimitedAxesImuSensor(list, count,
                                                           SENSOR_TYPE_GYROSCOPE_UNCALIBRATED),
                                  /*isDebug=*/false, /*isVirtual=*/true);
               }
            }

            // Check if the device really supports batching by looking at the FIFO event
            // counts for each sensor.
            bool batchingSupported = false;