blob: af86d09784c98db86a6b3930a9742e40be34fc7d [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"
Mike Ma24743862020-01-29 00:36:55 -080019#include <android/util/ProtoOutputStream.h>
20#include <frameworks/base/core/proto/android/service/sensor_service.proto.h>
Peng Xue36e3472016-11-03 11:57:10 -070021#include <hardware/sensors.h>
22
Peng Xue36e3472016-11-03 11:57:10 -070023#define UNUSED(x) (void)(x)
24
25namespace android {
26
Mike Ma24743862020-01-29 00:36:55 -080027using util::ProtoOutputStream;
28
Peng Xue36e3472016-11-03 11:57:10 -070029SensorService::SensorDirectConnection::SensorDirectConnection(const sp<SensorService>& service,
30 uid_t uid, const sensors_direct_mem_t *mem, int32_t halChannelHandle,
31 const String16& opPackageName)
32 : mService(service), mUid(uid), mMem(*mem),
33 mHalChannelHandle(halChannelHandle),
Peng Xu8cbefd72017-07-10 16:41:08 -070034 mOpPackageName(opPackageName), mDestroyed(false) {
Anh Phamaf91a912021-02-10 14:10:53 +010035 mIsRateCappedBasedOnPermission = mService->isRateCappedBasedOnPermission(mOpPackageName);
Anh Pham5198c992021-02-10 14:15:30 +010036 mUserId = multiuser_get_user_id(mUid);
Peng Xue36e3472016-11-03 11:57:10 -070037 ALOGD_IF(DEBUG_CONNECTIONS, "Created SensorDirectConnection");
38}
39
40SensorService::SensorDirectConnection::~SensorDirectConnection() {
41 ALOGD_IF(DEBUG_CONNECTIONS, "~SensorDirectConnection %p", this);
Peng Xu8cbefd72017-07-10 16:41:08 -070042 destroy();
43}
44
45void SensorService::SensorDirectConnection::destroy() {
46 Mutex::Autolock _l(mDestroyLock);
47 // destroy once only
48 if (mDestroyed) {
49 return;
50 }
Peng Xue36e3472016-11-03 11:57:10 -070051
52 stopAll();
53 mService->cleanupConnection(this);
54 if (mMem.handle != nullptr) {
55 native_handle_close(mMem.handle);
56 native_handle_delete(const_cast<struct native_handle*>(mMem.handle));
57 }
Peng Xu8cbefd72017-07-10 16:41:08 -070058 mDestroyed = true;
Peng Xue36e3472016-11-03 11:57:10 -070059}
60
61void SensorService::SensorDirectConnection::onFirstRef() {
62}
63
64void SensorService::SensorDirectConnection::dump(String8& result) const {
65 Mutex::Autolock _l(mConnectionLock);
66 result.appendFormat("\tPackage %s, HAL channel handle %d, total sensor activated %zu\n",
67 String8(mOpPackageName).string(), getHalChannelHandle(), mActivated.size());
68 for (auto &i : mActivated) {
69 result.appendFormat("\t\tSensor %#08x, rate %d\n", i.first, i.second);
70 }
71}
72
Mike Ma24743862020-01-29 00:36:55 -080073/**
74 * Dump debugging information as android.service.SensorDirectConnectionProto protobuf message using
75 * ProtoOutputStream.
76 *
77 * See proto definition and some notes about ProtoOutputStream in
78 * frameworks/base/core/proto/android/service/sensor_service.proto
79 */
80void SensorService::SensorDirectConnection::dump(ProtoOutputStream* proto) const {
81 using namespace service::SensorDirectConnectionProto;
82 Mutex::Autolock _l(mConnectionLock);
83 proto->write(PACKAGE_NAME, std::string(String8(mOpPackageName).string()));
84 proto->write(HAL_CHANNEL_HANDLE, getHalChannelHandle());
85 proto->write(NUM_SENSOR_ACTIVATED, int(mActivated.size()));
86 for (auto &i : mActivated) {
87 uint64_t token = proto->start(SENSORS);
88 proto->write(SensorProto::SENSOR, i.first);
89 proto->write(SensorProto::RATE, i.second);
90 proto->end(token);
91 }
92}
93
Peng Xue36e3472016-11-03 11:57:10 -070094sp<BitTube> SensorService::SensorDirectConnection::getSensorChannel() const {
95 return nullptr;
96}
97
Arthur Ishiguroe3ed3d22020-04-13 10:29:44 -070098void SensorService::SensorDirectConnection::onSensorAccessChanged(bool hasAccess) {
99 if (!hasAccess) {
100 stopAll(true /* backupRecord */);
101 } else {
102 recoverAll();
103 }
104}
105
Anh Pham5198c992021-02-10 14:15:30 +0100106void SensorService::SensorDirectConnection::onMicSensorAccessChanged(bool isMicToggleOn) {
107 if (isMicToggleOn) {
108 capRates();
109 } else {
110 uncapRates();
111 }
112}
113
Arthur Ishiguroe3ed3d22020-04-13 10:29:44 -0700114bool SensorService::SensorDirectConnection::hasSensorAccess() const {
115 return mService->hasSensorAccess(mUid, mOpPackageName);
116}
117
Peng Xue36e3472016-11-03 11:57:10 -0700118status_t SensorService::SensorDirectConnection::enableDisable(
119 int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
120 int reservedFlags) {
121 // SensorDirectConnection does not support enableDisable, parameters not used
122 UNUSED(handle);
123 UNUSED(enabled);
124 UNUSED(samplingPeriodNs);
125 UNUSED(maxBatchReportLatencyNs);
126 UNUSED(reservedFlags);
127 return INVALID_OPERATION;
128}
129
130status_t SensorService::SensorDirectConnection::setEventRate(
131 int handle, nsecs_t samplingPeriodNs) {
132 // SensorDirectConnection does not support setEventRate, parameters not used
133 UNUSED(handle);
134 UNUSED(samplingPeriodNs);
135 return INVALID_OPERATION;
136}
137
138status_t SensorService::SensorDirectConnection::flush() {
139 // SensorDirectConnection does not support flush
140 return INVALID_OPERATION;
141}
142
143int32_t SensorService::SensorDirectConnection::configureChannel(int handle, int rateLevel) {
144
145 if (handle == -1 && rateLevel == SENSOR_DIRECT_RATE_STOP) {
146 stopAll();
Anh Pham5198c992021-02-10 14:15:30 +0100147 mMicRateBackup.clear();
Peng Xue36e3472016-11-03 11:57:10 -0700148 return NO_ERROR;
149 }
150
Arthur Ishiguroe3ed3d22020-04-13 10:29:44 -0700151 if (!hasSensorAccess()) {
Peng Xue36e3472016-11-03 11:57:10 -0700152 return PERMISSION_DENIED;
153 }
154
155 sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
156 if (si == nullptr) {
157 return NAME_NOT_FOUND;
158 }
159
160 const Sensor& s = si->getSensor();
161 if (!SensorService::canAccessSensor(s, "config direct channel", mOpPackageName)) {
162 return PERMISSION_DENIED;
163 }
164
165 if (s.getHighestDirectReportRateLevel() == 0
166 || rateLevel > s.getHighestDirectReportRateLevel()
167 || !s.isDirectChannelTypeSupported(mMem.type)) {
168 return INVALID_OPERATION;
169 }
170
Anh Pham5198c992021-02-10 14:15:30 +0100171 int requestedRateLevel = rateLevel;
Anh Phamaf91a912021-02-10 14:10:53 +0100172 if (mService->isSensorInCappedSet(s.getType()) && rateLevel != SENSOR_DIRECT_RATE_STOP) {
173 status_t err = mService->adjustRateLevelBasedOnMicAndPermission(&rateLevel, mOpPackageName);
174 if (err != OK) {
175 return err;
176 }
177 }
178
Peng Xue36e3472016-11-03 11:57:10 -0700179 struct sensors_direct_cfg_t config = {
180 .rate_level = rateLevel
181 };
182
183 Mutex::Autolock _l(mConnectionLock);
184 SensorDevice& dev(SensorDevice::getInstance());
185 int ret = dev.configureDirectChannel(handle, getHalChannelHandle(), &config);
186
187 if (rateLevel == SENSOR_DIRECT_RATE_STOP) {
188 if (ret == NO_ERROR) {
189 mActivated.erase(handle);
Anh Pham5198c992021-02-10 14:15:30 +0100190 mMicRateBackup.erase(handle);
Peng Xue36e3472016-11-03 11:57:10 -0700191 } else if (ret > 0) {
192 ret = UNKNOWN_ERROR;
193 }
194 } else {
195 if (ret > 0) {
196 mActivated[handle] = rateLevel;
Anh Pham5198c992021-02-10 14:15:30 +0100197 if (mService->isSensorInCappedSet(s.getType())) {
198 // Back up the rates that the app is allowed to have if the mic toggle is off
199 // This is used in the uncapRates() function.
200 if (!mIsRateCappedBasedOnPermission ||
201 requestedRateLevel <= SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL) {
202 mMicRateBackup[handle] = requestedRateLevel;
203 } else {
204 mMicRateBackup[handle] = SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL;
205 }
206 }
Peng Xue36e3472016-11-03 11:57:10 -0700207 }
208 }
209
210 return ret;
211}
212
Anh Pham5198c992021-02-10 14:15:30 +0100213void SensorService::SensorDirectConnection::capRates() {
214 Mutex::Autolock _l(mConnectionLock);
215 const struct sensors_direct_cfg_t capConfig = {
216 .rate_level = SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL
217 };
218
219 const struct sensors_direct_cfg_t stopConfig = {
220 .rate_level = SENSOR_DIRECT_RATE_STOP
221 };
222
223 // If our requests are in the backup, then we shouldn't activate sensors from here
224 bool temporarilyStopped = mActivated.empty() && !mActivatedBackup.empty();
225 std::unordered_map<int, int>& existingConnections =
226 (!temporarilyStopped) ? mActivated : mActivatedBackup;
227
228 SensorDevice& dev(SensorDevice::getInstance());
229 for (auto &i : existingConnections) {
230 int handle = i.first;
231 int rateLevel = i.second;
232 sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
233 if (si != nullptr) {
234 const Sensor& s = si->getSensor();
235 if (mService->isSensorInCappedSet(s.getType()) &&
236 rateLevel > SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL) {
237 mMicRateBackup[handle] = rateLevel;
238 // Modify the rate kept by the existing map
239 existingConnections[handle] = SENSOR_SERVICE_CAPPED_SAMPLING_RATE_LEVEL;
240 // Only reconfigure the channel if it's ongoing
241 if (!temporarilyStopped) {
242 // Stopping before reconfiguring is the well-tested path in CTS
243 dev.configureDirectChannel(handle, getHalChannelHandle(), &stopConfig);
244 dev.configureDirectChannel(handle, getHalChannelHandle(), &capConfig);
245 }
246 }
247 }
248 }
249}
250
251void SensorService::SensorDirectConnection::uncapRates() {
252 Mutex::Autolock _l(mConnectionLock);
253
254 // If our requests are in the backup, then we shouldn't activate sensors from here
255 bool temporarilyStopped = mActivated.empty() && !mActivatedBackup.empty();
256 std::unordered_map<int, int>& existingConnections =
257 (!temporarilyStopped) ? mActivated : mActivatedBackup;
258
259 const struct sensors_direct_cfg_t stopConfig = {
260 .rate_level = SENSOR_DIRECT_RATE_STOP
261 };
262 SensorDevice& dev(SensorDevice::getInstance());
263 for (auto &i : mMicRateBackup) {
264 int handle = i.first;
265 int rateLevel = i.second;
266
267 const struct sensors_direct_cfg_t config = {
268 .rate_level = rateLevel
269 };
270
271 // Modify the rate kept by the existing map
272 existingConnections[handle] = rateLevel;
273
274 // Only reconfigure the channel if it's ongoing
275 if (!temporarilyStopped) {
276 // Stopping before reconfiguring is the well-tested path in CTS
277 dev.configureDirectChannel(handle, getHalChannelHandle(), &stopConfig);
278 dev.configureDirectChannel(handle, getHalChannelHandle(), &config);
279 }
280 }
281 mMicRateBackup.clear();
282}
283
Peng Xue36e3472016-11-03 11:57:10 -0700284void SensorService::SensorDirectConnection::stopAll(bool backupRecord) {
Arthur Ishiguroe3ed3d22020-04-13 10:29:44 -0700285 Mutex::Autolock _l(mConnectionLock);
286 stopAllLocked(backupRecord);
287}
Peng Xue36e3472016-11-03 11:57:10 -0700288
Arthur Ishiguroe3ed3d22020-04-13 10:29:44 -0700289void SensorService::SensorDirectConnection::stopAllLocked(bool backupRecord) {
Peng Xue36e3472016-11-03 11:57:10 -0700290 struct sensors_direct_cfg_t config = {
291 .rate_level = SENSOR_DIRECT_RATE_STOP
292 };
293
Peng Xue36e3472016-11-03 11:57:10 -0700294 SensorDevice& dev(SensorDevice::getInstance());
295 for (auto &i : mActivated) {
296 dev.configureDirectChannel(i.first, getHalChannelHandle(), &config);
297 }
298
299 if (backupRecord && mActivatedBackup.empty()) {
300 mActivatedBackup = mActivated;
301 }
302 mActivated.clear();
303}
304
305void SensorService::SensorDirectConnection::recoverAll() {
Peng Xue36e3472016-11-03 11:57:10 -0700306 Mutex::Autolock _l(mConnectionLock);
Arthur Ishiguroe3ed3d22020-04-13 10:29:44 -0700307 if (!mActivatedBackup.empty()) {
308 stopAllLocked(false);
Peng Xue36e3472016-11-03 11:57:10 -0700309
Arthur Ishiguroe3ed3d22020-04-13 10:29:44 -0700310 SensorDevice& dev(SensorDevice::getInstance());
Peng Xue36e3472016-11-03 11:57:10 -0700311
Arthur Ishiguroe3ed3d22020-04-13 10:29:44 -0700312 // recover list of report from backup
313 ALOG_ASSERT(mActivated.empty(),
314 "mActivated must be empty if mActivatedBackup was non-empty");
315 mActivated = mActivatedBackup;
316 mActivatedBackup.clear();
317
318 // re-enable them
319 for (auto &i : mActivated) {
320 struct sensors_direct_cfg_t config = {
321 .rate_level = i.second
322 };
323 dev.configureDirectChannel(i.first, getHalChannelHandle(), &config);
324 }
Peng Xue36e3472016-11-03 11:57:10 -0700325 }
326}
327
328int32_t SensorService::SensorDirectConnection::getHalChannelHandle() const {
329 return mHalChannelHandle;
330}
331
332bool SensorService::SensorDirectConnection::isEquivalent(const sensors_direct_mem_t *mem) const {
333 bool ret = false;
334
335 if (mMem.type == mem->type) {
336 switch (mMem.type) {
337 case SENSOR_DIRECT_MEM_TYPE_ASHMEM: {
Peng Xu36407732017-05-16 15:12:22 -0700338 // there is no known method to test if two ashmem fds are equivalent besides
339 // trivially comparing the fd values (ino number from fstat() are always the
340 // same, pointing to "/dev/ashmem").
341 int fd1 = mMem.handle->data[0];
342 int fd2 = mem->handle->data[0];
343 ret = (fd1 == fd2);
Peng Xuf149b402017-02-09 12:24:25 -0800344 break;
Peng Xue36e3472016-11-03 11:57:10 -0700345 }
346 case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
Peng Xuf88e2b92017-04-10 15:52:58 -0700347 // there is no known method to test if two gralloc handle are equivalent
348 ret = false;
Peng Xuf149b402017-02-09 12:24:25 -0800349 break;
Peng Xue36e3472016-11-03 11:57:10 -0700350 default:
Peng Xuf88e2b92017-04-10 15:52:58 -0700351 // should never happen
Peng Xue36e3472016-11-03 11:57:10 -0700352 ALOGE("Unexpected mem type %d", mMem.type);
353 ret = true;
Peng Xuf149b402017-02-09 12:24:25 -0800354 break;
Peng Xue36e3472016-11-03 11:57:10 -0700355 }
356 }
357 return ret;
358}
359
360} // namespace android
361