summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/android/sensor.h88
-rw-r--r--libs/sensor/ISensorEventConnection.cpp20
-rw-r--r--libs/sensor/ISensorServer.cpp10
-rw-r--r--libs/sensor/OWNERS2
-rw-r--r--libs/sensor/Sensor.cpp9
-rw-r--r--libs/sensor/SensorManager.cpp5
-rw-r--r--libs/sensor/include/sensor/ISensorEventConnection.h2
-rw-r--r--libs/sensor/include/sensor/ISensorServer.h2
-rw-r--r--libs/sensor/include/sensor/Sensor.h1
-rw-r--r--libs/sensor/include/sensor/SensorManager.h2
-rw-r--r--services/sensorservice/Android.bp70
-rw-r--r--services/sensorservice/Android.mk73
-rw-r--r--services/sensorservice/OWNERS2
-rw-r--r--services/sensorservice/SensorDevice.cpp21
-rw-r--r--services/sensorservice/SensorDirectConnection.cpp12
-rw-r--r--services/sensorservice/SensorDirectConnection.h7
-rw-r--r--services/sensorservice/SensorEventConnection.cpp24
-rw-r--r--services/sensorservice/SensorEventConnection.h3
-rw-r--r--services/sensorservice/SensorList.cpp11
-rw-r--r--services/sensorservice/SensorService.cpp38
-rw-r--r--services/sensorservice/SensorService.h2
-rw-r--r--services/sensorservice/hidl/Android.bp1
-rw-r--r--services/sensorservice/hidl/SensorManager.cpp73
-rw-r--r--services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h10
24 files changed, 327 insertions, 161 deletions
diff --git a/include/android/sensor.h b/include/android/sensor.h
index 7f460873b5..2db0ee7fd9 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -197,7 +197,7 @@ enum {
* A sensor event.
*/
-/* NOTE: Must match hardware/sensors.h */
+/* NOTE: changes to these structs have to be backward compatible */
typedef struct ASensorVector {
union {
float v[3];
@@ -259,7 +259,7 @@ typedef struct {
};
} AAdditionalInfoEvent;
-/* NOTE: Must match hardware/sensors.h */
+/* NOTE: changes to this struct has to be backward compatible */
typedef struct ASensorEvent {
int32_t version; /* sizeof(struct ASensorEvent) */
int32_t sensor;
@@ -388,13 +388,13 @@ ASensorManager* ASensorManager_getInstance();
#endif
#if __ANDROID_API__ >= __ANDROID_API_O__
-/*
+/**
* Get a reference to the sensor manager. ASensorManager is a singleton
* per package as different packages may have access to different sensors.
*
* Example:
*
- * ASensorManager* sensorManager = ASensorManager_getInstanceForPackage("foo.bar.baz");
+ * ASensorManager* sensorManager = ASensorManager_getInstanceForPackage("foo.bar.baz");
*
*/
ASensorManager* ASensorManager_getInstanceForPackage(const char* packageName);
@@ -503,14 +503,12 @@ void ASensorManager_destroyDirectChannel(ASensorManager* manager, int channelId)
* {@link ASensor_isDirectChannelTypeSupported}, respectively.
*
* Example:
- * \code{.cpp}
- * ASensorManager *manager = ...;
- * ASensor *sensor = ...;
- * int channelId = ...;
*
- * ASensorManager_configureDirectReport(
- * manager, sensor, channel_id, ASENSOR_DIRECT_RATE_FAST);
- * \endcode
+ * ASensorManager *manager = ...;
+ * ASensor *sensor = ...;
+ * int channelId = ...;
+ *
+ * ASensorManager_configureDirectReport(manager, sensor, channel_id, ASENSOR_DIRECT_RATE_FAST);
*
* \param manager the {@link ASensorManager} instance obtained from
* {@link ASensorManager_getInstanceForPackage}.
@@ -530,50 +528,86 @@ int ASensorManager_configureDirectReport(
/*****************************************************************************/
/**
- * Enable the selected sensor with a specified sampling period and max batch report latency.
- * Returns a negative error code on failure.
- * Note: To disable the selected sensor, use ASensorEventQueue_disableSensor() same as before.
+ * Enable the selected sensor with sampling and report parameters
+ *
+ * Enable the selected sensor at a specified sampling period and max batch report latency.
+ * To disable sensor, use {@link ASensorEventQueue_disableSensor}.
+ *
+ * \param queue {@link ASensorEventQueue} for sensor event to be report to.
+ * \param sensor {@link ASensor} to be enabled.
+ * \param samplingPeriodUs sampling period of sensor in microseconds.
+ * \param maxBatchReportLatencyus maximum time interval between two batch of sensor events are
+ * delievered in microseconds. For sensor streaming, set to 0.
+ * \return 0 on success or a negative error code on failure.
*/
int ASensorEventQueue_registerSensor(ASensorEventQueue* queue, ASensor const* sensor,
int32_t samplingPeriodUs, int64_t maxBatchReportLatencyUs);
/**
- * Enable the selected sensor. Returns a negative error code on failure.
+ * Enable the selected sensor at default sampling rate.
+ *
+ * Start event reports of a sensor to specified sensor event queue at a default rate.
+ *
+ * \param queue {@link ASensorEventQueue} for sensor event to be report to.
+ * \param sensor {@link ASensor} to be enabled.
+ *
+ * \return 0 on success or a negative error code on failure.
*/
int ASensorEventQueue_enableSensor(ASensorEventQueue* queue, ASensor const* sensor);
/**
- * Disable the selected sensor. Returns a negative error code on failure.
+ * Disable the selected sensor.
+ *
+ * Stop event reports from the sensor to specified sensor event queue.
+ *
+ * \param queue {@link ASensorEventQueue} to be changed
+ * \param sensor {@link ASensor} to be disabled
+ * \return 0 on success or a negative error code on failure.
*/
int ASensorEventQueue_disableSensor(ASensorEventQueue* queue, ASensor const* sensor);
/**
* Sets the delivery rate of events in microseconds for the given sensor.
+ *
+ * This function has to be called after {@link ASensorEventQueue_enableSensor}.
* Note that this is a hint only, generally event will arrive at a higher
* rate. It is an error to set a rate inferior to the value returned by
* ASensor_getMinDelay().
- * Returns a negative error code on failure.
+ *
+ * \param queue {@link ASensorEventQueue} to which sensor event is delivered.
+ * \param sensor {@link ASensor} of which sampling rate to be updated.
+ * \param usec sensor sampling period (1/sampling rate) in microseconds
+ * \return 0 on sucess or a negative error code on failure.
*/
int ASensorEventQueue_setEventRate(ASensorEventQueue* queue, ASensor const* sensor, int32_t usec);
/**
- * Returns true if there are one or more events available in the
- * sensor queue. Returns 1 if the queue has events; 0 if
- * it does not have events; and a negative value if there is an error.
+ * Determine if a sensor event queue has pending event to be processed.
+ *
+ * \param queue {@link ASensorEventQueue} to be queried
+ * \return 1 if the queue has events; 0 if it does not have events;
+ * or a negative value if there is an error.
*/
int ASensorEventQueue_hasEvents(ASensorEventQueue* queue);
/**
- * Returns the next available events from the queue. Returns a negative
- * value if no events are available or an error has occurred, otherwise
- * the number of events returned.
+ * Retrieve pending events in sensor event queue
+ *
+ * Retrieve next available events from the queue to a specified event array.
+ *
+ * \param queue {@link ASensorEventQueue} to get events from
+ * \param events pointer to an array of {@link ASensorEvents}.
+ * \param count max number of event that can be filled into array event.
+ * \return number of events returned on success; negative error code when
+ * no events are pending or an error has occurred.
*
* Examples:
- * ASensorEvent event;
- * ssize_t numEvent = ASensorEventQueue_getEvents(queue, &event, 1);
*
- * ASensorEvent eventBuffer[8];
- * ssize_t numEvent = ASensorEventQueue_getEvents(queue, eventBuffer, 8);
+ * ASensorEvent event;
+ * ssize_t numEvent = ASensorEventQueue_getEvents(queue, &event, 1);
+ *
+ * ASensorEvent eventBuffer[8];
+ * ssize_t numEvent = ASensorEventQueue_getEvents(queue, eventBuffer, 8);
*
*/
ssize_t ASensorEventQueue_getEvents(ASensorEventQueue* queue, ASensorEvent* events, size_t count);
diff --git a/libs/sensor/ISensorEventConnection.cpp b/libs/sensor/ISensorEventConnection.cpp
index 8a3a623983..1cd8e01643 100644
--- a/libs/sensor/ISensorEventConnection.cpp
+++ b/libs/sensor/ISensorEventConnection.cpp
@@ -36,7 +36,8 @@ enum {
ENABLE_DISABLE,
SET_EVENT_RATE,
FLUSH_SENSOR,
- CONFIGURE_CHANNEL
+ CONFIGURE_CHANNEL,
+ DESTROY,
};
class BpSensorEventConnection : public BpInterface<ISensorEventConnection>
@@ -96,11 +97,22 @@ public:
remote()->transact(CONFIGURE_CHANNEL, data, &reply);
return reply.readInt32();
}
+
+ virtual void onLastStrongRef(const void* id) {
+ destroy();
+ BpInterface<ISensorEventConnection>::onLastStrongRef(id);
+ }
+
+protected:
+ virtual void destroy() {
+ Parcel data, reply;
+ remote()->transact(DESTROY, data, &reply);
+ }
};
// Out-of-line virtual method definition to trigger vtable emission in this
// translation unit (see clang warning -Wweak-vtables)
-BpSensorEventConnection::~BpSensorEventConnection() {}
+BpSensorEventConnection::~BpSensorEventConnection() { }
IMPLEMENT_META_INTERFACE(SensorEventConnection, "android.gui.SensorEventConnection");
@@ -150,6 +162,10 @@ status_t BnSensorEventConnection::onTransact(
reply->writeInt32(result);
return NO_ERROR;
}
+ case DESTROY: {
+ destroy();
+ return NO_ERROR;
+ }
}
return BBinder::onTransact(code, data, reply, flags);
diff --git a/libs/sensor/ISensorServer.cpp b/libs/sensor/ISensorServer.cpp
index 74186dfcb9..f20668d1e9 100644
--- a/libs/sensor/ISensorServer.cpp
+++ b/libs/sensor/ISensorServer.cpp
@@ -119,10 +119,12 @@ public:
return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
}
- virtual int setOperationParameter(
- int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints) {
+ virtual int setOperationParameter(int32_t handle, int32_t type,
+ const Vector<float> &floats,
+ const Vector<int32_t> &ints) {
Parcel data, reply;
data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+ data.writeInt32(handle);
data.writeInt32(type);
data.writeUint32(static_cast<uint32_t>(floats.size()));
for (auto i : floats) {
@@ -203,10 +205,12 @@ status_t BnSensorServer::onTransact(
}
case SET_OPERATION_PARAMETER: {
CHECK_INTERFACE(ISensorServer, data, reply);
+ int32_t handle;
int32_t type;
Vector<float> floats;
Vector<int32_t> ints;
+ handle = data.readInt32();
type = data.readInt32();
floats.resize(data.readUint32());
for (auto &i : floats) {
@@ -217,7 +221,7 @@ status_t BnSensorServer::onTransact(
i = data.readInt32();
}
- int32_t ret = setOperationParameter(type, floats, ints);
+ int32_t ret = setOperationParameter(handle, type, floats, ints);
reply->writeInt32(ret);
return NO_ERROR;
}
diff --git a/libs/sensor/OWNERS b/libs/sensor/OWNERS
new file mode 100644
index 0000000000..6a38a1ff14
--- /dev/null
+++ b/libs/sensor/OWNERS
@@ -0,0 +1,2 @@
+ashutoshj@google.com
+pengxu@google.com
diff --git a/libs/sensor/Sensor.cpp b/libs/sensor/Sensor.cpp
index c2d477e4b5..a0e368c7e4 100644
--- a/libs/sensor/Sensor.cpp
+++ b/libs/sensor/Sensor.cpp
@@ -30,7 +30,7 @@ Sensor::Sensor(const char * name) :
mName(name), mHandle(0), mType(0),
mMinValue(0), mMaxValue(0), mResolution(0),
mPower(0), mMinDelay(0), mVersion(0), mFifoReservedEventCount(0),
- mFifoMaxEventCount(0), mRequiredAppOp(0),
+ mFifoMaxEventCount(0), mRequiredAppOp(-1),
mMaxDelay(0), mFlags(0) {
}
@@ -38,7 +38,8 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion) :
Sensor(*hwSensor, uuid_t(), halVersion) {
}
-Sensor::Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersion) {
+Sensor::Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersion) :
+ Sensor("") {
mName = hwSensor.name;
mVendor = hwSensor.vendor;
mVersion = hwSensor.version;
@@ -412,6 +413,10 @@ bool Sensor::isDynamicSensor() const {
return (mFlags & SENSOR_FLAG_DYNAMIC_SENSOR) != 0;
}
+bool Sensor::isDataInjectionSupported() const {
+ return (mFlags & SENSOR_FLAG_DATA_INJECTION) != 0;
+}
+
bool Sensor::hasAdditionalInfo() const {
return (mFlags & SENSOR_FLAG_ADDITIONAL_INFO) != 0;
}
diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp
index 3fbc5ebba8..6fe72a13ba 100644
--- a/libs/sensor/SensorManager.cpp
+++ b/libs/sensor/SensorManager.cpp
@@ -305,12 +305,13 @@ int SensorManager::configureDirectChannel(int channelNativeHandle, int sensorHan
}
int SensorManager::setOperationParameter(
- int type, const Vector<float> &floats, const Vector<int32_t> &ints) {
+ int handle, int type,
+ const Vector<float> &floats, const Vector<int32_t> &ints) {
Mutex::Autolock _l(mLock);
if (assertStateLocked() != NO_ERROR) {
return NO_INIT;
}
- return mSensorServer->setOperationParameter(type, floats, ints);
+ return mSensorServer->setOperationParameter(handle, type, floats, ints);
}
// ----------------------------------------------------------------------------
diff --git a/libs/sensor/include/sensor/ISensorEventConnection.h b/libs/sensor/include/sensor/ISensorEventConnection.h
index 07cc7e84ad..b62e18c63c 100644
--- a/libs/sensor/include/sensor/ISensorEventConnection.h
+++ b/libs/sensor/include/sensor/ISensorEventConnection.h
@@ -42,6 +42,8 @@ public:
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;
+protected:
+ virtual void destroy() = 0; // synchronously release resource hold by remote object
};
// ----------------------------------------------------------------------------
diff --git a/libs/sensor/include/sensor/ISensorServer.h b/libs/sensor/include/sensor/ISensorServer.h
index 8d5006258f..edf3e0f4cf 100644
--- a/libs/sensor/include/sensor/ISensorServer.h
+++ b/libs/sensor/include/sensor/ISensorServer.h
@@ -52,7 +52,7 @@ public:
uint32_t size, int32_t type, int32_t format, const native_handle_t *resource) = 0;
virtual int setOperationParameter(
- int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints) = 0;
+ int32_t handle, int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/libs/sensor/include/sensor/Sensor.h b/libs/sensor/include/sensor/Sensor.h
index 043e6352a7..6926f7f341 100644
--- a/libs/sensor/include/sensor/Sensor.h
+++ b/libs/sensor/include/sensor/Sensor.h
@@ -90,6 +90,7 @@ public:
uint32_t getFlags() const;
bool isWakeUpSensor() const;
bool isDynamicSensor() const;
+ bool isDataInjectionSupported() const;
bool hasAdditionalInfo() const;
int32_t getHighestDirectReportRateLevel() const;
bool isDirectChannelTypeSupported(int32_t sharedMemType) const;
diff --git a/libs/sensor/include/sensor/SensorManager.h b/libs/sensor/include/sensor/SensorManager.h
index 5fc85d329b..23f7a918bb 100644
--- a/libs/sensor/include/sensor/SensorManager.h
+++ b/libs/sensor/include/sensor/SensorManager.h
@@ -64,7 +64,7 @@ public:
int createDirectChannel(size_t size, int channelType, const native_handle_t *channelData);
void destroyDirectChannel(int channelNativeHandle);
int configureDirectChannel(int channelNativeHandle, int sensorHandle, int rateLevel);
- int setOperationParameter(int type, const Vector<float> &floats, const Vector<int32_t> &ints);
+ int setOperationParameter(int handle, int type, const Vector<float> &floats, const Vector<int32_t> &ints);
private:
// DeathRecipient interface
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index 8c2300e9d0..8d381b1c31 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -1,3 +1,73 @@
subdirs = [
"hidl"
]
+cc_library_shared {
+ name: "libsensorservice",
+
+ srcs: [
+ "BatteryService.cpp",
+ "CorrectedGyroSensor.cpp",
+ "Fusion.cpp",
+ "GravitySensor.cpp",
+ "LinearAccelerationSensor.cpp",
+ "OrientationSensor.cpp",
+ "RecentEventLogger.cpp",
+ "RotationVectorSensor.cpp",
+ "SensorDevice.cpp",
+ "SensorDirectConnection.cpp",
+ "SensorEventConnection.cpp",
+ "SensorFusion.cpp",
+ "SensorInterface.cpp",
+ "SensorList.cpp",
+ "SensorRecord.cpp",
+ "SensorService.cpp",
+ "SensorServiceUtils.cpp",
+ ],
+
+ cflags: [
+ "-DLOG_TAG=\"SensorService\"",
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ "-fvisibility=hidden"
+ ],
+
+ shared_libs: [
+ "libcutils",
+ "libhardware",
+ "libhardware_legacy",
+ "libutils",
+ "liblog",
+ "libbinder",
+ "libsensor",
+ "libcrypto",
+ "libbase",
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "android.hardware.sensors@1.0",
+ ],
+
+ static_libs: ["android.hardware.sensors@1.0-convert"],
+
+ // our public headers depend on libsensor
+ export_shared_lib_headers: ["libsensor"],
+}
+
+cc_binary {
+ name: "sensorservice",
+
+ srcs: ["main_sensorservice.cpp"],
+
+ shared_libs: [
+ "libsensorservice",
+ "libbinder",
+ "libutils",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+}
diff --git a/services/sensorservice/Android.mk b/services/sensorservice/Android.mk
deleted file mode 100644
index cfb72310d5..0000000000
--- a/services/sensorservice/Android.mk
+++ /dev/null
@@ -1,73 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- BatteryService.cpp \
- CorrectedGyroSensor.cpp \
- Fusion.cpp \
- GravitySensor.cpp \
- LinearAccelerationSensor.cpp \
- OrientationSensor.cpp \
- RecentEventLogger.cpp \
- RotationVectorSensor.cpp \
- SensorDevice.cpp \
- SensorDirectConnection.cpp \
- SensorEventConnection.cpp \
- SensorFusion.cpp \
- SensorInterface.cpp \
- SensorList.cpp \
- SensorRecord.cpp \
- SensorService.cpp \
- SensorServiceUtils.cpp \
-
-LOCAL_CFLAGS:= -DLOG_TAG=\"SensorService\"
-
-LOCAL_CFLAGS += -Wall -Werror -Wextra
-
-LOCAL_CFLAGS += -fvisibility=hidden
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libhardware \
- libhardware_legacy \
- libutils \
- liblog \
- libbinder \
- libsensor \
- libcrypto \
- libbase \
- libhidlbase \
- libhidltransport \
- libhwbinder \
- android.hardware.sensors@1.0
-
-LOCAL_STATIC_LIBRARIES := \
- android.hardware.sensors@1.0-convert
-
-# our public headers depend on libsensor
-LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
- libsensor \
-
-LOCAL_MODULE:= libsensorservice
-
-include $(BUILD_SHARED_LIBRARY)
-
-#####################################################################
-# build executable
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- main_sensorservice.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libsensorservice \
- libbinder \
- libutils
-
-LOCAL_CFLAGS := -Wall -Werror -Wextra
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE:= sensorservice
-
-include $(BUILD_EXECUTABLE)
diff --git a/services/sensorservice/OWNERS b/services/sensorservice/OWNERS
new file mode 100644
index 0000000000..6a38a1ff14
--- /dev/null
+++ b/services/sensorservice/OWNERS
@@ -0,0 +1,2 @@
+ashutoshj@google.com
+pengxu@google.com
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 7d9b0b730a..da3b2758d1 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -223,8 +223,13 @@ ssize_t SensorDevice::poll(sensors_event_t* buffer, size_t count) {
}
void SensorDevice::autoDisable(void *ident, int handle) {
- Info& info( mActivationCount.editValueFor(handle) );
Mutex::Autolock _l(mLock);
+ ssize_t activationIndex = mActivationCount.indexOfKey(handle);
+ if (activationIndex < 0) {
+ ALOGW("Handle %d cannot be found in activation record", handle);
+ return;
+ }
+ Info& info(mActivationCount.editValueAt(activationIndex));
info.removeBatchParamsForIdent(ident);
}
@@ -235,7 +240,12 @@ status_t SensorDevice::activate(void* ident, int handle, int enabled) {
bool actuateHardware = false;
Mutex::Autolock _l(mLock);
- Info& info( mActivationCount.editValueFor(handle) );
+ ssize_t activationIndex = mActivationCount.indexOfKey(handle);
+ if (activationIndex < 0) {
+ ALOGW("Handle %d cannot be found in activation record", handle);
+ return BAD_VALUE;
+ }
+ Info& info(mActivationCount.editValueAt(activationIndex));
ALOGD_IF(DEBUG_CONNECTIONS,
"SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
@@ -329,7 +339,12 @@ status_t SensorDevice::batch(
ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
Mutex::Autolock _l(mLock);
- Info& info(mActivationCount.editValueFor(handle));
+ ssize_t activationIndex = mActivationCount.indexOfKey(handle);
+ if (activationIndex < 0) {
+ ALOGW("Handle %d cannot be found in activation record", handle);
+ return BAD_VALUE;
+ }
+ Info& info(mActivationCount.editValueAt(activationIndex));
if (info.batchParams.indexOfKey(ident) < 0) {
BatchParams params(samplingPeriodNs, maxBatchReportLatencyNs);
diff --git a/services/sensorservice/SensorDirectConnection.cpp b/services/sensorservice/SensorDirectConnection.cpp
index 870635bf05..538d72822e 100644
--- a/services/sensorservice/SensorDirectConnection.cpp
+++ b/services/sensorservice/SensorDirectConnection.cpp
@@ -27,12 +27,21 @@ SensorService::SensorDirectConnection::SensorDirectConnection(const sp<SensorSer
const String16& opPackageName)
: mService(service), mUid(uid), mMem(*mem),
mHalChannelHandle(halChannelHandle),
- mOpPackageName(opPackageName) {
+ mOpPackageName(opPackageName), mDestroyed(false) {
ALOGD_IF(DEBUG_CONNECTIONS, "Created SensorDirectConnection");
}
SensorService::SensorDirectConnection::~SensorDirectConnection() {
ALOGD_IF(DEBUG_CONNECTIONS, "~SensorDirectConnection %p", this);
+ destroy();
+}
+
+void SensorService::SensorDirectConnection::destroy() {
+ Mutex::Autolock _l(mDestroyLock);
+ // destroy once only
+ if (mDestroyed) {
+ return;
+ }
stopAll();
mService->cleanupConnection(this);
@@ -40,6 +49,7 @@ SensorService::SensorDirectConnection::~SensorDirectConnection() {
native_handle_close(mMem.handle);
native_handle_delete(const_cast<struct native_handle*>(mMem.handle));
}
+ mDestroyed = true;
}
void SensorService::SensorDirectConnection::onFirstRef() {
diff --git a/services/sensorservice/SensorDirectConnection.h b/services/sensorservice/SensorDirectConnection.h
index 27458d4a2f..5c398a8caa 100644
--- a/services/sensorservice/SensorDirectConnection.h
+++ b/services/sensorservice/SensorDirectConnection.h
@@ -47,7 +47,7 @@ public:
// 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);
+ void stopAll(bool backupRecord = false);
// recover sensor reports previously stopped by stopAll(true)
// called by SensorService when return to NORMAL mode.
@@ -63,7 +63,7 @@ protected:
virtual status_t setEventRate(int handle, nsecs_t samplingPeriodNs);
virtual status_t flush();
virtual int32_t configureChannel(int handle, int rateLevel);
-
+ virtual void destroy();
private:
const sp<SensorService> mService;
const uid_t mUid;
@@ -74,6 +74,9 @@ private:
mutable Mutex mConnectionLock;
std::unordered_map<int, int> mActivated;
std::unordered_map<int, int> mActivatedBackup;
+
+ mutable Mutex mDestroyLock;
+ bool mDestroyed;
};
} // namepsace android
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index fad046cf53..0a05dd1b18 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -32,7 +32,8 @@ SensorService::SensorEventConnection::SensorEventConnection(
const String16& opPackageName)
: mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(NULL),
- mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName) {
+ mCacheSize(0), mMaxCacheSize(0), mPackageName(packageName), mOpPackageName(opPackageName),
+ mDestroyed(false) {
mChannel = new BitTube(mService->mSocketBufferSize);
#if DEBUG_CONNECTIONS
mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
@@ -42,10 +43,22 @@ SensorService::SensorEventConnection::SensorEventConnection(
SensorService::SensorEventConnection::~SensorEventConnection() {
ALOGD_IF(DEBUG_CONNECTIONS, "~SensorEventConnection(%p)", this);
+ destroy();
+}
+
+void SensorService::SensorEventConnection::destroy() {
+ Mutex::Autolock _l(mDestroyLock);
+
+ // destroy once only
+ if (mDestroyed) {
+ return;
+ }
+
mService->cleanupConnection(this);
if (mEventCache != NULL) {
delete mEventCache;
}
+ mDestroyed = true;
}
void SensorService::SensorEventConnection::onFirstRef() {
@@ -477,7 +490,14 @@ void SensorService::SensorEventConnection::countFlushCompleteEventsLocked(
// separately before the next batch of events.
for (int j = 0; j < numEventsDropped; ++j) {
if (scratch[j].type == SENSOR_TYPE_META_DATA) {
- FlushInfo& flushInfo = mSensorInfo.editValueFor(scratch[j].meta_data.sensor);
+ ssize_t index = mSensorInfo.indexOfKey(scratch[j].meta_data.sensor);
+ if (index < 0) {
+ ALOGW("%s: sensor 0x%x is not found in connection",
+ __func__, scratch[j].meta_data.sensor);
+ continue;
+ }
+
+ FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
flushInfo.mPendingFlushEventsToSend++;
ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
flushInfo.mPendingFlushEventsToSend);
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index c81e015dbe..6f282cdc60 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -75,6 +75,7 @@ private:
virtual status_t setEventRate(int handle, nsecs_t samplingPeriodNs);
virtual status_t flush();
virtual int32_t configureChannel(int handle, int rateLevel);
+ virtual void destroy();
// 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
@@ -164,6 +165,8 @@ private:
int mTotalAcksNeeded, mTotalAcksReceived;
#endif
+ mutable Mutex mDestroyLock;
+ bool mDestroyed;
};
} // namepsace android
diff --git a/services/sensorservice/SensorList.cpp b/services/sensorservice/SensorList.cpp
index ab08cac2c8..aa306d885e 100644
--- a/services/sensorservice/SensorList.cpp
+++ b/services/sensorservice/SensorList.cpp
@@ -124,14 +124,15 @@ std::string SensorList::dump() const {
forEachSensor([&result] (const Sensor& s) -> bool {
result.appendFormat(
"%#010x) %-25s | %-15s | ver: %" PRId32 " | type: %20s(%" PRId32
- ") | perm: %s\n",
+ ") | perm: %s | flags: 0x%08x\n",
s.getHandle(),
s.getName().string(),
s.getVendor().string(),
s.getVersion(),
s.getStringType().string(),
s.getType(),
- s.getRequiredPermission().size() ? s.getRequiredPermission().string() : "n/a");
+ s.getRequiredPermission().size() ? s.getRequiredPermission().string() : "n/a",
+ static_cast<int>(s.getFlags()));
result.append("\t");
const int reportingMode = s.getReportingMode();
@@ -173,9 +174,14 @@ std::string SensorList::dump() const {
result.appendFormat("non-wakeUp | ");
}
+ if (s.isDataInjectionSupported()) {
+ result.appendFormat("data-injection, ");
+ }
+
if (s.isDynamicSensor()) {
result.appendFormat("dynamic, ");
}
+
if (s.hasAdditionalInfo()) {
result.appendFormat("has-additional-info, ");
}
@@ -190,7 +196,6 @@ std::string SensorList::dump() const {
if (s.isDirectChannelTypeSupported(SENSOR_DIRECT_MEM_TYPE_GRALLOC)) {
result.append("gralloc, ");
}
- result.appendFormat("flag =0x%08x", static_cast<int>(s.getFlags()));
result.append("\n");
}
return true;
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index d60768c98d..dc491d97c0 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -394,6 +394,7 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) {
}
} else if (!mSensors.hasAnySensor()) {
result.append("No Sensors on the device\n");
+ result.appendFormat("devInitCheck : %d\n", SensorDevice::getInstance().initCheck());
} else {
// Default dump the sensor list and debugging information.
//
@@ -932,8 +933,14 @@ sp<ISensorEventConnection> SensorService::createSensorEventConnection(const Stri
}
uid_t uid = IPCThreadState::self()->getCallingUid();
- sp<SensorEventConnection> result(new SensorEventConnection(this, uid, packageName,
- requestedMode == DATA_INJECTION, opPackageName));
+ pid_t pid = IPCThreadState::self()->getCallingPid();
+
+ String8 connPackageName =
+ (packageName == "") ? String8::format("unknown_package_pid_%d", pid) : packageName;
+ String16 connOpPackageName =
+ (opPackageName == String16("")) ? String16(connPackageName) : opPackageName;
+ sp<SensorEventConnection> result(new SensorEventConnection(this, uid, connPackageName,
+ requestedMode == DATA_INJECTION, connOpPackageName));
if (requestedMode == DATA_INJECTION) {
if (mActiveConnections.indexOf(result) < 0) {
mActiveConnections.add(result);
@@ -1032,17 +1039,16 @@ sp<ISensorEventConnection> SensorService::createSensorDirectConnection(
}
int SensorService::setOperationParameter(
- int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints) {
+ int32_t handle, int32_t type,
+ const Vector<float> &floats, const Vector<int32_t> &ints) {
Mutex::Autolock _l(mLock);
- // check permission
- int32_t uid;
- bool hasPermission = checkCallingPermission(sLocationHardwarePermission, nullptr, &uid);
- if (!hasPermission || (uid != 1000 && uid != 0)) {
+ if (!checkCallingPermission(sLocationHardwarePermission, nullptr, nullptr)) {
return PERMISSION_DENIED;
}
bool isFloat = true;
+ bool isCustom = false;
size_t expectSize = INT32_MAX;
switch (type) {
case AINFO_LOCAL_GEOMAGNETIC_FIELD:
@@ -1060,7 +1066,21 @@ int SensorService::setOperationParameter(
expectSize = 1;
break;
default:
- return BAD_VALUE;
+ // CUSTOM events must only contain float data; it may have variable size
+ if (type < AINFO_CUSTOM_START || type >= AINFO_DEBUGGING_START ||
+ ints.size() ||
+ sizeof(additional_info_event_t::data_float)/sizeof(float) < floats.size() ||
+ handle < 0) {
+ return BAD_VALUE;
+ }
+ isFloat = true;
+ isCustom = true;
+ expectSize = floats.size();
+ break;
+ }
+
+ if (!isCustom && handle != -1) {
+ return BAD_VALUE;
}
// three events: first one is begin tag, last one is end tag, the one in the middle
@@ -1070,7 +1090,7 @@ int SensorService::setOperationParameter(
for (sensors_event_t* i = event; i < event + 3; i++) {
*i = (sensors_event_t) {
.version = sizeof(sensors_event_t),
- .sensor = SENSORS_HANDLE_BASE - 1, // sensor that never exists
+ .sensor = handle,
.type = SENSOR_TYPE_ADDITIONAL_INFO,
.timestamp = timestamp++,
.additional_info = (additional_info_event_t) {
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 2a9d6e86ba..3e183942ff 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -159,7 +159,7 @@ private:
virtual sp<ISensorEventConnection> createSensorDirectConnection(const String16& opPackageName,
uint32_t size, int32_t type, int32_t format, const native_handle *resource);
virtual int setOperationParameter(
- int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints);
+ int32_t handle, int32_t type, const Vector<float> &floats, const Vector<int32_t> &ints);
virtual status_t dump(int fd, const Vector<String16>& args);
String8 getSensorName(int handle) const;
diff --git a/services/sensorservice/hidl/Android.bp b/services/sensorservice/hidl/Android.bp
index 8bbc4c59a8..02c13fa579 100644
--- a/services/sensorservice/hidl/Android.bp
+++ b/services/sensorservice/hidl/Android.bp
@@ -14,6 +14,7 @@ cc_library_shared {
"libbase",
"libhidlbase",
"libhidltransport",
+ "libhwbinder",
"libutils",
"libsensor",
"android.frameworks.sensorservice@1.0",
diff --git a/services/sensorservice/hidl/SensorManager.cpp b/services/sensorservice/hidl/SensorManager.cpp
index 25a3dc50d2..fee6da1e60 100644
--- a/services/sensorservice/hidl/SensorManager.cpp
+++ b/services/sensorservice/hidl/SensorManager.cpp
@@ -24,12 +24,14 @@
#include <sched.h>
-#include <thread>
#include "EventQueue.h"
#include "DirectReportChannel.h"
#include "utils.h"
+#include <hwbinder/IPCThreadState.h>
+#include <utils/String8.h>
+
namespace android {
namespace frameworks {
namespace sensorservice {
@@ -40,20 +42,24 @@ using ::android::hardware::sensors::V1_0::SensorInfo;
using ::android::hardware::sensors::V1_0::SensorsEventFormatOffset;
using ::android::hardware::hidl_vec;
using ::android::hardware::Void;
-using ::android::sp;
static const char* POLL_THREAD_NAME = "hidl_ssvc_poll";
SensorManager::SensorManager(JavaVM* vm)
- : mJavaVm(vm) {
+ : mLooper(new Looper(false /*allowNonCallbacks*/)), mStopThread(true), mJavaVm(vm) {
}
SensorManager::~SensorManager() {
// Stops pollAll inside the thread.
- std::unique_lock<std::mutex> lock(mLooperMutex);
+ std::lock_guard<std::mutex> lock(mThreadMutex);
+
+ mStopThread = true;
if (mLooper != nullptr) {
mLooper->wake();
}
+ if (mPollThread.joinable()) {
+ mPollThread.join();
+ }
}
// Methods from ::android::frameworks::sensorservice::V1_0::ISensorManager follow.
@@ -128,12 +134,13 @@ Return<void> SensorManager::createGrallocDirectChannel(
}
/* One global looper for all event queues created from this SensorManager. */
-sp<::android::Looper> SensorManager::getLooper() {
- std::unique_lock<std::mutex> lock(mLooperMutex);
- if (mLooper == nullptr) {
- std::condition_variable looperSet;
+sp<Looper> SensorManager::getLooper() {
+ std::lock_guard<std::mutex> lock(mThreadMutex);
- std::thread{[&mutex = mLooperMutex, &looper = mLooper, &looperSet, javaVm = mJavaVm] {
+ if (!mPollThread.joinable()) {
+ // if thread not initialized, start thread
+ mStopThread = false;
+ std::thread pollThread{[&stopThread = mStopThread, looper = mLooper, javaVm = mJavaVm] {
struct sched_param p = {0};
p.sched_priority = 10;
@@ -142,16 +149,11 @@ sp<::android::Looper> SensorManager::getLooper() {
<< strerror(errno);
}
- std::unique_lock<std::mutex> lock(mutex);
- if (looper != nullptr) {
- LOG(INFO) << "Another thread has already set the looper, exiting this one.";
- return;
- }
- looper = Looper::prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS /* opts */);
- lock.unlock();
+ // set looper
+ Looper::setForThread(looper);
- // Attach the thread to JavaVM so that pollAll do not crash if the event
- // is from Java.
+ // Attach the thread to JavaVM so that pollAll do not crash if the thread
+ // eventually calls into Java.
JavaVMAttachArgs args{
.version = JNI_VERSION_1_2,
.name = POLL_THREAD_NAME,
@@ -162,19 +164,30 @@ sp<::android::Looper> SensorManager::getLooper() {
LOG(FATAL) << "Cannot attach SensorManager looper thread to Java VM.";
}
- looperSet.notify_one();
- int pollResult = looper->pollAll(-1 /* timeout */);
- if (pollResult != ALOOPER_POLL_WAKE) {
- LOG(ERROR) << "Looper::pollAll returns unexpected " << pollResult;
+ LOG(INFO) << POLL_THREAD_NAME << " started.";
+ for (;;) {
+ int pollResult = looper->pollAll(-1 /* timeout */);
+ if (pollResult == Looper::POLL_WAKE) {
+ if (stopThread == true) {
+ LOG(INFO) << POLL_THREAD_NAME << ": requested to stop";
+ break;
+ } else {
+ LOG(INFO) << POLL_THREAD_NAME << ": spurious wake up, back to work";
+ }
+ } else {
+ LOG(ERROR) << POLL_THREAD_NAME << ": Looper::pollAll returns unexpected "
+ << pollResult;
+ break;
+ }
}
if (javaVm->DetachCurrentThread() != JNI_OK) {
LOG(ERROR) << "Cannot detach SensorManager looper thread from Java VM.";
}
- LOG(INFO) << "Looper thread is terminated.";
- }}.detach();
- looperSet.wait(lock, [this]{ return this->mLooper != nullptr; });
+ LOG(INFO) << POLL_THREAD_NAME << " is terminated.";
+ }};
+ mPollThread = std::move(pollThread);
}
return mLooper;
}
@@ -196,7 +209,15 @@ Return<void> SensorManager::createEventQueue(
}
sp<::android::Looper> looper = getLooper();
- sp<::android::SensorEventQueue> internalQueue = getInternalManager().createEventQueue();
+ if (looper == nullptr) {
+ LOG(ERROR) << "::android::SensorManager::createEventQueue cannot initialize looper";
+ _hidl_cb(nullptr, Result::UNKNOWN_ERROR);
+ return Void();
+ }
+
+ String8 package(String8::format("hidl_client_pid_%d",
+ android::hardware::IPCThreadState::self()->getCallingPid()));
+ sp<::android::SensorEventQueue> internalQueue = getInternalManager().createEventQueue(package);
if (internalQueue == nullptr) {
LOG(WARNING) << "::android::SensorManager::createEventQueue returns nullptr.";
_hidl_cb(nullptr, Result::UNKNOWN_ERROR);
diff --git a/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h b/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
index e66c8e5d22..ddcee288e1 100644
--- a/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
+++ b/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
@@ -20,6 +20,7 @@
#include <jni.h>
#include <mutex>
+#include <thread>
#include <android/frameworks/sensorservice/1.0/ISensorManager.h>
#include <android/frameworks/sensorservice/1.0/types.h>
@@ -38,6 +39,7 @@ using ::android::hardware::sensors::V1_0::SensorType;
using ::android::hardware::hidl_handle;
using ::android::hardware::hidl_memory;
using ::android::hardware::Return;
+using ::android::sp;
struct SensorManager final : public ISensorManager {
@@ -54,13 +56,15 @@ struct SensorManager final : public ISensorManager {
private:
// Block until ::android::SensorManager is initialized.
::android::SensorManager& getInternalManager();
- sp<::android::Looper> getLooper();
+ sp<Looper> getLooper();
std::mutex mInternalManagerMutex;
::android::SensorManager* mInternalManager = nullptr; // does not own
+ sp<Looper> mLooper;
- std::mutex mLooperMutex;
- sp<::android::Looper> mLooper;
+ volatile bool mStopThread;
+ std::mutex mThreadMutex; //protects mPollThread
+ std::thread mPollThread;
JavaVM* mJavaVm;
};