Merge "Direct report mode support in sensor service and client"
diff --git a/include/gui/ISensorEventConnection.h b/include/gui/ISensorEventConnection.h
index 857444b..2ccd832 100644
--- a/include/gui/ISensorEventConnection.h
+++ b/include/gui/ISensorEventConnection.h
@@ -40,6 +40,7 @@
nsecs_t maxBatchReportLatencyNs, int reservedFlags) = 0;
virtual status_t setEventRate(int handle, nsecs_t ns) = 0;
virtual status_t flush() = 0;
+ virtual int32_t configureChannel(int32_t handle, int32_t rateLevel) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/gui/ISensorServer.h b/include/gui/ISensorServer.h
index 737c430..0c36c99 100644
--- a/include/gui/ISensorServer.h
+++ b/include/gui/ISensorServer.h
@@ -25,6 +25,8 @@
#include <binder/IInterface.h>
+struct native_handle;
+typedef struct native_handle native_handle_t;
namespace android {
// ----------------------------------------------------------------------------
@@ -43,6 +45,9 @@
virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
int mode, const String16& opPackageName) = 0;
virtual int32_t isDataInjectionEnabled() = 0;
+
+ virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName,
+ uint32_t size, int32_t type, int32_t format, const native_handle_t *resource) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/gui/Sensor.h b/include/gui/Sensor.h
index 7506835..d886b2b 100644
--- a/include/gui/Sensor.h
+++ b/include/gui/Sensor.h
@@ -91,6 +91,8 @@
bool isWakeUpSensor() const;
bool isDynamicSensor() const;
bool hasAdditionalInfo() const;
+ int32_t getHighestDirectReportRateLevel() const;
+ bool isDirectChannelTypeSupported(int32_t sharedMemType) const;
int32_t getReportingMode() const;
// Note that after setId() has been called, getUuid() no longer
diff --git a/include/gui/SensorManager.h b/include/gui/SensorManager.h
index 6c6230f..5b34ff4 100644
--- a/include/gui/SensorManager.h
+++ b/include/gui/SensorManager.h
@@ -34,10 +34,15 @@
#include <gui/SensorEventQueue.h>
+#include <unordered_map>
+
// ----------------------------------------------------------------------------
// Concrete types for the NDK
struct ASensorManager { };
+struct native_handle;
+typedef struct native_handle native_handle_t;
+
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------
@@ -59,6 +64,9 @@
Sensor const* getDefaultSensor(int type);
sp<SensorEventQueue> createEventQueue(String8 packageName = String8(""), int mode = 0);
bool isDataInjectionEnabled();
+ int createDirectChannel(size_t size, int channelType, const native_handle_t *channelData);
+ void destroyDirectChannel(int channelNativeHandle);
+ int configureDirectChannel(int channelNativeHandle, int sensorHandle, int rateLevel);
private:
// DeathRecipient interface
@@ -77,6 +85,8 @@
Vector<Sensor> mSensors;
sp<IBinder::DeathRecipient> mDeathObserver;
const String16 mOpPackageName;
+ std::unordered_map<int, sp<ISensorEventConnection>> mDirectConnection;
+ int32_t mDirectConnectionHandle;
};
// ----------------------------------------------------------------------------
diff --git a/libs/gui/ISensorEventConnection.cpp b/libs/gui/ISensorEventConnection.cpp
index 59ecee7..8af51c5 100644
--- a/libs/gui/ISensorEventConnection.cpp
+++ b/libs/gui/ISensorEventConnection.cpp
@@ -34,7 +34,8 @@
GET_SENSOR_CHANNEL = IBinder::FIRST_CALL_TRANSACTION,
ENABLE_DISABLE,
SET_EVENT_RATE,
- FLUSH_SENSOR
+ FLUSH_SENSOR,
+ CONFIGURE_CHANNEL
};
class BpSensorEventConnection : public BpInterface<ISensorEventConnection>
@@ -85,6 +86,15 @@
remote()->transact(FLUSH_SENSOR, data, &reply);
return reply.readInt32();
}
+
+ virtual int32_t configureChannel(int32_t handle, int32_t rateLevel) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
+ data.writeInt32(handle);
+ data.writeInt32(rateLevel);
+ remote()->transact(CONFIGURE_CHANNEL, data, &reply);
+ return reply.readInt32();
+ }
};
// Out-of-line virtual method definition to trigger vtable emission in this
@@ -131,6 +141,15 @@
reply->writeInt32(result);
return NO_ERROR;
}
+ case CONFIGURE_CHANNEL: {
+ CHECK_INTERFACE(ISensorEventConnection, data, reply);
+ int handle = data.readInt32();
+ int rateLevel = data.readInt32();
+ status_t result = configureChannel(handle, rateLevel);
+ reply->writeInt32(result);
+ return NO_ERROR;
+ }
+
}
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/ISensorServer.cpp b/libs/gui/ISensorServer.cpp
index 07c507a..aea7403 100644
--- a/libs/gui/ISensorServer.cpp
+++ b/libs/gui/ISensorServer.cpp
@@ -17,6 +17,7 @@
#include <stdint.h>
#include <sys/types.h>
+#include <cutils/native_handle.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/Vector.h>
@@ -37,6 +38,7 @@
CREATE_SENSOR_EVENT_CONNECTION,
ENABLE_DATA_INJECTION,
GET_DYNAMIC_SENSOR_LIST,
+ CREATE_SENSOR_DIRECT_CONNECTION,
};
class BpSensorServer : public BpInterface<ISensorServer>
@@ -101,6 +103,19 @@
remote()->transact(ENABLE_DATA_INJECTION, data, &reply);
return reply.readInt32();
}
+
+ virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName,
+ uint32_t size, int32_t type, int32_t format, const native_handle_t *resource) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+ data.writeString16(opPackageName);
+ data.writeUint32(size);
+ data.writeInt32(type);
+ data.writeInt32(format);
+ data.writeNativeHandle(resource);
+ remote()->transact(CREATE_SENSOR_DIRECT_CONNECTION, data, &reply);
+ return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
+ }
};
// Out-of-line virtual method definition to trigger vtable emission in this
@@ -153,6 +168,20 @@
}
return NO_ERROR;
}
+ case CREATE_SENSOR_DIRECT_CONNECTION: {
+ CHECK_INTERFACE(ISensorServer, data, reply);
+ const String16& opPackageName = data.readString16();
+ uint32_t size = data.readUint32();
+ int32_t type = data.readInt32();
+ int32_t format = data.readInt32();
+ native_handle_t *resource = data.readNativeHandle();
+ sp<ISensorEventConnection> ch =
+ createSensorDirectConnection(opPackageName, size, type, format, resource);
+ native_handle_close(resource);
+ native_handle_delete(resource);
+ reply->writeStrongBinder(IInterface::asBinder(ch));
+ return NO_ERROR;
+ }
}
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index 9cb2035..2fd29d5 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -300,7 +300,15 @@
// Feature flags
// Set DYNAMIC_SENSOR_MASK and ADDITIONAL_INFO_MASK flag here. Compatible with HAL 1_3.
if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
- mFlags |= (hwSensor.flags & (DYNAMIC_SENSOR_MASK | ADDITIONAL_INFO_MASK));
+ mFlags |= hwSensor.flags & (DYNAMIC_SENSOR_MASK | ADDITIONAL_INFO_MASK);
+ }
+ // Set DIRECT_REPORT_MASK and DIRECT_CHANNEL_MASK flags. Compatible with HAL 1_3.
+ if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
+ // only on continuous sensors direct report mode is defined
+ if ((mFlags & REPORTING_MODE_MASK) == SENSOR_FLAG_CONTINUOUS_MODE) {
+ mFlags |= hwSensor.flags
+ & (SENSOR_FLAG_MASK_DIRECT_REPORT | SENSOR_FLAG_MASK_DIRECT_CHANNEL);
+ }
}
// Set DATA_INJECTION flag here. Defined in HAL 1_4.
if (halVersion >= SENSORS_DEVICE_API_VERSION_1_4) {
@@ -410,6 +418,21 @@
return (mFlags & SENSOR_FLAG_ADDITIONAL_INFO) != 0;
}
+int32_t Sensor::getHighestDirectReportRateLevel() const {
+ return ((mFlags & SENSOR_FLAG_MASK_DIRECT_REPORT) >> SENSOR_FLAG_SHIFT_DIRECT_REPORT);
+}
+
+bool Sensor::isDirectChannelTypeSupported(int32_t sharedMemType) const {
+ switch (sharedMemType) {
+ case SENSOR_DIRECT_MEM_TYPE_ASHMEM:
+ return mFlags & SENSOR_FLAG_DIRECT_CHANNEL_ASHMEM;
+ case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
+ return mFlags & SENSOR_FLAG_DIRECT_CHANNEL_GRALLOC;
+ default:
+ return false;
+ }
+}
+
int32_t Sensor::getReportingMode() const {
return ((mFlags & REPORTING_MODE_MASK) >> REPORTING_MODE_SHIFT);
}
diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp
index 57c3073..46eaf28 100644
--- a/libs/gui/SensorManager.cpp
+++ b/libs/gui/SensorManager.cpp
@@ -19,6 +19,7 @@
#include <stdint.h>
#include <sys/types.h>
+#include <cutils/native_handle.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/Singleton.h>
@@ -89,7 +90,7 @@
}
SensorManager::SensorManager(const String16& opPackageName)
- : mSensorList(0), mOpPackageName(opPackageName) {
+ : mSensorList(0), mOpPackageName(opPackageName), mDirectConnectionHandle(1) {
// okay we're not locked here, but it's not needed during construction
assertStateLocked();
}
@@ -237,5 +238,62 @@
return false;
}
+int SensorManager::createDirectChannel(
+ size_t size, int channelType, const native_handle_t *resourceHandle) {
+ Mutex::Autolock _l(mLock);
+ if (assertStateLocked() != NO_ERROR) {
+ return NO_INIT;
+ }
+
+ switch (channelType) {
+ case SENSOR_DIRECT_MEM_TYPE_ASHMEM: {
+ sp<ISensorEventConnection> conn =
+ mSensorServer->createSensorDirectConnection(mOpPackageName,
+ static_cast<uint32_t>(size),
+ static_cast<int32_t>(channelType),
+ SENSOR_DIRECT_FMT_SENSORS_EVENT, resourceHandle);
+ if (conn == nullptr) {
+ return NO_MEMORY;
+ }
+ int nativeHandle = mDirectConnectionHandle++;
+ mDirectConnection.emplace(nativeHandle, conn);
+ return nativeHandle;
+ }
+ case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
+ LOG_FATAL("%s: Finish implementation of ION and GRALLOC or remove", __FUNCTION__);
+ return BAD_VALUE;
+ default:
+ ALOGE("Bad channel shared memory type %d", channelType);
+ return BAD_VALUE;
+ }
+}
+
+void SensorManager::destroyDirectChannel(int channelNativeHandle) {
+ Mutex::Autolock _l(mLock);
+ if (assertStateLocked() == NO_ERROR) {
+ mDirectConnection.erase(channelNativeHandle);
+ }
+}
+
+int SensorManager::configureDirectChannel(int channelNativeHandle, int sensorHandle, int rateLevel) {
+ Mutex::Autolock _l(mLock);
+ if (assertStateLocked() != NO_ERROR) {
+ return NO_INIT;
+ }
+
+ auto i = mDirectConnection.find(channelNativeHandle);
+ if (i == mDirectConnection.end()) {
+ ALOGE("Cannot find the handle in client direct connection table");
+ return BAD_VALUE;
+ }
+
+ int ret;
+ ret = i->second->configureChannel(sensorHandle, rateLevel);
+ ALOGE_IF(ret < 0, "SensorManager::configureChannel (%d, %d) returns %d",
+ static_cast<int>(sensorHandle), static_cast<int>(rateLevel),
+ static_cast<int>(ret));
+ return ret;
+}
+
// ----------------------------------------------------------------------------
}; // namespace android
diff --git a/services/sensorservice/Android.mk b/services/sensorservice/Android.mk
index 86af0ef..c41630a 100644
--- a/services/sensorservice/Android.mk
+++ b/services/sensorservice/Android.mk
@@ -10,6 +10,7 @@
OrientationSensor.cpp \
RecentEventLogger.cpp \
RotationVectorSensor.cpp \
+ SensorDirectConnection.cpp \
SensorEventConnection.cpp \
SensorFusion.cpp \
SensorInterface.cpp \
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 0245b26..41ad918 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -14,23 +14,27 @@
* limitations under the License.
*/
-#include <inttypes.h>
-#include <math.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/Atomic.h>
-#include <utils/Errors.h>
-#include <utils/Singleton.h>
+#include "SensorDevice.h"
+#include "SensorService.h"
+
#include <binder/BinderService.h>
#include <binder/Parcel.h>
#include <binder/IServiceManager.h>
-
+#include <cutils/ashmem.h>
#include <hardware/sensors.h>
+#include <utils/Atomic.h>
+#include <utils/Errors.h>
+#include <utils/Singleton.h>
-#include "SensorDevice.h"
-#include "SensorService.h"
+#include <inttypes.h>
+#include <math.h>
+#include <sys/mman.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sstream>
+#include <unistd.h>
namespace android {
// ---------------------------------------------------------------------------
@@ -386,7 +390,7 @@
void SensorDevice::disableAllSensors() {
Mutex::Autolock _l(mLock);
- for (size_t i = 0; i< mActivationCount.size(); ++i) {
+ for (size_t i = 0; i< mActivationCount.size(); ++i) {
const Info& info = mActivationCount.valueAt(i);
// Check if this sensor has been activated previously and disable it.
if (info.batchParams.size() > 0) {
@@ -486,6 +490,29 @@
mDisabledClients.remove(ident);
}
+int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) {
+ Mutex::Autolock _l(mLock);
+
+ int32_t channelHandle = mSensorDevice->register_direct_channel(
+ mSensorDevice, memory, -1 /*channel_handle*/);
+ return channelHandle;
+}
+
+void SensorDevice::unregisterDirectChannel(int32_t channelHandle) {
+ Mutex::Autolock _l(mLock);
+
+ mSensorDevice->register_direct_channel(mSensorDevice, nullptr, channelHandle);
+}
+
+int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle, int32_t channelHandle,
+ const struct sensors_direct_cfg_t *config) {
+ Mutex::Autolock _l(mLock);
+
+ int32_t ret = mSensorDevice->config_direct_report(
+ mSensorDevice, sensorHandle, channelHandle, config);
+ ALOGE_IF(ret < 0, "SensorDevice::configureDirectChannel ret %d", ret);
+ return ret;
+}
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index 0bb0752..b6886a2 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -26,6 +26,7 @@
#include <stdint.h>
#include <sys/types.h>
+#include <string>
#ifdef ENABLE_TREBLE
#include <map>
@@ -57,6 +58,12 @@
status_t setDelay(void* ident, int handle, int64_t ns);
status_t flush(void* ident, int handle);
status_t setMode(uint32_t mode);
+
+ int32_t registerDirectChannel(const sensors_direct_mem_t *memory);
+ void unregisterDirectChannel(int32_t channelHandle);
+ int32_t configureDirectChannel(int32_t sensorHandle,
+ int32_t channelHandle, const struct sensors_direct_cfg_t *config);
+
void disableAllSensors();
void enableAllSensors();
void autoDisable(void *ident, int handle);
diff --git a/services/sensorservice/SensorDeviceTreble.cpp b/services/sensorservice/SensorDeviceTreble.cpp
index 37f0f6c..2877589 100644
--- a/services/sensorservice/SensorDeviceTreble.cpp
+++ b/services/sensorservice/SensorDeviceTreble.cpp
@@ -29,16 +29,9 @@
#include <sensors/convert.h>
-using android::hardware::sensors::V1_0::ISensors;
using android::hardware::hidl_vec;
-using Event = android::hardware::sensors::V1_0::Event;
-using SensorInfo = android::hardware::sensors::V1_0::SensorInfo;
-using SensorType = android::hardware::sensors::V1_0::SensorType;
-using DynamicSensorInfo = android::hardware::sensors::V1_0::DynamicSensorInfo;
-using SensorInfo = android::hardware::sensors::V1_0::SensorInfo;
-using Result = android::hardware::sensors::V1_0::Result;
-
+using namespace android::hardware::sensors::V1_0;
using namespace android::hardware::sensors::V1_0::implementation;
namespace android {
@@ -504,6 +497,90 @@
mDisabledClients.remove(ident);
}
+int32_t SensorDevice::registerDirectChannel(const sensors_direct_mem_t* memory) {
+ Mutex::Autolock _l(mLock);
+
+ SharedMemType type;
+ switch (memory->type) {
+ case SENSOR_DIRECT_MEM_TYPE_ASHMEM:
+ type = SharedMemType::ASHMEM;
+ break;
+ case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
+ type = SharedMemType::GRALLOC;
+ break;
+ default:
+ return BAD_VALUE;
+ }
+
+ SharedMemFormat format;
+ if (memory->format != SENSOR_DIRECT_FMT_SENSORS_EVENT) {
+ return BAD_VALUE;
+ }
+ format = SharedMemFormat::SENSORS_EVENT;
+
+ SharedMemInfo mem = {
+ .type = type,
+ .format = format,
+ .size = static_cast<uint32_t>(memory->size),
+ .memoryHandle = memory->handle,
+ };
+
+ int32_t ret;
+ mSensors->registerDirectChannel(mem,
+ [&ret](auto result, auto channelHandle) {
+ if (result == Result::OK) {
+ ret = channelHandle;
+ } else {
+ ret = StatusFromResult(result);
+ }
+ });
+ return ret;
+}
+
+void SensorDevice::unregisterDirectChannel(int32_t channelHandle) {
+ Mutex::Autolock _l(mLock);
+ mSensors->unregisterDirectChannel(channelHandle);
+}
+
+int32_t SensorDevice::configureDirectChannel(int32_t sensorHandle,
+ int32_t channelHandle, const struct sensors_direct_cfg_t *config) {
+ Mutex::Autolock _l(mLock);
+
+ RateLevel rate;
+ switch(config->rate_level) {
+ case SENSOR_DIRECT_RATE_STOP:
+ rate = RateLevel::STOP;
+ break;
+ case SENSOR_DIRECT_RATE_NORMAL:
+ rate = RateLevel::NORMAL;
+ break;
+ case SENSOR_DIRECT_RATE_FAST:
+ rate = RateLevel::FAST;
+ break;
+ case SENSOR_DIRECT_RATE_VERY_FAST:
+ rate = RateLevel::VERY_FAST;
+ break;
+ default:
+ return BAD_VALUE;
+ }
+
+ int32_t ret;
+ mSensors->configDirectReport(sensorHandle, channelHandle, rate,
+ [&ret, rate] (auto result, auto token) {
+ if (rate == RateLevel::STOP) {
+ ret = StatusFromResult(result);
+ } else {
+ if (result == Result::OK) {
+ ret = token;
+ } else {
+ ret = StatusFromResult(result);
+ }
+ }
+ });
+
+ return ret;
+}
+
void SensorDevice::convertToSensorEvent(
const Event &src, sensors_event_t *dst) {
::android::hardware::sensors::V1_0::implementation::convertToSensorEvent(
diff --git a/services/sensorservice/SensorDirectConnection.cpp b/services/sensorservice/SensorDirectConnection.cpp
new file mode 100644
index 0000000..662f320
--- /dev/null
+++ b/services/sensorservice/SensorDirectConnection.cpp
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2016 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 "SensorDevice.h"
+#include "SensorDirectConnection.h"
+#include <hardware/sensors.h>
+
+#include <sys/stat.h>
+
+#define UNUSED(x) (void)(x)
+
+namespace android {
+
+SensorService::SensorDirectConnection::SensorDirectConnection(const sp<SensorService>& service,
+ uid_t uid, const sensors_direct_mem_t *mem, int32_t halChannelHandle,
+ const String16& opPackageName)
+ : mService(service), mUid(uid), mMem(*mem),
+ mHalChannelHandle(halChannelHandle),
+ mOpPackageName(opPackageName) {
+ ALOGD_IF(DEBUG_CONNECTIONS, "Created SensorDirectConnection");
+}
+
+SensorService::SensorDirectConnection::~SensorDirectConnection() {
+ ALOGD_IF(DEBUG_CONNECTIONS, "~SensorDirectConnection %p", this);
+
+ stopAll();
+ mService->cleanupConnection(this);
+ if (mMem.handle != nullptr) {
+ native_handle_close(mMem.handle);
+ native_handle_delete(const_cast<struct native_handle*>(mMem.handle));
+ }
+}
+
+void SensorService::SensorDirectConnection::onFirstRef() {
+}
+
+void SensorService::SensorDirectConnection::dump(String8& result) const {
+ Mutex::Autolock _l(mConnectionLock);
+ result.appendFormat("\tPackage %s, HAL channel handle %d, total sensor activated %zu\n",
+ String8(mOpPackageName).string(), getHalChannelHandle(), mActivated.size());
+ for (auto &i : mActivated) {
+ result.appendFormat("\t\tSensor %#08x, rate %d\n", i.first, i.second);
+ }
+}
+
+sp<BitTube> SensorService::SensorDirectConnection::getSensorChannel() const {
+ return nullptr;
+}
+
+status_t SensorService::SensorDirectConnection::enableDisable(
+ int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
+ int reservedFlags) {
+ // SensorDirectConnection does not support enableDisable, parameters not used
+ UNUSED(handle);
+ UNUSED(enabled);
+ UNUSED(samplingPeriodNs);
+ UNUSED(maxBatchReportLatencyNs);
+ UNUSED(reservedFlags);
+ return INVALID_OPERATION;
+}
+
+status_t SensorService::SensorDirectConnection::setEventRate(
+ int handle, nsecs_t samplingPeriodNs) {
+ // SensorDirectConnection does not support setEventRate, parameters not used
+ UNUSED(handle);
+ UNUSED(samplingPeriodNs);
+ return INVALID_OPERATION;
+}
+
+status_t SensorService::SensorDirectConnection::flush() {
+ // SensorDirectConnection does not support flush
+ return INVALID_OPERATION;
+}
+
+int32_t SensorService::SensorDirectConnection::configureChannel(int handle, int rateLevel) {
+
+ if (handle == -1 && rateLevel == SENSOR_DIRECT_RATE_STOP) {
+ stopAll();
+ return NO_ERROR;
+ }
+
+ if (mService->isOperationRestricted(mOpPackageName)) {
+ return PERMISSION_DENIED;
+ }
+
+ sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
+ if (si == nullptr) {
+ return NAME_NOT_FOUND;
+ }
+
+ const Sensor& s = si->getSensor();
+ if (!SensorService::canAccessSensor(s, "config direct channel", mOpPackageName)) {
+ return PERMISSION_DENIED;
+ }
+
+ if (s.getHighestDirectReportRateLevel() == 0
+ || rateLevel > s.getHighestDirectReportRateLevel()
+ || !s.isDirectChannelTypeSupported(mMem.type)) {
+ return INVALID_OPERATION;
+ }
+
+ struct sensors_direct_cfg_t config = {
+ .rate_level = rateLevel
+ };
+
+ Mutex::Autolock _l(mConnectionLock);
+ SensorDevice& dev(SensorDevice::getInstance());
+ int ret = dev.configureDirectChannel(handle, getHalChannelHandle(), &config);
+
+ if (rateLevel == SENSOR_DIRECT_RATE_STOP) {
+ if (ret == NO_ERROR) {
+ mActivated.erase(handle);
+ } else if (ret > 0) {
+ ret = UNKNOWN_ERROR;
+ }
+ } else {
+ if (ret > 0) {
+ mActivated[handle] = rateLevel;
+ }
+ }
+
+ return ret;
+}
+
+void SensorService::SensorDirectConnection::stopAll(bool backupRecord) {
+
+ struct sensors_direct_cfg_t config = {
+ .rate_level = SENSOR_DIRECT_RATE_STOP
+ };
+
+ Mutex::Autolock _l(mConnectionLock);
+ SensorDevice& dev(SensorDevice::getInstance());
+ for (auto &i : mActivated) {
+ dev.configureDirectChannel(i.first, getHalChannelHandle(), &config);
+ }
+
+ if (backupRecord && mActivatedBackup.empty()) {
+ mActivatedBackup = mActivated;
+ }
+ mActivated.clear();
+}
+
+void SensorService::SensorDirectConnection::recoverAll() {
+ stopAll(false);
+
+ Mutex::Autolock _l(mConnectionLock);
+ SensorDevice& dev(SensorDevice::getInstance());
+
+ // recover list of report from backup
+ mActivated = mActivatedBackup;
+ mActivatedBackup.clear();
+
+ // re-enable them
+ for (auto &i : mActivated) {
+ struct sensors_direct_cfg_t config = {
+ .rate_level = i.second
+ };
+ dev.configureDirectChannel(i.first, getHalChannelHandle(), &config);
+ }
+}
+
+int32_t SensorService::SensorDirectConnection::getHalChannelHandle() const {
+ return mHalChannelHandle;
+}
+
+bool SensorService::SensorDirectConnection::isEquivalent(const sensors_direct_mem_t *mem) const {
+ bool ret = false;
+
+ if (mMem.type == mem->type) {
+ switch (mMem.type) {
+ case SENSOR_DIRECT_MEM_TYPE_ASHMEM: {
+ struct stat s1, s2;
+ int fd1, fd2;
+ fd1 = mMem.handle->data[0];
+ fd2 = mem->handle->data[1];
+ if (fstat(fd1, &s1) < 0 || fstat(fd2, &s2) < 0 || s1.st_ino == s2.st_ino) {
+ ret = true;
+ }
+ }
+ case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
+ LOG_FATAL("%s: Implement GRALLOC or remove", __FUNCTION__);
+ ret = true;
+ default:
+ ALOGE("Unexpected mem type %d", mMem.type);
+ ret = true;
+ }
+ }
+ return ret;
+}
+
+} // namespace android
+
diff --git a/services/sensorservice/SensorDirectConnection.h b/services/sensorservice/SensorDirectConnection.h
new file mode 100644
index 0000000..692ef0d
--- /dev/null
+++ b/services/sensorservice/SensorDirectConnection.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef ANDROID_SENSOR_DIRECT_CONNECTION_H
+#define ANDROID_SENSOR_DIRECT_CONNECTION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <binder/BinderService.h>
+
+#include <gui/Sensor.h>
+#include <gui/BitTube.h>
+#include <gui/ISensorServer.h>
+#include <gui/ISensorEventConnection.h>
+
+#include "SensorService.h"
+
+namespace android {
+
+class SensorService;
+class BitTube;
+
+class SensorService::SensorDirectConnection: public BnSensorEventConnection {
+public:
+ SensorDirectConnection(const sp<SensorService>& service, uid_t uid,
+ const sensors_direct_mem_t *mem, int32_t halChannelHandle,
+ const String16& opPackageName);
+ void dump(String8& result) const;
+ uid_t getUid() const { return mUid; }
+ int32_t getHalChannelHandle() const;
+ bool isEquivalent(const sensors_direct_mem_t *mem) const;
+
+ // stop all active sensor report. if backupRecord is set to false,
+ // those report can be recovered by recoverAll
+ // called by SensorService when enter restricted mode
+ void stopAll(bool clearRecord = false);
+
+ // recover sensor reports previously stopped by stopAll(true)
+ // called by SensorService when return to NORMAL mode.
+ void recoverAll();
+
+protected:
+ virtual ~SensorDirectConnection();
+ // ISensorEventConnection functions
+ virtual void onFirstRef();
+ virtual sp<BitTube> getSensorChannel() const;
+ virtual status_t enableDisable(int handle, bool enabled, nsecs_t samplingPeriodNs,
+ nsecs_t maxBatchReportLatencyNs, int reservedFlags);
+ virtual status_t setEventRate(int handle, nsecs_t samplingPeriodNs);
+ virtual status_t flush();
+ virtual int32_t configureChannel(int handle, int rateLevel);
+
+private:
+ const sp<SensorService> mService;
+ const uid_t mUid;
+ const sensors_direct_mem_t mMem;
+ const int32_t mHalChannelHandle;
+ const String16 mOpPackageName;
+
+ mutable Mutex mConnectionLock;
+ std::unordered_map<int, int> mActivated;
+ std::unordered_map<int, int> mActivatedBackup;
+};
+
+} // namepsace android
+
+#endif // ANDROID_SENSOR_DIRECT_CONNECTION_H
+
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index f2f1444..d84d36e 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -23,6 +23,8 @@
#include "SensorEventConnection.h"
#include "SensorDevice.h"
+#define UNUSED(x) (void)(x)
+
namespace android {
SensorService::SensorEventConnection::SensorEventConnection(
@@ -524,6 +526,13 @@
return mService->flushSensor(this, mOpPackageName);
}
+int32_t SensorService::SensorEventConnection::configureChannel(int handle, int rateLevel) {
+ // SensorEventConnection does not support configureChannel, parameters not used
+ UNUSED(handle);
+ UNUSED(rateLevel);
+ return INVALID_OPERATION;
+}
+
int SensorService::SensorEventConnection::handleEvent(int fd, int events, void* /*data*/) {
if (events & ALOOPER_EVENT_HANGUP || events & ALOOPER_EVENT_ERROR) {
{
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index 883c16e..cd81ddd 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -74,6 +74,8 @@
nsecs_t maxBatchReportLatencyNs, int reservedFlags);
virtual status_t setEventRate(int handle, nsecs_t samplingPeriodNs);
virtual status_t flush();
+ virtual int32_t configureChannel(int handle, int rateLevel);
+
// Count the number of flush complete events which are about to be dropped in the buffer.
// Increment mPendingFlushEventsToSend in mSensorInfo. These flush complete events will be sent
// separately before the next batch of events.
diff --git a/services/sensorservice/SensorList.cpp b/services/sensorservice/SensorList.cpp
index e0101c1..31c8251 100644
--- a/services/sensorservice/SensorList.cpp
+++ b/services/sensorservice/SensorList.cpp
@@ -124,7 +124,7 @@
forEachSensor([&result] (const Sensor& s) -> bool {
result.appendFormat(
"%#010x) %-25s | %-15s | ver: %" PRId32 " | type: %20s(%" PRId32
- ") | perm: %s\n\t",
+ ") | perm: %s\n",
s.getHandle(),
s.getName().string(),
s.getVendor().string(),
@@ -133,17 +133,18 @@
s.getType(),
s.getRequiredPermission().size() ? s.getRequiredPermission().string() : "n/a");
+ result.append("\t");
const int reportingMode = s.getReportingMode();
if (reportingMode == AREPORTING_MODE_CONTINUOUS) {
- result.append(" continuous | ");
+ result.append("continuous | ");
} else if (reportingMode == AREPORTING_MODE_ON_CHANGE) {
- result.append(" on-change | ");
+ result.append("on-change | ");
} else if (reportingMode == AREPORTING_MODE_ONE_SHOT) {
- result.append(" one-shot | ");
+ result.append("one-shot | ");
} else if (reportingMode == AREPORTING_MODE_SPECIAL_TRIGGER) {
- result.append(" special-trigger | ");
+ result.append("special-trigger | ");
} else {
- result.append(" unknown-mode | ");
+ result.append("unknown-mode | ");
}
if (s.getMaxDelay() > 0) {
@@ -178,8 +179,19 @@
if (s.hasAdditionalInfo()) {
result.appendFormat("has-additional-info, ");
}
-
result.append("\n");
+
+ if (s.getHighestDirectReportRateLevel() > SENSOR_DIRECT_RATE_STOP) {
+ result.appendFormat("\thighest rate level = %d, support shared mem: ",
+ s.getHighestDirectReportRateLevel());
+ if (s.isDirectChannelTypeSupported(SENSOR_DIRECT_MEM_TYPE_ASHMEM)) {
+ result.append("ashmem, ");
+ }
+ if (s.isDirectChannelTypeSupported(SENSOR_DIRECT_MEM_TYPE_GRALLOC)) {
+ result.append("gralloc, ");
+ }
+ result.append("\n");
+ }
return true;
});
return std::string(result.string());
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 2e44736..143a3c5 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -21,6 +21,7 @@
#include <binder/IServiceManager.h>
#include <binder/PermissionCache.h>
+#include <cutils/ashmem.h>
#include <gui/SensorEventQueue.h>
#include <hardware/sensors.h>
@@ -40,6 +41,7 @@
#include "SensorInterface.h"
#include "SensorService.h"
+#include "SensorDirectConnection.h"
#include "SensorEventAckReceiver.h"
#include "SensorEventConnection.h"
#include "SensorRecord.h"
@@ -337,7 +339,16 @@
if (mCurrentOperatingMode != NORMAL) {
return INVALID_OPERATION;
}
+
mCurrentOperatingMode = RESTRICTED;
+ // temporarily stop all sensor direct report
+ for (auto &i : mDirectConnections) {
+ sp<SensorDirectConnection> connection(i.promote());
+ if (connection != nullptr) {
+ connection->stopAll(true /* backupRecord */);
+ }
+ }
+
dev.disableAllSensors();
// Clear all pending flush connections for all active sensors. If one of the active
// connections has called flush() and the underlying sensor has been disabled before a
@@ -352,6 +363,13 @@
if (mCurrentOperatingMode == RESTRICTED) {
mCurrentOperatingMode = NORMAL;
dev.enableAllSensors();
+ // recover all sensor direct report
+ for (auto &i : mDirectConnections) {
+ sp<SensorDirectConnection> connection(i.promote());
+ if (connection != nullptr) {
+ connection->recoverAll();
+ }
+ }
}
if (mCurrentOperatingMode == DATA_INJECTION) {
resetToNormalModeLocked();
@@ -430,8 +448,8 @@
case DATA_INJECTION:
result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string());
}
- result.appendFormat("%zd active connections\n", mActiveConnections.size());
+ result.appendFormat("%zd active connections\n", mActiveConnections.size());
for (size_t i=0 ; i < mActiveConnections.size() ; i++) {
sp<SensorEventConnection> connection(mActiveConnections[i].promote());
if (connection != 0) {
@@ -440,6 +458,15 @@
}
}
+ result.appendFormat("%zd direct connections\n", mDirectConnections.size());
+ for (size_t i = 0 ; i < mDirectConnections.size() ; i++) {
+ sp<SensorDirectConnection> connection(mDirectConnections[i].promote());
+ if (connection != nullptr) {
+ result.appendFormat("Direct connection %zu:\n", i);
+ connection->dump(result);
+ }
+ }
+
result.appendFormat("Previous Registrations:\n");
// Log in the reverse chronological order.
int currentIndex = (mNextSensorRegIndex - 1 + SENSOR_REGISTRATIONS_BUF_SIZE) %
@@ -936,6 +963,85 @@
return (mCurrentOperatingMode == DATA_INJECTION);
}
+sp<ISensorEventConnection> SensorService::createSensorDirectConnection(
+ const String16& opPackageName, uint32_t size, int32_t type, int32_t format,
+ const native_handle *resource) {
+ Mutex::Autolock _l(mLock);
+
+ struct sensors_direct_mem_t mem = {
+ .type = type,
+ .format = format,
+ .size = size,
+ .handle = resource,
+ };
+ uid_t uid = IPCThreadState::self()->getCallingUid();
+
+ if (mem.handle == nullptr) {
+ ALOGE("Failed to clone resource handle");
+ return nullptr;
+ }
+
+ // check format
+ if (format != SENSOR_DIRECT_FMT_SENSORS_EVENT) {
+ ALOGE("Direct channel format %d is unsupported!", format);
+ return nullptr;
+ }
+
+ // check for duplication
+ for (auto &i : mDirectConnections) {
+ sp<SensorDirectConnection> connection(i.promote());
+ if (connection != nullptr && connection->isEquivalent(&mem)) {
+ return nullptr;
+ }
+ }
+
+ // check specific to memory type
+ switch(type) {
+ case SENSOR_DIRECT_MEM_TYPE_ASHMEM: { // channel backed by ashmem
+ int fd = resource->data[0];
+ int size2 = ashmem_get_size_region(fd);
+ // check size consistency
+ if (size2 != static_cast<int>(size)) {
+ ALOGE("Ashmem direct channel size mismatch, %" PRIu32 " vs %d", size, size2);
+ return nullptr;
+ }
+ break;
+ }
+ case SENSOR_DIRECT_MEM_TYPE_GRALLOC:
+ LOG_FATAL("%s: Finish implementation of ION and GRALLOC or remove", __FUNCTION__);
+ break;
+ default:
+ ALOGE("Unknown direct connection memory type %d", type);
+ return nullptr;
+ }
+
+ native_handle_t *clone = native_handle_clone(resource);
+ if (!clone) {
+ return nullptr;
+ }
+
+ SensorDirectConnection* conn = nullptr;
+ SensorDevice& dev(SensorDevice::getInstance());
+ int channelHandle = dev.registerDirectChannel(&mem);
+
+ if (channelHandle <= 0) {
+ ALOGE("SensorDevice::registerDirectChannel returns %d", channelHandle);
+ } else {
+ mem.handle = clone;
+ conn = new SensorDirectConnection(this, uid, &mem, channelHandle, opPackageName);
+ }
+
+ if (conn == nullptr) {
+ native_handle_close(clone);
+ native_handle_delete(clone);
+ } else {
+ // add to list of direct connections
+ // sensor service should never hold pointer or sp of SensorDirectConnection object.
+ mDirectConnections.add(wp<SensorDirectConnection>(conn));
+ }
+ return conn;
+}
+
status_t SensorService::resetToNormalMode() {
Mutex::Autolock _l(mLock);
return resetToNormalModeLocked();
@@ -995,11 +1101,18 @@
dev.notifyConnectionDestroyed(c);
}
+void SensorService::cleanupConnection(SensorDirectConnection* c) {
+ Mutex::Autolock _l(mLock);
+
+ SensorDevice& dev(SensorDevice::getInstance());
+ dev.unregisterDirectChannel(c->getHalChannelHandle());
+ mDirectConnections.remove(c);
+}
+
sp<SensorInterface> SensorService::getSensorInterfaceFromHandle(int handle) const {
return mSensors.getInterface(handle);
}
-
status_t SensorService::enable(const sp<SensorEventConnection>& connection,
int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
const String16& opPackageName) {
@@ -1013,7 +1126,7 @@
}
Mutex::Autolock _l(mLock);
- if ((mCurrentOperatingMode == RESTRICTED || mCurrentOperatingMode == DATA_INJECTION)
+ if (mCurrentOperatingMode != NORMAL
&& !isWhiteListedPackage(connection->getPackageName())) {
return INVALID_OPERATION;
}
@@ -1331,5 +1444,14 @@
return (packageName.contains(mWhiteListedPackage.string()));
}
+bool SensorService::isOperationRestricted(const String16& opPackageName) {
+ Mutex::Autolock _l(mLock);
+ if (mCurrentOperatingMode != RESTRICTED) {
+ String8 package(opPackageName);
+ return !isWhiteListedPackage(package);
+ }
+ return false;
+}
+
}; // namespace android
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index e969d8a..eeedd4a 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -67,9 +67,11 @@
{
// nested class/struct for internal use
class SensorEventConnection;
+ class SensorDirectConnection;
public:
void cleanupConnection(SensorEventConnection* connection);
+ void cleanupConnection(SensorDirectConnection* c);
status_t enable(const sp<SensorEventConnection>& connection, int handle,
nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
@@ -154,6 +156,8 @@
const String8& packageName,
int requestedMode, const String16& opPackageName);
virtual int isDataInjectionEnabled();
+ virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName,
+ uint32_t size, int32_t type, int32_t format, const native_handle *resource);
virtual status_t dump(int fd, const Vector<String16>& args);
String8 getSensorName(int handle) const;
@@ -203,6 +207,7 @@
// allowed to register for or call flush on sensors. Typically only cts test packages are
// allowed.
bool isWhiteListedPackage(const String8& packageName);
+ bool isOperationRestricted(const String16& opPackageName);
// Reset the state of SensorService to NORMAL mode.
status_t resetToNormalMode();
@@ -239,6 +244,7 @@
sensors_event_t *mSensorEventBuffer, *mSensorEventScratch;
wp<const SensorEventConnection> * mMapFlushEventsToConnections;
std::unordered_map<int, RecentEventLogger*> mRecentEvent;
+ SortedVector< wp<SensorDirectConnection> > mDirectConnections;
Mode mCurrentOperatingMode;
// This packagaName is set when SensorService is in RESTRICTED or DATA_INJECTION mode. Only