diff options
Diffstat (limited to 'modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp')
-rw-r--r-- | modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp new file mode 100644 index 00000000..19779678 --- /dev/null +++ b/modules/sensors/dynamic_sensor/DummyDynamicAccelDaemon.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BaseSensorObject.h" +#include "ConnectionDetector.h" +#include "DummyDynamicAccelDaemon.h" +#include "DynamicSensorManager.h" + +#include <cutils/properties.h> +#include <utils/Log.h> +#include <utils/SystemClock.h> +#include <utils/misc.h> + +#include <sys/socket.h> +#include <netinet/in.h> +#include <algorithm> //std::max + +#define SYSPROP_PREFIX "dynamic_sensor.dummy" +#define FILE_NAME_BASE "dummy_accel_file" +#define FILE_NAME_REGEX ("^" FILE_NAME_BASE "[0-9]$") + +namespace android { +namespace SensorHalExt { + +DummyDynamicAccelDaemon::DummyDynamicAccelDaemon(DynamicSensorManager& manager) + : BaseDynamicSensorDaemon(manager) { + char property[PROPERTY_VALUE_MAX+1]; + + property_get(SYSPROP_PREFIX ".file", property, ""); + if (strcmp(property, "") != 0) { + mFileDetector = new FileConnectionDetector( + this, std::string(property), std::string(FILE_NAME_REGEX)); + } + + property_get(SYSPROP_PREFIX ".socket", property, ""); + if (strcmp(property, "") != 0) { + mSocketDetector = new SocketConnectionDetector(this, atoi(property)); + } +} + +BaseSensorObject * DummyDynamicAccelDaemon::createSensor(const std::string &deviceKey) { + if (deviceKey.compare(0, 1, "/") == 0) { + // file detector result, deviceKey is file absolute path + size_t start = std::max(static_cast<size_t>(0), + deviceKey.length() - (::strlen(FILE_NAME_BASE) + 1)); + return new DummySensor(deviceKey.substr(start)); + + } else if (deviceKey.compare(0, ::strlen("socket:"), "socket:") == 0) { + return new DummySensor(deviceKey); + } else { + // unknown deviceKey + return nullptr; + } +} + +DummyDynamicAccelDaemon::DummySensor::DummySensor(const std::string &name) : mRunState(false) { + mSensorName = "Dummy Accel - " + name; + mSensor = (struct sensor_t) { + mSensorName.c_str(), + "DemoSense, Inc.", + 1, // version + -1, // handle, dummy number here + SENSOR_TYPE_ACCELEROMETER, + 9.8 * 8.0f, // maxRange + 9.8 * 8.0f / 32768.0f, // resolution + 0.5f, // power + (int32_t)(1.0E6f / 50), // minDelay + 0, // fifoReservedEventCount + 0, // fifoMaxEventCount + SENSOR_STRING_TYPE_ACCELEROMETER, + "", // requiredPermission + (long)(1.0E6f / 50), // maxDelay + SENSOR_FLAG_CONTINUOUS_MODE, + { NULL, NULL } + }; + mRunLock.lock(); + run("DummySensor"); +} + +DummyDynamicAccelDaemon::DummySensor::~DummySensor() { + requestExitAndWait(); + // unlock mRunLock so thread can be unblocked + mRunLock.unlock(); +} + +const sensor_t* DummyDynamicAccelDaemon::DummySensor::getSensor() const { + return &mSensor; +} + +void DummyDynamicAccelDaemon::DummySensor::getUuid(uint8_t* uuid) const { + // at maximum, there will be always one instance, so we can hardcode + size_t hash = std::hash<std::string>()(mSensorName); + memset(uuid, 'x', 16); + memcpy(uuid, &hash, sizeof(hash)); +} + +int DummyDynamicAccelDaemon::DummySensor::enable(bool enable) { + std::lock_guard<std::mutex> lk(mLock); + if (mRunState != enable) { + if (enable) { + mRunLock.unlock(); + } else { + mRunLock.lock(); + } + mRunState = enable; + } + return 0; +} + +int DummyDynamicAccelDaemon::DummySensor::batch(nsecs_t, nsecs_t) { + return 0; +} + +void DummyDynamicAccelDaemon::DummySensor::waitUntilNextSample() { + // block when disabled (mRunLock locked) + mRunLock.lock(); + mRunLock.unlock(); + + if (!Thread::exitPending()) { + // sleep 20 ms (50Hz) + usleep(20000); + } +} + +bool DummyDynamicAccelDaemon::DummySensor::threadLoop() { + // designated intialization will leave the unspecified fields zeroed + sensors_event_t event = { + .version = sizeof(event), + .sensor = -1, + .type = SENSOR_TYPE_ACCELEROMETER, + }; + + int64_t startTimeNs = elapsedRealtimeNano(); + + ALOGI("Dynamic Dummy Accel started for sensor %s", mSensorName.c_str()); + while (!Thread::exitPending()) { + waitUntilNextSample(); + + if (Thread::exitPending()) { + break; + } + int64_t nowTimeNs = elapsedRealtimeNano(); + float t = (nowTimeNs - startTimeNs) / 1e9f; + + event.data[0] = 2 * ::sin(3 * M_PI * t); + event.data[1] = 3 * ::cos(3 * M_PI * t); + event.data[2] = 1.5 * ::sin(6 * M_PI * t); + event.timestamp = nowTimeNs; + generateEvent(event); + } + + ALOGI("Dynamic Dummy Accel thread ended for sensor %s", mSensorName.c_str()); + return false; +} + +} // namespace SensorHalExt +} // namespace android + |