Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit beb0dff3 authored by Rocky Fang's avatar Rocky Fang
Browse files

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
parent d41480ea
Loading
Loading
Loading
Loading
+20 −9
Original line number Diff line number Diff line
@@ -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 <condition_variable>
#include <cstddef>
#include <thread>
#include <mutex>
#include <condition_variable>
#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 @@ void SensorDevice::reconnect() {

    mActivationCount.clear();
    mSensorList.clear();
    if (sensorservice_flags::dynamic_sensor_hal_reconnect_handling()) {
        mConnectedDynamicSensors.clear();
    }

    if (mHalWrapper->connect(this)) {
        initializeSensorList();
@@ -342,6 +344,15 @@ void SensorDevice::dump(ProtoOutputStream* proto) const {
    }
}

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];

+2 −0
Original line number Diff line number Diff line
@@ -60,6 +60,8 @@ public:

    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;
+92 −49
Original line number Diff line number Diff line
@@ -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 @@ void SensorService::onFirstRef() {
                    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::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnecti
   }
}

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...");

@@ -1072,7 +1139,7 @@ bool SensorService::threadLoop() {
        ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
        if (count < 0) {
            if (count == DEAD_OBJECT && device.isReconnecting()) {
                device.reconnect();
                handleDeviceReconnection(device);
                continue;
            } else {
                ALOGE("sensor poll failed (%s)", strerror(-count));
@@ -1176,7 +1243,6 @@ bool SensorService::threadLoop() {
                    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 @@ bool SensorService::threadLoop() {
                    }
                } 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...");
+25 −9
Original line number Diff line number Diff line
@@ -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.
@@ -453,6 +452,11 @@ private:
    // 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 @@ private:

    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 @@ private:
    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