| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2010 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 |  | 
| Mathias Agopian | a7352c9 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 17 | #define LOG_TAG "Sensors" | 
 | 18 |  | 
| Mathias Agopian | 801ea09 | 2017-03-06 15:05:04 -0800 | [diff] [blame] | 19 | #include <sensor/SensorManager.h> | 
 | 20 |  | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 21 | #include <stdint.h> | 
 | 22 | #include <sys/types.h> | 
 | 23 |  | 
| Peng Xu | e36e347 | 2016-11-03 11:57:10 -0700 | [diff] [blame] | 24 | #include <cutils/native_handle.h> | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 25 | #include <utils/Errors.h> | 
 | 26 | #include <utils/RefBase.h> | 
 | 27 | #include <utils/Singleton.h> | 
 | 28 |  | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 29 | #include <binder/IBinder.h> | 
| Mathias Agopian | a7352c9 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 30 | #include <binder/IServiceManager.h> | 
 | 31 |  | 
| Mathias Agopian | 801ea09 | 2017-03-06 15:05:04 -0800 | [diff] [blame] | 32 | #include <sensor/ISensorServer.h> | 
 | 33 | #include <sensor/ISensorEventConnection.h> | 
 | 34 | #include <sensor/Sensor.h> | 
 | 35 | #include <sensor/SensorEventQueue.h> | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 36 |  | 
 | 37 | // ---------------------------------------------------------------------------- | 
 | 38 | namespace android { | 
 | 39 | // ---------------------------------------------------------------------------- | 
 | 40 |  | 
| Peng Xu | fe5476a | 2017-03-17 17:27:42 -0700 | [diff] [blame] | 41 | Mutex SensorManager::sLock; | 
 | 42 | std::map<String16, SensorManager*> SensorManager::sPackageInstances; | 
| Aravind Akella | e2806cb | 2015-07-29 18:03:48 -0700 | [diff] [blame] | 43 |  | 
 | 44 | SensorManager& SensorManager::getInstanceForPackage(const String16& packageName) { | 
| Peng Xu | fe5476a | 2017-03-17 17:27:42 -0700 | [diff] [blame] | 45 |     waitForSensorService(nullptr); | 
 | 46 |  | 
| Aravind Akella | e2806cb | 2015-07-29 18:03:48 -0700 | [diff] [blame] | 47 |     Mutex::Autolock _l(sLock); | 
 | 48 |     SensorManager* sensorManager; | 
| Peng Xu | fe5476a | 2017-03-17 17:27:42 -0700 | [diff] [blame] | 49 |     auto iterator = sPackageInstances.find(packageName); | 
| Aravind Akella | e2806cb | 2015-07-29 18:03:48 -0700 | [diff] [blame] | 50 |  | 
 | 51 |     if (iterator != sPackageInstances.end()) { | 
 | 52 |         sensorManager = iterator->second; | 
 | 53 |     } else { | 
 | 54 |         String16 opPackageName = packageName; | 
 | 55 |  | 
 | 56 |         // It is possible that the calling code has no access to the package name. | 
 | 57 |         // In this case we will get the packages for the calling UID and pick the | 
 | 58 |         // first one for attributing the app op. This will work correctly for | 
 | 59 |         // runtime permissions as for legacy apps we will toggle the app op for | 
 | 60 |         // all packages in the UID. The caveat is that the operation may be attributed | 
 | 61 |         // to the wrong package and stats based on app ops may be slightly off. | 
 | 62 |         if (opPackageName.size() <= 0) { | 
 | 63 |             sp<IBinder> binder = defaultServiceManager()->getService(String16("permission")); | 
 | 64 |             if (binder != 0) { | 
 | 65 |                 const uid_t uid = IPCThreadState::self()->getCallingUid(); | 
 | 66 |                 Vector<String16> packages; | 
 | 67 |                 interface_cast<IPermissionController>(binder)->getPackagesForUid(uid, packages); | 
 | 68 |                 if (!packages.isEmpty()) { | 
 | 69 |                     opPackageName = packages[0]; | 
 | 70 |                 } else { | 
 | 71 |                     ALOGE("No packages for calling UID"); | 
 | 72 |                 } | 
 | 73 |             } else { | 
 | 74 |                 ALOGE("Cannot get permission service"); | 
 | 75 |             } | 
 | 76 |         } | 
 | 77 |  | 
 | 78 |         sensorManager = new SensorManager(opPackageName); | 
 | 79 |  | 
 | 80 |         // If we had no package name, we looked it up from the UID and the sensor | 
 | 81 |         // manager instance we created should also be mapped to the empty package | 
 | 82 |         // name, to avoid looking up the packages for a UID and get the same result. | 
 | 83 |         if (packageName.size() <= 0) { | 
 | 84 |             sPackageInstances.insert(std::make_pair(String16(), sensorManager)); | 
 | 85 |         } | 
 | 86 |  | 
 | 87 |         // Stash the per package sensor manager. | 
 | 88 |         sPackageInstances.insert(std::make_pair(opPackageName, sensorManager)); | 
 | 89 |     } | 
 | 90 |  | 
 | 91 |     return *sensorManager; | 
 | 92 | } | 
 | 93 |  | 
| Svetoslav | b412f6e | 2015-04-29 16:50:41 -0700 | [diff] [blame] | 94 | SensorManager::SensorManager(const String16& opPackageName) | 
| Peng Xu | e36e347 | 2016-11-03 11:57:10 -0700 | [diff] [blame] | 95 |     : mSensorList(0), mOpPackageName(opPackageName), mDirectConnectionHandle(1) { | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 96 |     // okay we're not locked here, but it's not needed during construction | 
 | 97 |     assertStateLocked(); | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 98 | } | 
 | 99 |  | 
| Peng Xu | 2576cb6 | 2016-01-20 00:22:09 -0800 | [diff] [blame] | 100 | SensorManager::~SensorManager() { | 
| Mathias Agopian | a7352c9 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 101 |     free(mSensorList); | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 102 | } | 
 | 103 |  | 
| Peng Xu | fe5476a | 2017-03-17 17:27:42 -0700 | [diff] [blame] | 104 | status_t SensorManager::waitForSensorService(sp<ISensorServer> *server) { | 
 | 105 |     // try for 300 seconds (60*5(getService() tries for 5 seconds)) before giving up ... | 
 | 106 |     sp<ISensorServer> s; | 
 | 107 |     const String16 name("sensorservice"); | 
 | 108 |     for (int i = 0; i < 60; i++) { | 
 | 109 |         status_t err = getService(name, &s); | 
 | 110 |         switch (err) { | 
 | 111 |             case NAME_NOT_FOUND: | 
 | 112 |                 sleep(1); | 
 | 113 |                 continue; | 
 | 114 |             case NO_ERROR: | 
 | 115 |                 if (server != nullptr) { | 
 | 116 |                     *server = s; | 
 | 117 |                 } | 
 | 118 |                 return NO_ERROR; | 
 | 119 |             default: | 
 | 120 |                 return err; | 
 | 121 |         } | 
 | 122 |     } | 
 | 123 |     return TIMED_OUT; | 
 | 124 | } | 
 | 125 |  | 
| Peng Xu | 2576cb6 | 2016-01-20 00:22:09 -0800 | [diff] [blame] | 126 | void SensorManager::sensorManagerDied() { | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 127 |     Mutex::Autolock _l(mLock); | 
 | 128 |     mSensorServer.clear(); | 
 | 129 |     free(mSensorList); | 
 | 130 |     mSensorList = NULL; | 
 | 131 |     mSensors.clear(); | 
 | 132 | } | 
 | 133 |  | 
| Peng Xu | 2576cb6 | 2016-01-20 00:22:09 -0800 | [diff] [blame] | 134 | status_t SensorManager::assertStateLocked() { | 
| Aravind Akella | 8f35ca9 | 2015-08-17 15:22:12 -0700 | [diff] [blame] | 135 |     bool initSensorManager = false; | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 136 |     if (mSensorServer == NULL) { | 
| Aravind Akella | 8f35ca9 | 2015-08-17 15:22:12 -0700 | [diff] [blame] | 137 |         initSensorManager = true; | 
 | 138 |     } else { | 
 | 139 |         // Ping binder to check if sensorservice is alive. | 
 | 140 |         status_t err = IInterface::asBinder(mSensorServer)->pingBinder(); | 
 | 141 |         if (err != NO_ERROR) { | 
 | 142 |             initSensorManager = true; | 
 | 143 |         } | 
 | 144 |     } | 
 | 145 |     if (initSensorManager) { | 
| Peng Xu | fe5476a | 2017-03-17 17:27:42 -0700 | [diff] [blame] | 146 |         waitForSensorService(&mSensorServer); | 
 | 147 |         LOG_ALWAYS_FATAL_IF(mSensorServer == nullptr, "getService(SensorService) NULL"); | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 148 |  | 
 | 149 |         class DeathObserver : public IBinder::DeathRecipient { | 
| Peng Xu | 2576cb6 | 2016-01-20 00:22:09 -0800 | [diff] [blame] | 150 |             SensorManager& mSensorManager; | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 151 |             virtual void binderDied(const wp<IBinder>& who) { | 
| Steve Block | 32397c1 | 2012-01-05 23:22:43 +0000 | [diff] [blame] | 152 |                 ALOGW("sensorservice died [%p]", who.unsafe_get()); | 
| Peng Xu | 2576cb6 | 2016-01-20 00:22:09 -0800 | [diff] [blame] | 153 |                 mSensorManager.sensorManagerDied(); | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 154 |             } | 
 | 155 |         public: | 
| Chih-Hung Hsieh | 68a593e | 2016-04-28 09:14:32 -0700 | [diff] [blame] | 156 |             explicit DeathObserver(SensorManager& mgr) : mSensorManager(mgr) { } | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 157 |         }; | 
 | 158 |  | 
 | 159 |         mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this)); | 
| Marco Nelissen | 2ea926b | 2014-11-14 08:01:01 -0800 | [diff] [blame] | 160 |         IInterface::asBinder(mSensorServer)->linkToDeath(mDeathObserver); | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 161 |  | 
| Svetoslav | b412f6e | 2015-04-29 16:50:41 -0700 | [diff] [blame] | 162 |         mSensors = mSensorServer->getSensorList(mOpPackageName); | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 163 |         size_t count = mSensors.size(); | 
| Dan Stoza | d723bd7 | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 164 |         mSensorList = | 
 | 165 |                 static_cast<Sensor const**>(malloc(count * sizeof(Sensor*))); | 
| Aravind Akella | 8f35ca9 | 2015-08-17 15:22:12 -0700 | [diff] [blame] | 166 |         LOG_ALWAYS_FATAL_IF(mSensorList == NULL, "mSensorList NULL"); | 
 | 167 |  | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 168 |         for (size_t i=0 ; i<count ; i++) { | 
 | 169 |             mSensorList[i] = mSensors.array() + i; | 
 | 170 |         } | 
 | 171 |     } | 
 | 172 |  | 
 | 173 |     return NO_ERROR; | 
 | 174 | } | 
 | 175 |  | 
