• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SensorDirectConnection(const sp<SensorService> & service,uid_t uid,const sensors_direct_mem_t * mem,int32_t halChannelHandle,const String16 & opPackageName)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) {
31     ALOGD_IF(DEBUG_CONNECTIONS, "Created SensorDirectConnection");
32 }
33 
~SensorDirectConnection()34 SensorService::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 
onFirstRef()45 void SensorService::SensorDirectConnection::onFirstRef() {
46 }
47 
dump(String8 & result) const48 void 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 
getSensorChannel() const57 sp<BitTube> SensorService::SensorDirectConnection::getSensorChannel() const {
58     return nullptr;
59 }
60 
enableDisable(int handle,bool enabled,nsecs_t samplingPeriodNs,nsecs_t maxBatchReportLatencyNs,int reservedFlags)61 status_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 
setEventRate(int handle,nsecs_t samplingPeriodNs)73 status_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 
flush()81 status_t SensorService::SensorDirectConnection::flush() {
82     // SensorDirectConnection does not support flush
83     return INVALID_OPERATION;
84 }
85 
configureChannel(int handle,int rateLevel)86 int32_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 
stopAll(bool backupRecord)136 void 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 
recoverAll()154 void 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 
getHalChannelHandle() const173 int32_t SensorService::SensorDirectConnection::getHalChannelHandle() const {
174     return mHalChannelHandle;
175 }
176 
isEquivalent(const sensors_direct_mem_t * mem) const177 bool 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: {
183                 // 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);
189                 break;
190             }
191             case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
192                 // there is no known method to test if two gralloc handle are equivalent
193                 ret = false;
194                 break;
195             default:
196                 // should never happen
197                 ALOGE("Unexpected mem type %d", mMem.type);
198                 ret = true;
199                 break;
200         }
201     }
202     return ret;
203 }
204 
205 } // namespace android
206 
207