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