| Peng Xu | 2576cb6 | 2016-01-20 00:22:09 -0800 | [diff] [blame] | 176 | ssize_t SensorManager::getSensorList(Sensor const* const** list) { | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 177 |     Mutex::Autolock _l(mLock); | 
 | 178 |     status_t err = assertStateLocked(); | 
 | 179 |     if (err < 0) { | 
| Dan Stoza | d723bd7 | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 180 |         return static_cast<ssize_t>(err); | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 181 |     } | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 182 |     *list = mSensorList; | 
| Dan Stoza | d723bd7 | 2014-11-18 10:24:03 -0800 | [diff] [blame] | 183 |     return static_cast<ssize_t>(mSensors.size()); | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 184 | } | 
 | 185 |  | 
| Peng Xu | 2576cb6 | 2016-01-20 00:22:09 -0800 | [diff] [blame] | 186 | ssize_t SensorManager::getDynamicSensorList(Vector<Sensor> & dynamicSensors) { | 
 | 187 |     Mutex::Autolock _l(mLock); | 
 | 188 |     status_t err = assertStateLocked(); | 
 | 189 |     if (err < 0) { | 
 | 190 |         return static_cast<ssize_t>(err); | 
 | 191 |     } | 
 | 192 |  | 
 | 193 |     dynamicSensors = mSensorServer->getDynamicSensorList(mOpPackageName); | 
 | 194 |     size_t count = dynamicSensors.size(); | 
 | 195 |  | 
 | 196 |     return static_cast<ssize_t>(count); | 
 | 197 | } | 
 | 198 |  | 
