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