C++程序  |  448行  |  12.66 KB

/*
 * 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.
 */

#include "ALooper.h"
#include "ASensorEventQueue.h"
#include "ASensorManager.h"

#define LOG_TAG "libsensorndkbridge"
#include <android-base/logging.h>
#include <android/looper.h>
#include <hidl/HidlTransportSupport.h>
#include <sensors/convert.h>

using android::hardware::sensors::V1_0::SensorInfo;
using android::frameworks::sensorservice::V1_0::IEventQueue;
using android::frameworks::sensorservice::V1_0::ISensorManager;
using android::frameworks::sensorservice::V1_0::Result;
using android::hardware::sensors::V1_0::SensorType;
using android::sp;
using android::wp;
using android::Mutex;
using android::status_t;
using android::OK;
using android::NO_INIT;
using android::BAD_VALUE;
using android::hardware::hidl_vec;
using android::hardware::Return;

static Mutex gLock;

// static
ASensorManager *ASensorManager::sInstance = NULL;

// static
ASensorManager *ASensorManager::getInstance() {
    Mutex::Autolock autoLock(gLock);
    if (sInstance == NULL) {
        sInstance = new ASensorManager;
        if (sInstance->initCheck() != OK) {
            delete sInstance;
            sInstance = NULL;
        }
    }
    return sInstance;
}

void ASensorManager::SensorDeathRecipient::serviceDied(
        uint64_t, const wp<::android::hidl::base::V1_0::IBase>&) {
    LOG(ERROR) << "Sensor service died. Cleanup sensor manager instance!";
    Mutex::Autolock autoLock(gLock);
    delete sInstance;
    sInstance = NULL;
}

ASensorManager::ASensorManager()
    : mInitCheck(NO_INIT) {
    mManager = ISensorManager::getService();
    if (mManager != NULL) {
        mDeathRecipient = new SensorDeathRecipient();
        Return<bool> linked = mManager->linkToDeath(mDeathRecipient, /*cookie*/ 0);
        if (!linked.isOk()) {
            LOG(ERROR) << "Transaction error in linking to sensor service death: " <<
                    linked.description().c_str();
        } else if (!linked) {
            LOG(WARNING) << "Unable to link to sensor service death notifications";
        } else {
            LOG(DEBUG) << "Link to sensor service death notification successful";
            mInitCheck = OK;
        }
    }
}

status_t ASensorManager::initCheck() const {
    return mInitCheck;
}

int ASensorManager::getSensorList(ASensorList *out) {
    LOG(VERBOSE) << "ASensorManager::getSensorList";

    Mutex::Autolock autoLock(mLock);

    if (mSensorList == NULL) {
        Return<void> ret =
            mManager->getSensorList([&](const auto &list, auto result) {
                if (result != Result::OK) {
                    return;
                }

                mSensors = list;
        });

        (void)ret.isOk();

        mSensorList.reset(new ASensorRef[mSensors.size()]);
        for (size_t i = 0; i < mSensors.size(); ++i) {
            mSensorList.get()[i] =
                reinterpret_cast<ASensorRef>(&mSensors[i]);
        }
    }

    if (out) {
        *out = reinterpret_cast<ASensorList>(mSensorList.get());
    }

    return mSensors.size();
}

ASensorRef ASensorManager::getDefaultSensor(int type) {
    (void)getSensorList(NULL /* list */);

    ASensorRef defaultSensor = NULL;

    Return<void> ret = mManager->getDefaultSensor(
            static_cast<SensorType>(type),
            [&](const auto &sensor, auto result) {
                if (result != Result::OK) {
                    return;
                }

                for (size_t i = 0; i < mSensors.size(); ++i) {
                    if (sensor == mSensors[i]) {
                        defaultSensor =
                             reinterpret_cast<ASensorRef>(&mSensors[i]);

                        break;
                    }
                }
            });

    (void)ret.isOk();

    return defaultSensor;
}

ASensorRef ASensorManager::getDefaultSensorEx(
        int /* type */, bool /* wakeup */) {
    // XXX ISensorManager's getDefaultSensorEx() lacks a "wakeup" parameter.
    return NULL;
}

ASensorEventQueue *ASensorManager::createEventQueue(
        ALooper *looper, int ident, ALooper_callbackFunc callback, void *data) {
    LOG(VERBOSE) << "ASensorManager::createEventQueue";

    sp<ASensorEventQueue> queue =
        new ASensorEventQueue(looper, ident, callback, data);

    ::android::hardware::setMinSchedulerPolicy(queue, SCHED_FIFO, 98);
    Result result;
    Return<void> ret =
        mManager->createEventQueue(
                queue, [&](const sp<IEventQueue> &queueImpl, auto tmpResult) {
                    result = tmpResult;
                    if (result != Result::OK) {
                        return;
                    }

                    queue->setImpl(queueImpl);
                });

    if (!ret.isOk() || result != Result::OK) {
        LOG(ERROR) << "FAILED to create event queue";
        return NULL;
    }

    queue->incStrong(NULL /* id */);

    LOG(VERBOSE) << "Returning event queue " << queue.get();
    return queue.get();
}