| Mathias Agopian | a7352c9 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 199 | Sensor const* SensorManager::getDefaultSensor(int type) | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 200 | { | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 201 |     Mutex::Autolock _l(mLock); | 
 | 202 |     if (assertStateLocked() == NO_ERROR) { | 
| Aravind Akella | b37ba39 | 2014-08-05 14:53:07 -0700 | [diff] [blame] | 203 |         bool wakeUpSensor = false; | 
 | 204 |         // For the following sensor types, return a wake-up sensor. These types are by default | 
 | 205 |         // defined as wake-up sensors. For the rest of the sensor types defined in sensors.h return | 
 | 206 |         // a non_wake-up version. | 
 | 207 |         if (type == SENSOR_TYPE_PROXIMITY || type == SENSOR_TYPE_SIGNIFICANT_MOTION || | 
 | 208 |             type == SENSOR_TYPE_TILT_DETECTOR || type == SENSOR_TYPE_WAKE_GESTURE || | 
| Nick Vaccaro | 5e7f79b | 2016-10-17 15:40:51 -0700 | [diff] [blame] | 209 |             type == SENSOR_TYPE_GLANCE_GESTURE || type == SENSOR_TYPE_PICK_UP_GESTURE || | 
| Nick Vaccaro | 2e990eb | 2017-01-12 21:13:58 -0800 | [diff] [blame] | 210 |             type == SENSOR_TYPE_WRIST_TILT_GESTURE || | 
 | 211 |             type == SENSOR_TYPE_LOW_LATENCY_OFFBODY_DETECT) { | 
| Aravind Akella | b37ba39 | 2014-08-05 14:53:07 -0700 | [diff] [blame] | 212 |             wakeUpSensor = true; | 
 | 213 |         } | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 214 |         // For now we just return the first sensor of that type we find. | 
 | 215 |         // in the future it will make sense to let the SensorService make | 
 | 216 |         // that decision. | 
 | 217 |         for (size_t i=0 ; i<mSensors.size() ; i++) { | 
| Aravind Akella | b37ba39 | 2014-08-05 14:53:07 -0700 | [diff] [blame] | 218 |             if (mSensorList[i]->getType() == type && | 
 | 219 |                 mSensorList[i]->isWakeUpSensor() == wakeUpSensor) { | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 220 |                 return mSensorList[i]; | 
| Aravind Akella | b37ba39 | 2014-08-05 14:53:07 -0700 | [diff] [blame] | 221 |             } | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 222 |         } | 
| Mathias Agopian | a7352c9 | 2010-07-14 23:41:37 -0700 | [diff] [blame] | 223 |     } | 
 | 224 |     return NULL; | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 225 | } | 
 | 226 |  | 
