diff options
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; }; |