void ASensorManager::destroyEventQueue(ASensorEventQueue *queue) {
    LOG(VERBOSE) << "ASensorManager::destroyEventQueue(" << queue << ")";

    queue->invalidate();

    queue->decStrong(NULL /* id */);
    queue = NULL;
}

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

ASensorManager *ASensorManager_getInstance() {
    return ASensorManager::getInstance();
}

ASensorManager *ASensorManager_getInstanceForPackage(
        const char* /* packageName */) {
    return ASensorManager::getInstance();
}

#define RETURN_IF_MANAGER_IS_NULL(x)    \
    do {                                \
        if (manager == NULL) {          \
            return x;                   \
        }                               \
    } while (0)

#define RETURN_IF_QUEUE_IS_NULL(x)      \
    do {                                \
        if (queue == NULL) {            \
            return x;                   \
        }                               \
    } while (0)

#define RETURN_IF_SENSOR_IS_NULL(x)     \
    do {                                \
        if (sensor == NULL) {           \
            return x;                   \
        }                               \
    } while (0)

int ASensorManager_getSensorList(ASensorManager* manager, ASensorList* list) {
    RETURN_IF_MANAGER_IS_NULL(BAD_VALUE);
    return manager->getSensorList(list);
}

ASensor const* ASensorManager_getDefaultSensor(
        ASensorManager* manager, int type) {
    RETURN_IF_MANAGER_IS_NULL(NULL);

    return manager->getDefaultSensor(type);
}

#if 0
ASensor const* ASensorManager_getDefaultSensorEx(
        ASensorManager* manager, int type, bool wakeUp) {
    RETURN_IF_MANAGER_IS_NULL(NULL);

    return manager->getDefaultSensorEx(type, wakeUp);
}
#endif

ASensorEventQueue* ASensorManager_createEventQueue(
        ASensorManager* manager,
        ALooper* looper,
        int ident,
        ALooper_callbackFunc callback,
        void* data) {
    RETURN_IF_MANAGER_IS_NULL(NULL);

    if (looper == NULL) {
        return NULL;
    }

    return manager->createEventQueue(looper, ident, callback, data);
}

int ASensorManager_destroyEventQueue(
        ASensorManager* manager, ASensorEventQueue* queue) {
    RETURN_IF_MANAGER_IS_NULL(BAD_VALUE);
    RETURN_IF_QUEUE_IS_NULL(BAD_VALUE);

    manager->destroyEventQueue(queue);
    queue = NULL;

    return OK;
}

#if 0
int ASensorManager_createSharedMemoryDirectChannel(
        ASensorManager* manager, int fd, size_t size) {
    RETURN_IF_MANAGER_IS_NULL(BAD_VALUE);

    return OK;
}

int ASensorManager_createHardwareBufferDirectChannel(
        ASensorManager* manager, AHardwareBuffer const * buffer, size_t size) {
    RETURN_IF_MANAGER_IS_NULL(BAD_VALUE);

    return OK;
}

void ASensorManager_destroyDirectChannel(
        ASensorManager* manager, int channelId) {
}

int ASensorManager_configureDirectReport(
        ASensorManager* manager,
        ASensor const* sensor,
        int channelId,int rate) {
    RETURN_IF_MANAGER_IS_NULL(BAD_VALUE);
    return OK;
}
#endif

int ASensorEventQueue_registerSensor(
        ASensorEventQueue* queue,
        ASensor const* sensor,
        int32_t samplingPeriodUs,
        int64_t maxBatchReportLatencyUs) {
    LOG(VERBOSE) << "ASensorEventQueue_registerSensor";
    RETURN_IF_QUEUE_IS_NULL(BAD_VALUE);
    return queue->registerSensor(
            sensor, samplingPeriodUs, maxBatchReportLatencyUs);
}

int ASensorEventQueue_enableSensor(
        ASensorEventQueue* queue, ASensor const* sensor) {
    LOG(VERBOSE) << "ASensorEventQueue_enableSensor(queue " << queue << ")";
    RETURN_IF_QUEUE_IS_NULL(BAD_VALUE);
    return queue->enableSensor(sensor);
}

int ASensorEventQueue_disableSensor(
        ASensorEventQueue* queue, ASensor const* sensor) {
    LOG(VERBOSE) << "ASensorEventQueue_disableSensor";
    RETURN_IF_QUEUE_IS_NULL(BAD_VALUE);
    return queue->disableSensor(sensor);
}

