Home | History | Annotate | Download | only in sensorservice
      1 /*
      2  * Copyright (C) 2016 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 "SensorDevice.h"
     18 #include "SensorDirectConnection.h"
     19 #include <hardware/sensors.h>
     20 
     21 #define UNUSED(x) (void)(x)
     22 
     23 namespace android {
     24 
     25 SensorService::SensorDirectConnection::SensorDirectConnection(const sp<SensorService>& service,
     26         uid_t uid, const sensors_direct_mem_t *mem, int32_t halChannelHandle,
     27         const String16& opPackageName)
     28         : mService(service), mUid(uid), mMem(*mem),
     29         mHalChannelHandle(halChannelHandle),
     30         mOpPackageName(opPackageName), mDestroyed(false) {
     31     ALOGD_IF(DEBUG_CONNECTIONS, "Created SensorDirectConnection");
     32 }
     33 
     34 SensorService::SensorDirectConnection::~SensorDirectConnection() {
     35     ALOGD_IF(DEBUG_CONNECTIONS, "~SensorDirectConnection %p", this);
     36     destroy();
     37 }
     38 
     39 void SensorService::SensorDirectConnection::destroy() {
     40     Mutex::Autolock _l(mDestroyLock);
     41     // destroy once only
     42     if (mDestroyed) {
     43         return;
     44     }
     45 
     46     stopAll();
     47     mService->cleanupConnection(this);
     48     if (mMem.handle != nullptr) {
     49         native_handle_close(mMem.handle);
     50         native_handle_delete(const_cast<struct native_handle*>(mMem.handle));
     51     }
     52     mDestroyed = true;
     53 }
     54 
     55 void SensorService::SensorDirectConnection::onFirstRef() {
     56 }
     57 
     58 void SensorService::SensorDirectConnection::dump(String8& result) const {
     59     Mutex::Autolock _l(mConnectionLock);
     60     result.appendFormat("\tPackage %s, HAL channel handle %d, total sensor activated %zu\n",
     61             String8(mOpPackageName).string(), getHalChannelHandle(), mActivated.size());
     62     for (auto &i : mActivated) {
     63         result.appendFormat("\t\tSensor %#08x, rate %d\n", i.first, i.second);
     64     }
     65 }
     66 
     67 sp<BitTube> SensorService::SensorDirectConnection::getSensorChannel() const {
     68     return nullptr;
     69 }
     70 
     71 status_t SensorService::SensorDirectConnection::enableDisable(
     72         int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
     73         int reservedFlags) {
     74     // SensorDirectConnection does not support enableDisable, parameters not used
     75     UNUSED(handle);
     76     UNUSED(enabled);
     77     UNUSED(samplingPeriodNs);
     78     UNUSED(maxBatchReportLatencyNs);
     79     UNUSED(reservedFlags);
     80     return INVALID_OPERATION;
     81 }
     82 
     83 status_t SensorService::SensorDirectConnection::setEventRate(
     84         int handle, nsecs_t samplingPeriodNs) {
     85     // SensorDirectConnection does not support setEventRate, parameters not used
     86     UNUSED(handle);
     87     UNUSED(samplingPeriodNs);
     88     return INVALID_OPERATION;
     89 }
     90 
     91 status_t SensorService::SensorDirectConnection::flush() {
     92     // SensorDirectConnection does not support flush
     93     return INVALID_OPERATION;
     94 }
     95 
     96 int32_t SensorService::SensorDirectConnection::configureChannel(int handle, int rateLevel) {
     97 
     98     if (handle == -1 && rateLevel == SENSOR_DIRECT_RATE_STOP) {
     99         stopAll();
    100         return NO_ERROR;
    101     }
    102 
    103     if (mService->isOperationRestricted(mOpPackageName)) {
    104         return PERMISSION_DENIED;
    105     }
    106 
    107     sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
    108     if (si == nullptr) {
    109         return NAME_NOT_FOUND;
    110     }
    111 
    112     const Sensor& s = si->getSensor();
    113     if (!SensorService::canAccessSensor(s, "config direct channel", mOpPackageName)) {
    114         return PERMISSION_DENIED;
    115     }
    116 
    117     if (s.getHighestDirectReportRateLevel() == 0
    118             || rateLevel > s.getHighestDirectReportRateLevel()
    119             || !s.isDirectChannelTypeSupported(mMem.type)) {
    120         return INVALID_OPERATION;
    121     }
    122 
    123     struct sensors_direct_cfg_t config = {
    124         .rate_level = rateLevel
    125     };
    126 
    127     Mutex::Autolock _l(mConnectionLock);
    128     SensorDevice& dev(SensorDevice::getInstance());
    129     int ret = dev.configureDirectChannel(handle, getHalChannelHandle(), &config);
    130 
    131     if (rateLevel == SENSOR_DIRECT_RATE_STOP) {
    132         if (ret == NO_ERROR) {
    133             mActivated.erase(handle);
    134         } else if (ret > 0) {
    135             ret = UNKNOWN_ERROR;
    136         }
    137     } else {
    138         if (ret > 0) {
    139             mActivated[handle] = rateLevel;
    140         }
    141     }
    142 
    143     return ret;
    144 }
    145 
    146 void SensorService::SensorDirectConnection::stopAll(bool backupRecord) {
    147 
    148     struct sensors_direct_cfg_t config = {
    149         .rate_level = SENSOR_DIRECT_RATE_STOP
    150     };
    151 
    152     Mutex::Autolock _l(mConnectionLock);
    153     SensorDevice& dev(SensorDevice::getInstance());
    154     for (auto &i : mActivated) {
    155         dev.configureDirectChannel(i.first, getHalChannelHandle(), &config);
    156     }
    157 
    158     if (backupRecord && mActivatedBackup.empty()) {
    159         mActivatedBackup = mActivated;
    160     }
    161     mActivated.clear();
    162 }
    163 
    164 void SensorService::SensorDirectConnection::recoverAll() {
    165     stopAll(false);
    166 
    167     Mutex::Autolock _l(mConnectionLock);
    168     SensorDevice& dev(SensorDevice::getInstance());
    169 
    170     // recover list of report from backup
    171     mActivated = mActivatedBackup;
    172     mActivatedBackup.clear();
    173 
    174     // re-enable them
    175     for (auto &i : mActivated) {
    176         struct sensors_direct_cfg_t config = {
    177             .rate_level = i.second
    178         };
    179         dev.configureDirectChannel(i.first, getHalChannelHandle(), &config);
    180     }
    181 }
    182 
    183 int32_t SensorService::SensorDirectConnection::getHalChannelHandle() const {
    184     return mHalChannelHandle;
    185 }
    186 
    187 bool SensorService::SensorDirectConnection::isEquivalent(const sensors_direct_mem_t *mem) const {
    188     bool ret = false;
    189 
    190     if (mMem.type == mem->type) {
    191         switch (mMem.type) {
    192             case SENSOR_DIRECT_MEM_TYPE_ASHMEM: {
    193                 // there is no known method to test if two ashmem fds are equivalent besides
    194                 // trivially comparing the fd values (ino number from fstat() are always the
    195                 // same, pointing to "/dev/ashmem").
    196                 int fd1 = mMem.handle->data[0];
    197                 int fd2 = mem->handle->data[0];
    198                 ret = (fd1 == fd2);
    199                 break;
    200             }
    201             case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
    202                 // there is no known method to test if two gralloc handle are equivalent
    203                 ret = false;
    204                 break;
    205             default:
    206                 // should never happen
    207                 ALOGE("Unexpected mem type %d", mMem.type);
    208                 ret = true;
    209                 break;
    210         }
    211     }
    212     return ret;
    213 }
    214 
    215 } // namespace android
    216 
    217