Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "SensorTest.h"
     18 #include <errno.h>
     19 
     20 namespace android {
     21 namespace SensorTest {
     22 
     23 // SensorTest container class
     24 bool SensorTest::SetUp() {
     25     if (mManager == nullptr) {
     26         mManager.reset(
     27               TestSensorManager::getInstanceForPackage("android.hardware.cts.SensorNativeTest"));
     28     }
     29     return mManager == nullptr;
     30 }
     31 
     32 void SensorTest::TearDown() {
     33     if (mManager == nullptr) {
     34         mManager.reset(nullptr);
     35     }
     36 }
     37 
     38 TestSensorManager::TestSensorManager(const char *package) {
     39     mManager = ASensorManager_getInstanceForPackage(package);
     40 }
     41 
     42 TestSensorManager::~TestSensorManager() {
     43     for (int channel : mSensorDirectChannel) {
     44         destroyDirectChannel(channel);
     45     }
     46     mSensorDirectChannel.clear();
     47 }
     48 
     49 TestSensorManager * TestSensorManager::getInstanceForPackage(const char *package) {
     50     return new TestSensorManager(package);
     51 }
     52 
     53 TestSensor TestSensorManager::getDefaultSensor(int type) {
     54     return TestSensor(ASensorManager_getDefaultSensor(mManager, type));
     55 }
     56 
     57 int TestSensorManager::createDirectChannel(const TestSharedMemory &mem) {
     58     if (!isValid()) {
     59         return -EINVAL;
     60     }
     61     switch (mem.getType()) {
     62         case ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY:
     63             return createSharedMemoryDirectChannel(
     64                     mem.getSharedMemoryFd(), mem.getSize());
     65         case ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER:
     66             return createHardwareBufferDirectChannel(
     67                     mem.getHardwareBuffer(), mem.getSize());
     68         default:
     69             return -1;
     70     }
     71 }
     72 
     73 int TestSensorManager::createSharedMemoryDirectChannel(int fd, size_t size) {
     74     int ret = ASensorManager_createSharedMemoryDirectChannel(mManager, fd, size);
     75     if (ret > 0) {
     76         mSensorDirectChannel.insert(ret);
     77     }
     78     return ret;
     79 }
     80 
     81 int TestSensorManager::createHardwareBufferDirectChannel(
     82         AHardwareBuffer const *buffer, size_t size) {
     83     int ret = ASensorManager_createHardwareBufferDirectChannel(mManager, buffer, size);
     84     if (ret > 0) {
     85         mSensorDirectChannel.insert(ret);
     86     }
     87     return ret;
     88 }
     89 
     90 void TestSensorManager::destroyDirectChannel(int channel) {
     91     if (!isValid()) {
     92         return;
     93     }
     94     ASensorManager_destroyDirectChannel(mManager, channel);
     95     mSensorDirectChannel.erase(channel);
     96     return;
     97 }
     98 
     99 int TestSensorManager::configureDirectReport(TestSensor sensor, int channel, int rate) {
    100     if (!isValid()) {
    101         return -EINVAL;
    102     }
    103     return ASensorManager_configureDirectReport(mManager, sensor, channel, rate);
    104 }
    105 
    106 char * TestSharedMemory::getBuffer() const {
    107     return mBuffer;
    108 }
    109 
    110 std::vector<ASensorEvent> TestSharedMemory::parseEvents(int64_t lastCounter, size_t offset) const {
    111     constexpr size_t kEventSize = sizeof(ASensorEvent);
    112     constexpr size_t kOffsetSize = offsetof(ASensorEvent, version);
    113     constexpr size_t kOffsetAtomicCounter = offsetof(ASensorEvent, reserved0);
    114 
    115     std::vector<ASensorEvent> events;
    116     while (offset + kEventSize <= mSize) {
    117         int64_t atomicCounter = *reinterpret_cast<uint32_t *>(mBuffer + offset + kOffsetAtomicCounter);
    118         if (atomicCounter <= lastCounter) {
    119             break;
    120         }
    121 
    122         int32_t size = *reinterpret_cast<int32_t *>(mBuffer + offset + kOffsetSize);
    123         if (size != kEventSize) {
    124             // unknown error, events parsed may be wrong, remove all
    125             events.clear();
    126             break;
    127         }
    128 
    129         events.push_back(*reinterpret_cast<ASensorEvent *>(mBuffer + offset));
    130         lastCounter = atomicCounter;
    131         offset += kEventSize;
    132     }
    133 
    134     return events;
    135 }
    136 
    137 TestSharedMemory::TestSharedMemory(int type, size_t size)
    138         : mType(type), mSize(0), mBuffer(nullptr),
    139             mSharedMemoryFd(-1), mHardwareBuffer(nullptr) {
    140     bool success = false;
    141     switch(type) {
    142         case ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY: {
    143             mSharedMemoryFd = ASharedMemory_create("TestSharedMemory", size);
    144             if (mSharedMemoryFd < 0
    145                     || ASharedMemory_getSize(mSharedMemoryFd) != size) {
    146                 break;
    147             }
    148 
    149             mSize = size;
    150             mBuffer = reinterpret_cast<char *>(::mmap(
    151                     nullptr, mSize, PROT_READ | PROT_WRITE,
    152                     MAP_SHARED, mSharedMemoryFd, 0));
    153 
    154             if (mBuffer == MAP_FAILED) {
    155                 mBuffer = nullptr;
    156                 break;
    157             }
    158             success = true;
    159             break;
    160         }
    161         case ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER: {
    162             AHardwareBuffer_Desc desc = {
    163                 .width = static_cast<uint32_t>(size),
    164                 .height = 1,
    165                 .layers = 1,
    166                 .usage = AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA
    167                          | AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
    168                 .format = AHARDWAREBUFFER_FORMAT_BLOB
    169             };
    170 
    171             // allocate
    172             if (AHardwareBuffer_allocate(&desc, &mHardwareBuffer) == 0) {
    173                 // lock
    174                 if (AHardwareBuffer_lock(mHardwareBuffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY,
    175                                          -1, nullptr, reinterpret_cast<void **>(&mBuffer)) == 0) {
    176                     if (mBuffer != nullptr) {
    177                         mSize = size;
    178                         success = true;
    179                     }
    180                 }
    181             }
    182             break;
    183         }
    184         default:
    185             break;
    186     }
    187 
    188     if (!success) {
    189         release();
    190     }
    191 }
    192 
    193 TestSharedMemory::~TestSharedMemory() {
    194     release();
    195 }
    196 
    197 void TestSharedMemory::release() {
    198     switch(mType) {
    199         case ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY: {
    200             if (mBuffer != nullptr) {
    201                 ::munmap(mBuffer, mSize);
    202                 mBuffer = nullptr;
    203             }
    204             if (mSharedMemoryFd > 0) {
    205                 ::close(mSharedMemoryFd);
    206                 mSharedMemoryFd = -1;
    207             }
    208             mSize = 0;
    209             break;
    210         }
    211         case ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER: {
    212             if (mHardwareBuffer != nullptr) {
    213                 if (mBuffer != nullptr) {
    214                     int32_t fence = -1;
    215                     AHardwareBuffer_unlock(mHardwareBuffer, &fence);
    216                     mBuffer = nullptr;
    217                 }
    218                 AHardwareBuffer_release(mHardwareBuffer);
    219                 mHardwareBuffer = nullptr;
    220             }
    221             mSize = 0;
    222             break;
    223         }
    224         default:
    225             break;
    226     }
    227     if (mSharedMemoryFd > 0 || mSize != 0 || mBuffer != nullptr || mHardwareBuffer != nullptr) {
    228         ALOGE("TestSharedMemory %p not properly destructed: "
    229               "type %d, shared_memory_fd %d, hardware_buffer %p, size %zu, buffer %p",
    230               this, static_cast<int>(mType), mSharedMemoryFd, mHardwareBuffer, mSize, mBuffer);
    231     }
    232 }
    233 
    234 TestSharedMemory* TestSharedMemory::create(int type, size_t size) {
    235     constexpr size_t kMaxSize = 128*1024*1024; // sensor test should not need more than 128M
    236     if (size == 0 || size >= kMaxSize) {
    237         return nullptr;
    238     }
    239 
    240     auto m = new TestSharedMemory(type, size);
    241     if (m->mSize != size || m->mBuffer == nullptr) {
    242         delete m;
    243         m = nullptr;
    244     }
    245     return m;
    246 }
    247 } // namespace SensorTest
    248 } // namespace android
    249