| Aravind Akella | a9e6cc3 | 2015-04-16 18:57:31 -0700 | [diff] [blame] | 227 | sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName, int mode) { | 
| Mathias Agopian | be58de0 | 2011-10-16 00:38:30 -0700 | [diff] [blame] | 228 |     sp<SensorEventQueue> queue; | 
 | 229 |  | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 230 |     Mutex::Autolock _l(mLock); | 
 | 231 |     while (assertStateLocked() == NO_ERROR) { | 
 | 232 |         sp<ISensorEventConnection> connection = | 
| Svetoslav | b412f6e | 2015-04-29 16:50:41 -0700 | [diff] [blame] | 233 |                 mSensorServer->createSensorEventConnection(packageName, mode, mOpPackageName); | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 234 |         if (connection == NULL) { | 
| Aravind Akella | a9e6cc3 | 2015-04-16 18:57:31 -0700 | [diff] [blame] | 235 |             // SensorService just died or the app doesn't have required permissions. | 
 | 236 |             ALOGE("createEventQueue: connection is NULL."); | 
 | 237 |             return NULL; | 
| Mathias Agopian | 1a2b83a | 2011-10-16 22:15:23 -0700 | [diff] [blame] | 238 |         } | 
 | 239 |         queue = new SensorEventQueue(connection); | 
 | 240 |         break; | 
| Mathias Agopian | be58de0 | 2011-10-16 00:38:30 -0700 | [diff] [blame] | 241 |     } | 
| Mathias Agopian | be58de0 | 2011-10-16 00:38:30 -0700 | [diff] [blame] | 242 |     return queue; | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 243 | } | 
 | 244 |  | 
| Aravind Akella | 841a592 | 2015-06-29 12:37:48 -0700 | [diff] [blame] | 245 | bool SensorManager::isDataInjectionEnabled() { | 
| Aravind Akella | a9e6cc3 | 2015-04-16 18:57:31 -0700 | [diff] [blame] | 246 |     Mutex::Autolock _l(mLock); | 
 | 247 |     if (assertStateLocked() == NO_ERROR) { | 
| Aravind Akella | 841a592 | 2015-06-29 12:37:48 -0700 | [diff] [blame] | 248 |         return mSensorServer->isDataInjectionEnabled(); | 
| Aravind Akella | a9e6cc3 | 2015-04-16 18:57:31 -0700 | [diff] [blame] | 249 |     } | 
| Aravind Akella | 841a592 | 2015-06-29 12:37:48 -0700 | [diff] [blame] | 250 |     return false; | 
| Aravind Akella | a9e6cc3 | 2015-04-16 18:57:31 -0700 | [diff] [blame] | 251 | } | 
 | 252 |  | 
