diff options
| author | 2017-09-23 00:17:10 +0000 | |
|---|---|---|
| committer | 2017-09-23 00:17:10 +0000 | |
| commit | 4f33ab9eff361a2d4fd5f07b18ecda4c79f33c88 (patch) | |
| tree | 1423523ee3333ea7428b15767b329f5491ae349f | |
| parent | 8260e06c5095c7688eaede8b8f6d0889a57c7c6b (diff) | |
| parent | 4acb1999f31f633e5b72b4f4e9d2c41b0b12cd65 (diff) | |
Merge changes from topic "equalizer"
* changes:
Initialize native Sensor object correctly
Clarify sensor NDK struct has to be backward compatible
[sensor] Clarify sequence requirement between setEventRate and enable
sensorservice: Android.mk -> Android.bp
Checking exisitence before calling editValueFor in SensorDevice
Adding package name for HIDL connection and default package name
Fix hidl_ssvc_poll thread issues
Use appendFormat instead of append when passing arguments
Synchronous resource recover mechanism for ISensorEventConnection
Check key before edit value in countFlushCompleteEventsLocked
Support custom permission, slight adjust of dumpsys print
sensors: pass sensor handle along with injected event
Adding OWNERS files for services/sensorservice, libs/sensor
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; }; |