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

Commit c160815b authored by Anthony Stange's avatar Anthony Stange
Browse files

Refactor sensor service mode changing logic

Bug: 262573975
Test: Verify mode switching continues to work
Change-Id: I66e42c72fea990fd5f634d29678cc6576c3962c0
parent cd01ec10
Loading
Loading
Loading
Loading
+104 −72
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@

#include <ctime>
#include <future>
#include <string>

#include <private/android_filesystem_config.h>

@@ -548,80 +549,22 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) {
        if (args.size() > 2) {
           return INVALID_OPERATION;
        }
        ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
        SensorDevice& dev(SensorDevice::getInstance());
        if (args.size() == 2 && args[0] == String16("restrict")) {
            // If already in restricted mode. Ignore.
            if (mCurrentOperatingMode == RESTRICTED) {
                return status_t(NO_ERROR);
            }
            // If in any mode other than normal, ignore.
            if (mCurrentOperatingMode != NORMAL) {
                return INVALID_OPERATION;
            }

            mCurrentOperatingMode = RESTRICTED;
            // temporarily stop all sensor direct report and disable sensors
            disableAllSensorsLocked(&connLock);
            mAllowListedPackage.setTo(String8(args[1]));
            return status_t(NO_ERROR);
        } else if (args.size() == 1 && args[0] == String16("enable")) {
            // If currently in restricted mode, reset back to NORMAL mode else ignore.
            if (mCurrentOperatingMode == RESTRICTED) {
                mCurrentOperatingMode = NORMAL;
                // enable sensors and recover all sensor direct report
                enableAllSensorsLocked(&connLock);
            }
            if (mCurrentOperatingMode == REPLAY_DATA_INJECTION) {
                dev.disableAllSensors();
            }
            if (mCurrentOperatingMode == DATA_INJECTION ||
                    mCurrentOperatingMode == REPLAY_DATA_INJECTION) {
               resetToNormalModeLocked();
            }
            mAllowListedPackage.clear();
            return status_t(NO_ERROR);
        } else if (args.size() == 2 && args[0] == String16("data_injection")) {
            if (mCurrentOperatingMode == NORMAL) {
                dev.disableAllSensors();
                status_t err = dev.setMode(DATA_INJECTION);
                if (err == NO_ERROR) {
                    mCurrentOperatingMode = DATA_INJECTION;
                } else {
                    // Re-enable sensors.
                    dev.enableAllSensors();
                }
                mAllowListedPackage.setTo(String8(args[1]));
                return NO_ERROR;
            } else if (mCurrentOperatingMode == DATA_INJECTION) {
                // Already in DATA_INJECTION mode. Treat this as a no_op.
                return NO_ERROR;
            } else {
                // Transition to data injection mode supported only from NORMAL mode.
                return INVALID_OPERATION;
        if (args.size() > 0) {
            Mode targetOperatingMode = NORMAL;
            std::string inputStringMode = String8(args[0]).string();
            if (getTargetOperatingMode(inputStringMode, &targetOperatingMode)) {
              status_t error = changeOperatingMode(args, targetOperatingMode);
              // Dump the latest state only if no error was encountered.
              if (error != NO_ERROR) {
                return error;
              }
        } else if (args.size() == 2 && args[0] == String16("replay_data_injection")
                   && !SensorServiceUtil::isUserBuild()) {
            if (mCurrentOperatingMode == NORMAL) {
                dev.disableAllSensors();
                // Use DATA_INJECTION here since this value goes to the HAL and the HAL doesn't
                // have an understanding of replay vs. normal data injection.
                status_t err = dev.setMode(DATA_INJECTION);
                if (err == NO_ERROR) {
                    mCurrentOperatingMode = REPLAY_DATA_INJECTION;
            }
                // Re-enable sensors.
                dev.enableAllSensors();
                mAllowListedPackage.setTo(String8(args[1]));
                return NO_ERROR;
            } else if (mCurrentOperatingMode == REPLAY_DATA_INJECTION) {
                // Already in REPLAY_DATA_INJECTION mode. Treat this as a no_op.
                return NO_ERROR;
            } else {
                // Transition to data injection mode supported only from NORMAL mode.
                return INVALID_OPERATION;
        }
        } else if (args.size() == 1 && args[0] == String16("--proto")) {

        ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
        // Run the following logic if a transition isn't requested above based on the input
        // argument parsing.
        if (args.size() == 1 && args[0] == String16("--proto")) {
            return dumpProtoLocked(fd, &connLock);
        } else if (!mSensors.hasAnySensor()) {
            result.append("No Sensors on the device\n");
@@ -2266,6 +2209,95 @@ void SensorService::resetTargetSdkVersionCache(const String16& opPackageName) {
    }
}

bool SensorService::getTargetOperatingMode(const std::string &inputString, Mode *targetModeOut) {
    if (inputString == std::string("restrict")) {
      *targetModeOut = RESTRICTED;
      return true;
    }
    if (inputString == std::string("enable")) {
      *targetModeOut = NORMAL;
      return true;
    }
    if (inputString == std::string("data_injection")) {
      *targetModeOut = DATA_INJECTION;
      return true;
    }
    if (inputString == std::string("replay_data_injection")) {
      *targetModeOut = REPLAY_DATA_INJECTION;
      return true;
    }
    return false;
}

status_t SensorService::changeOperatingMode(const Vector<String16>& args,
                                            Mode targetOperatingMode) {
    ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
    SensorDevice& dev(SensorDevice::getInstance());
    if (mCurrentOperatingMode == targetOperatingMode) {
        return NO_ERROR;
    }
    if (targetOperatingMode != NORMAL && args.size() < 2) {
        return INVALID_OPERATION;
    }
    switch (targetOperatingMode) {
      case NORMAL:
        // If currently in restricted mode, reset back to NORMAL mode else ignore.
        if (mCurrentOperatingMode == RESTRICTED) {
            mCurrentOperatingMode = NORMAL;
            // enable sensors and recover all sensor direct report
            enableAllSensorsLocked(&connLock);
        }
        if (mCurrentOperatingMode == REPLAY_DATA_INJECTION) {
            dev.disableAllSensors();
        }
        if (mCurrentOperatingMode == DATA_INJECTION ||
                mCurrentOperatingMode == REPLAY_DATA_INJECTION) {
          resetToNormalModeLocked();
        }
        mAllowListedPackage.clear();
        return status_t(NO_ERROR);
      case RESTRICTED:
        // If in any mode other than normal, ignore.
        if (mCurrentOperatingMode != NORMAL) {
            return INVALID_OPERATION;
        }

        mCurrentOperatingMode = RESTRICTED;
        // temporarily stop all sensor direct report and disable sensors
        disableAllSensorsLocked(&connLock);
        mAllowListedPackage.setTo(String8(args[1]));
        return status_t(NO_ERROR);
      case REPLAY_DATA_INJECTION:
        if (SensorServiceUtil::isUserBuild()) {
            return INVALID_OPERATION;
        }
        FALLTHROUGH_INTENDED;
      case DATA_INJECTION:
        if (mCurrentOperatingMode == NORMAL) {
            dev.disableAllSensors();
            // Always use DATA_INJECTION here since this value goes to the HAL and the HAL
            // doesn't have an understanding of replay vs. normal data injection.
            status_t err = dev.setMode(DATA_INJECTION);
            if (err == NO_ERROR) {
                mCurrentOperatingMode = targetOperatingMode;
            }
            if (err != NO_ERROR || targetOperatingMode == REPLAY_DATA_INJECTION) {
                // Re-enable sensors.
                dev.enableAllSensors();
            }
            mAllowListedPackage.setTo(String8(args[1]));
            return NO_ERROR;
        } else {
            // Transition to data injection mode supported only from NORMAL mode.
            return INVALID_OPERATION;
        }
        break;
      default:
        break;
    }
    return NO_ERROR;
}

void SensorService::checkWakeLockState() {
    ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
    checkWakeLockStateLocked(&connLock);
+3 −0
Original line number Diff line number Diff line
@@ -398,6 +398,9 @@ private:
    static bool hasPermissionForSensor(const Sensor& sensor);
    static int getTargetSdkVersion(const String16& opPackageName);
    static void resetTargetSdkVersionCache(const String16& opPackageName);
    // Checks if the provided target operating mode is valid and returns the enum if it is.
    static bool getTargetOperatingMode(const std::string &inputString, Mode *targetModeOut);
    status_t changeOperatingMode(const Vector<String16>& args, Mode targetOperatingMode);
    // SensorService acquires a partial wakelock for delivering events from wake up sensors. This
    // method checks whether all the events from these wake up sensors have been delivered to the
    // corresponding applications, if yes the wakelock is released.