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