Clear dynamic sensors during reconnect
Test: on device test, not see the crash reported.
Test: Enable logs on sensor notification service and see dynamic sensor
broadcast event after HAL crashes.
Fixes 307782607
Change-Id: I18ff67a86e8bf4da00aceb46bbab9714c7239ae8
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 45fab7e..8e9dfea 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -16,13 +16,6 @@
#include "SensorDevice.h"
-#include "android/hardware/sensors/2.0/types.h"
-#include "android/hardware/sensors/2.1/types.h"
-#include "convertV2_1.h"
-
-#include "AidlSensorHalWrapper.h"
-#include "HidlSensorHalWrapper.h"
-
#include <android-base/logging.h>
#include <android/util/ProtoOutputStream.h>
#include <com_android_frameworks_sensorservice_flags.h>
@@ -36,10 +29,16 @@
#include <chrono>
#include <cinttypes>
-#include <cstddef>
-#include <thread>
-#include <mutex>
#include <condition_variable>
+#include <cstddef>
+#include <mutex>
+#include <thread>
+
+#include "AidlSensorHalWrapper.h"
+#include "HidlSensorHalWrapper.h"
+#include "android/hardware/sensors/2.0/types.h"
+#include "android/hardware/sensors/2.1/types.h"
+#include "convertV2_1.h"
using namespace android::hardware::sensors;
using android::util::ProtoOutputStream;
@@ -168,6 +167,9 @@
mActivationCount.clear();
mSensorList.clear();
+ if (sensorservice_flags::dynamic_sensor_hal_reconnect_handling()) {
+ mConnectedDynamicSensors.clear();
+ }
if (mHalWrapper->connect(this)) {
initializeSensorList();
@@ -342,6 +344,15 @@
}
}
+std::vector<int32_t> SensorDevice::getDynamicSensorHandles() {
+ std::vector<int32_t> sensorHandles;
+ std::lock_guard<std::mutex> lock(mDynamicSensorsMutex);
+ for (auto& sensors : mConnectedDynamicSensors) {
+ sensorHandles.push_back(sensors.first);
+ }
+ return sensorHandles;
+}
+
ssize_t SensorDevice::getSensorList(sensor_t const** list) {
*list = &mSensorList[0];
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index f127c0f..52f7cf2 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -60,6 +60,8 @@
ssize_t getSensorList(sensor_t const** list);
+ std::vector<int32_t> getDynamicSensorHandles();
+
void handleDynamicSensorConnection(int handle, bool connected);
status_t initCheck() const;
int getHalDeviceVersion() const;
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 85043c9..e1c43c6 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -13,6 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include "SensorService.h"
+
#include <aidl/android/hardware/sensors/ISensors.h>
#include <android-base/strings.h>
#include <android/content/pm/IPackageManagerNative.h>
@@ -22,20 +24,36 @@
#include <binder/IServiceManager.h>
#include <binder/PermissionCache.h>
#include <binder/PermissionController.h>
+#include <com_android_frameworks_sensorservice_flags.h>
#include <cutils/ashmem.h>
#include <cutils/misc.h>
#include <cutils/properties.h>
#include <frameworks/base/core/proto/android/service/sensor_service.proto.h>
#include <hardware/sensors.h>
#include <hardware_legacy/power.h>
+#include <inttypes.h>
#include <log/log.h>
+#include <math.h>
#include <openssl/digest.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>
+#include <private/android_filesystem_config.h>
+#include <sched.h>
#include <sensor/SensorEventQueue.h>
#include <sensorprivacy/SensorPrivacyManager.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
#include <utils/SystemClock.h>
+#include <condition_variable>
+#include <ctime>
+#include <future>
+#include <mutex>
+#include <string>
+
#include "BatteryService.h"
#include "CorrectedGyroSensor.h"
#include "GravitySensor.h"
@@ -43,35 +61,17 @@
#include "LinearAccelerationSensor.h"
#include "OrientationSensor.h"
#include "RotationVectorSensor.h"
-#include "SensorFusion.h"
-#include "SensorInterface.h"
-
-#include "SensorService.h"
#include "SensorDirectConnection.h"
#include "SensorEventAckReceiver.h"
#include "SensorEventConnection.h"
+#include "SensorFusion.h"
+#include "SensorInterface.h"
#include "SensorRecord.h"
#include "SensorRegistrationInfo.h"
#include "SensorServiceUtils.h"
-#include <inttypes.h>
-#include <math.h>
-#include <sched.h>
-#include <stdint.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <condition_variable>
-#include <ctime>
-#include <future>
-#include <mutex>
-#include <string>
-
-#include <private/android_filesystem_config.h>
-
using namespace std::chrono_literals;
+namespace sensorservice_flags = com::android::frameworks::sensorservice::flags;
namespace android {
// ---------------------------------------------------------------------------
@@ -335,6 +335,11 @@
case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
hasGyroUncalibrated = true;
break;
+ case SENSOR_TYPE_DYNAMIC_SENSOR_META:
+ if (sensorservice_flags::dynamic_sensor_hal_reconnect_handling()) {
+ mDynamicMetaSensorHandle = list[i].handle;
+ }
+ break;
case SENSOR_TYPE_GRAVITY:
case SENSOR_TYPE_LINEAR_ACCELERATION:
case SENSOR_TYPE_ROTATION_VECTOR:
@@ -1055,6 +1060,68 @@
}
}
+void SensorService::sendEventsToAllClients(
+ const std::vector<sp<SensorEventConnection>>& activeConnections,
+ ssize_t count) {
+ // Send our events to clients. Check the state of wake lock for each client
+ // and release the lock if none of the clients need it.
+ bool needsWakeLock = false;
+ for (const sp<SensorEventConnection>& connection : activeConnections) {
+ connection->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
+ mMapFlushEventsToConnections);
+ needsWakeLock |= connection->needsWakeLock();
+ // If the connection has one-shot sensors, it may be cleaned up after
+ // first trigger. Early check for one-shot sensors.
+ if (connection->hasOneShotSensors()) {
+ cleanupAutoDisabledSensorLocked(connection, mSensorEventBuffer, count);
+ }
+ }
+
+ if (mWakeLockAcquired && !needsWakeLock) {
+ setWakeLockAcquiredLocked(false);
+ }
+}
+
+void SensorService::disconnectDynamicSensor(
+ int handle,
+ const std::vector<sp<SensorEventConnection>>& activeConnections) {
+ ALOGI("Dynamic sensor handle 0x%x disconnected", handle);
+ SensorDevice::getInstance().handleDynamicSensorConnection(
+ handle, false /*connected*/);
+ if (!unregisterDynamicSensorLocked(handle)) {
+ ALOGE("Dynamic sensor release error.");
+ }
+ for (const sp<SensorEventConnection>& connection : activeConnections) {
+ connection->removeSensor(handle);
+ }
+}
+
+void SensorService::handleDeviceReconnection(SensorDevice& device) {
+ if (sensorservice_flags::dynamic_sensor_hal_reconnect_handling()) {
+ const std::vector<sp<SensorEventConnection>> activeConnections =
+ mConnectionHolder.lock(mLock).getActiveConnections();
+
+ for (int32_t handle : device.getDynamicSensorHandles()) {
+ if (mDynamicMetaSensorHandle.has_value()) {
+ // Sending one event at a time to prevent the number of handle is more than the
+ // buffer can hold.
+ mSensorEventBuffer[0].type = SENSOR_TYPE_DYNAMIC_SENSOR_META;
+ mSensorEventBuffer[0].sensor = *mDynamicMetaSensorHandle;
+ mSensorEventBuffer[0].dynamic_sensor_meta.connected = false;
+ mSensorEventBuffer[0].dynamic_sensor_meta.handle = handle;
+ mMapFlushEventsToConnections[0] = nullptr;
+
+ disconnectDynamicSensor(handle, activeConnections);
+ sendEventsToAllClients(activeConnections, 1);
+ } else {
+ ALOGE("Failed to find mDynamicMetaSensorHandle during init.");
+ break;
+ }
+ }
+ }
+ device.reconnect();
+}
+
bool SensorService::threadLoop() {
ALOGD("nuSensorService thread starting...");
@@ -1071,8 +1138,8 @@
do {
ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
if (count < 0) {
- if(count == DEAD_OBJECT && device.isReconnecting()) {
- device.reconnect();
+ if (count == DEAD_OBJECT && device.isReconnecting()) {
+ handleDeviceReconnection(device);
continue;
} else {
ALOGE("sensor poll failed (%s)", strerror(-count));
@@ -1176,7 +1243,6 @@
rec->removeFirstPendingFlushConnection();
}
}
-
// handle dynamic sensor meta events, process registration and unregistration of dynamic
// sensor based on content of event.
if (mSensorEventBuffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) {
@@ -1206,37 +1272,14 @@
}
} else {
int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle;
- ALOGI("Dynamic sensor handle 0x%x disconnected", handle);
-
- device.handleDynamicSensorConnection(handle, false /*connected*/);
- if (!unregisterDynamicSensorLocked(handle)) {
- ALOGE("Dynamic sensor release error.");
- }
-
- for (const sp<SensorEventConnection>& connection : activeConnections) {
- connection->removeSensor(handle);
- }
+ disconnectDynamicSensor(handle, activeConnections);
}
}
}
// Send our events to clients. Check the state of wake lock for each client and release the
// lock if none of the clients need it.
- bool needsWakeLock = false;
- for (const sp<SensorEventConnection>& connection : activeConnections) {
- connection->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,
- mMapFlushEventsToConnections);
- needsWakeLock |= connection->needsWakeLock();
- // If the connection has one-shot sensors, it may be cleaned up after first trigger.
- // Early check for one-shot sensors.
- if (connection->hasOneShotSensors()) {
- cleanupAutoDisabledSensorLocked(connection, mSensorEventBuffer, count);
- }
- }
-
- if (mWakeLockAcquired && !needsWakeLock) {
- setWakeLockAcquiredLocked(false);
- }
+ sendEventsToAllClients(activeConnections, count);
} while (!Thread::exitPending());
ALOGW("Exiting SensorService::threadLoop => aborting...");
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index b643f6b..ad10e7a 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -17,9 +17,6 @@
#ifndef ANDROID_SENSOR_SERVICE_H
#define ANDROID_SENSOR_SERVICE_H
-#include "SensorList.h"
-#include "RecentEventLogger.h"
-
#include <android-base/macros.h>
#include <binder/AppOpsManager.h>
#include <binder/BinderService.h>
@@ -27,11 +24,11 @@
#include <cutils/compiler.h>
#include <cutils/multiuser.h>
#include <private/android_filesystem_config.h>
-#include <sensor/ISensorServer.h>
#include <sensor/ISensorEventConnection.h>
+#include <sensor/ISensorServer.h>
#include <sensor/Sensor.h>
-#include "android/hardware/BnSensorPrivacyListener.h"
-
+#include <stdint.h>
+#include <sys/types.h>
#include <utils/AndroidThreads.h>
#include <utils/KeyedVector.h>
#include <utils/Looper.h>
@@ -40,8 +37,6 @@
#include <utils/Vector.h>
#include <utils/threads.h>
-#include <stdint.h>
-#include <sys/types.h>
#include <condition_variable>
#include <mutex>
#include <queue>
@@ -49,6 +44,10 @@
#include <unordered_set>
#include <vector>
+#include "RecentEventLogger.h"
+#include "SensorList.h"
+#include "android/hardware/BnSensorPrivacyListener.h"
+
#if __clang__
// Clang warns about SensorEventConnection::dump hiding BBinder::dump. The cause isn't fixable
// without changing the API, so let's tell clang this is indeed intentional.
@@ -57,7 +56,7 @@
// ---------------------------------------------------------------------------
#define IGNORE_HARDWARE_FUSION false
-#define DEBUG_CONNECTIONS false
+#define DEBUG_CONNECTIONS false
// Max size is 100 KB which is enough to accept a batch of about 1000 events.
#define MAX_SOCKET_BUFFER_SIZE_BATCHED (100 * 1024)
// For older HALs which don't support batching, use a smaller socket buffer size.
@@ -453,6 +452,11 @@
// Send events from the event cache for this particular connection.
void sendEventsFromCache(const sp<SensorEventConnection>& connection);
+ // Send all events in the buffer to all clients.
+ void sendEventsToAllClients(
+ const std::vector<sp<SensorEventConnection>>& activeConnections,
+ ssize_t count);
+
// If SensorService is operating in RESTRICTED mode, only select whitelisted packages are
// allowed to register for or call flush on sensors. Typically only cts test packages are
// allowed.
@@ -516,6 +520,14 @@
bool isInjectionMode(int mode);
+ void handleDeviceReconnection(SensorDevice& device);
+
+ // Removes a connected dynamic sensor and send the corresponding event to
+ // all connections.
+ void disconnectDynamicSensor(
+ int handle,
+ const std::vector<sp<SensorEventConnection>>& activeConnections);
+
static inline bool isAudioServerOrSystemServerUid(uid_t uid) {
return multiuser_get_app_id(uid) == AID_SYSTEM || uid == AID_AUDIOSERVER;
}
@@ -583,6 +595,10 @@
bool mLastReportedProxIsActive;
// Listeners subscribed to receive updates on the proximity sensor active state.
std::vector<sp<ProximityActiveListener>> mProximityActiveListeners;
+
+ // Stores the handle of the dynamic_meta sensor to send clean up event once
+ // HAL crashes.
+ std::optional<int> mDynamicMetaSensorHandle;
};
} // namespace android