int ASensorEventQueue_setEventRate(
        ASensorEventQueue* queue,
        ASensor const* sensor,
        int32_t usec) {
    RETURN_IF_QUEUE_IS_NULL(BAD_VALUE);
    return queue->setEventRate(sensor, usec);
}

int ASensorEventQueue_hasEvents(ASensorEventQueue* queue) {
    RETURN_IF_QUEUE_IS_NULL(BAD_VALUE);
    return queue->hasEvents();
}

ssize_t ASensorEventQueue_getEvents(
        ASensorEventQueue* queue, ASensorEvent* events, size_t count) {
    LOG(VERBOSE) << "ASensorEventQueue_getEvents";
    RETURN_IF_QUEUE_IS_NULL(BAD_VALUE);
    return queue->getEvents(events, count);
}

const char *ASensor_getName(ASensor const* sensor) {
    RETURN_IF_SENSOR_IS_NULL(NULL);
    return reinterpret_cast<const SensorInfo *>(sensor)->name.c_str();
}

const char *ASensor_getVendor(ASensor const* sensor) {
    RETURN_IF_SENSOR_IS_NULL(NULL);
    return reinterpret_cast<const SensorInfo *>(sensor)->vendor.c_str();
}

int ASensor_getType(ASensor const* sensor) {
    RETURN_IF_SENSOR_IS_NULL(ASENSOR_TYPE_INVALID);
    return static_cast<int>(
            reinterpret_cast<const SensorInfo *>(sensor)->type);
}

float ASensor_getResolution(ASensor const* sensor) {
    RETURN_IF_SENSOR_IS_NULL(ASENSOR_RESOLUTION_INVALID);
    return reinterpret_cast<const SensorInfo *>(sensor)->resolution;
}

int ASensor_getMinDelay(ASensor const* sensor) {
    RETURN_IF_SENSOR_IS_NULL(ASENSOR_DELAY_INVALID);
    return reinterpret_cast<const SensorInfo *>(sensor)->minDelay;
}

int ASensor_getFifoMaxEventCount(ASensor const* sensor) {
    RETURN_IF_SENSOR_IS_NULL(ASENSOR_FIFO_COUNT_INVALID);
    return reinterpret_cast<const SensorInfo *>(sensor)->fifoMaxEventCount;
}

int ASensor_getFifoReservedEventCount(ASensor const* sensor) {
    RETURN_IF_SENSOR_IS_NULL(ASENSOR_FIFO_COUNT_INVALID);
    return reinterpret_cast<const SensorInfo *>(sensor)->fifoReservedEventCount;
}

const char* ASensor_getStringType(ASensor const* sensor) {
    RETURN_IF_SENSOR_IS_NULL(NULL);
    return reinterpret_cast<const SensorInfo *>(sensor)->typeAsString.c_str();
}

extern "C" float ASensor_getMaxRange(ASensor const* sensor) {
    RETURN_IF_SENSOR_IS_NULL(nanf(""));
    return reinterpret_cast<const SensorInfo *>(sensor)->maxRange;
}

#if 0
int ASensor_getReportingMode(ASensor const* sensor) {
    RETURN_IF_SENSOR_IS_NULL(AREPORTING_MODE_INVALID);
    return 0;
}

bool ASensor_isWakeUpSensor(ASensor const* sensor) {
    RETURN_IF_SENSOR_IS_NULL(false);
    return false;
}

bool ASensor_isDirectChannelTypeSupported(
        ASensor const* sensor, int channelType) {
    RETURN_IF_SENSOR_IS_NULL(false);
    return false;
}

int ASensor_getHighestDirectReportRateLevel(ASensor const* sensor) {
    RETURN_IF_SENSOR_IS_NULL(ASENSOR_DIRECT_RATE_STOP);
    return 0;
}
#endif

static ALooper *getTheLooper() {
    static ALooper *sLooper = NULL;

    Mutex::Autolock autoLock(gLock);
    if (sLooper == NULL) {
        sLooper = new ALooper;
    }

    return sLooper;
}


ALooper *ALooper_forThread() {
    LOG(VERBOSE) << "ALooper_forThread";
    return getTheLooper();
}

ALooper *ALooper_prepare(int /* opts */) {
    LOG(VERBOSE) << "ALooper_prepare";
    return getTheLooper();
}

int ALooper_pollOnce(
        int timeoutMillis, int* outFd, int* outEvents, void** outData) {
    int res = getTheLooper()->pollOnce(timeoutMillis, outFd, outEvents, outData);
    LOG(VERBOSE) << "ALooper_pollOnce => " << res;
    return res;
}

void ALooper_wake(ALooper* looper) {
    LOG(VERBOSE) << "ALooper_wake";
    looper->wake();
}