| Peng Xu | e36e347 | 2016-11-03 11:57:10 -0700 | [diff] [blame] | 253 | int SensorManager::createDirectChannel( | 
 | 254 |         size_t size, int channelType, const native_handle_t *resourceHandle) { | 
 | 255 |     Mutex::Autolock _l(mLock); | 
 | 256 |     if (assertStateLocked() != NO_ERROR) { | 
 | 257 |         return NO_INIT; | 
 | 258 |     } | 
 | 259 |  | 
| Peng Xu | d9c8a86 | 2017-03-05 01:48:11 -0800 | [diff] [blame] | 260 |     if (channelType != SENSOR_DIRECT_MEM_TYPE_ASHMEM | 
 | 261 |             && channelType != SENSOR_DIRECT_MEM_TYPE_GRALLOC) { | 
 | 262 |         ALOGE("Bad channel shared memory type %d", channelType); | 
 | 263 |         return BAD_VALUE; | 
| Peng Xu | e36e347 | 2016-11-03 11:57:10 -0700 | [diff] [blame] | 264 |     } | 
| Peng Xu | d9c8a86 | 2017-03-05 01:48:11 -0800 | [diff] [blame] | 265 |  | 
 | 266 |     sp<ISensorEventConnection> conn = | 
 | 267 |               mSensorServer->createSensorDirectConnection(mOpPackageName, | 
 | 268 |                   static_cast<uint32_t>(size), | 
 | 269 |                   static_cast<int32_t>(channelType), | 
 | 270 |                   SENSOR_DIRECT_FMT_SENSORS_EVENT, resourceHandle); | 
 | 271 |     if (conn == nullptr) { | 
 | 272 |         return NO_MEMORY; | 
 | 273 |     } | 
 | 274 |  | 
 | 275 |     int nativeHandle = mDirectConnectionHandle++; | 
 | 276 |     mDirectConnection.emplace(nativeHandle, conn); | 
 | 277 |     return nativeHandle; | 
| Peng Xu | e36e347 | 2016-11-03 11:57:10 -0700 | [diff] [blame] | 278 | } | 
 | 279 |  | 
 | 280 | void SensorManager::destroyDirectChannel(int channelNativeHandle) { | 
 | 281 |     Mutex::Autolock _l(mLock); | 
 | 282 |     if (assertStateLocked() == NO_ERROR) { | 
 | 283 |         mDirectConnection.erase(channelNativeHandle); | 
 | 284 |     } | 
 | 285 | } | 
 | 286 |  | 
 | 287 | int SensorManager::configureDirectChannel(int channelNativeHandle, int sensorHandle, int rateLevel) { | 
 | 288 |     Mutex::Autolock _l(mLock); | 
 | 289 |     if (assertStateLocked() != NO_ERROR) { | 
 | 290 |         return NO_INIT; | 
 | 291 |     } | 
 | 292 |  | 
 | 293 |     auto i = mDirectConnection.find(channelNativeHandle); | 
 | 294 |     if (i == mDirectConnection.end()) { | 
 | 295 |         ALOGE("Cannot find the handle in client direct connection table"); | 
 | 296 |         return BAD_VALUE; | 
 | 297 |     } | 
 | 298 |  | 
 | 299 |     int ret; | 
 | 300 |     ret = i->second->configureChannel(sensorHandle, rateLevel); | 
 | 301 |     ALOGE_IF(ret < 0, "SensorManager::configureChannel (%d, %d) returns %d", | 
 | 302 |             static_cast<int>(sensorHandle), static_cast<int>(rateLevel), | 
 | 303 |             static_cast<int>(ret)); | 
 | 304 |     return ret; | 
 | 305 | } | 
 | 306 |  | 
| Peng Xu | dd5c5cb | 2017-03-16 17:39:43 -0700 | [diff] [blame] | 307 | int SensorManager::setOperationParameter( | 
 | 308 |         int type, const Vector<float> &floats, const Vector<int32_t> &ints) { | 
 | 309 |     Mutex::Autolock _l(mLock); | 
 | 310 |     if (assertStateLocked() != NO_ERROR) { | 
 | 311 |         return NO_INIT; | 
 | 312 |     } | 
 | 313 |     return mSensorServer->setOperationParameter(type, floats, ints); | 
 | 314 | } | 
 | 315 |  | 
| Mathias Agopian | 589ce85 | 2010-07-13 22:21:56 -0700 | [diff] [blame] | 316 | // ---------------------------------------------------------------------------- | 
 | 317 | }; // namespace android |