diff --git a/init.hardware.rc b/init.hardware.rc index 4c2711ec..0e9a274e 100644 --- a/init.hardware.rc +++ b/init.hardware.rc @@ -404,6 +404,7 @@ on early-boot chown system system /sys/class/leds/vibrator/device/ctrl_loop chown system system /sys/class/leds/vibrator/device/ol_lra_period chown system system /sys/class/leds/vibrator/device/autocal + chown system system /sys/class/leds/vibrator/device/lp_trigger_effect # Permission for LED driver chown system system /sys/class/leds/red/on_off_ms diff --git a/vibrator/Vibrator.cpp b/vibrator/Vibrator.cpp index b6804dbd..db64bb13 100644 --- a/vibrator/Vibrator.cpp +++ b/vibrator/Vibrator.cpp @@ -63,7 +63,7 @@ using EffectStrength = ::android::hardware::vibrator::V1_0::EffectStrength; Vibrator::Vibrator(std::ofstream&& activate, std::ofstream&& duration, std::ofstream&& state, std::ofstream&& rtpinput, std::ofstream&& mode, std::ofstream&& sequencer, - std::ofstream&& scale, std::ofstream&& ctrlloop) : + std::ofstream&& scale, std::ofstream&& ctrlloop, std::ofstream&& lptrigger) : mActivate(std::move(activate)), mDuration(std::move(duration)), mState(std::move(state)), @@ -71,10 +71,18 @@ Vibrator::Vibrator(std::ofstream&& activate, std::ofstream&& duration, mMode(std::move(mode)), mSequencer(std::move(sequencer)), mScale(std::move(scale)), - mCtrlLoop(std::move(ctrlloop)) { + mCtrlLoop(std::move(ctrlloop)), + mLpTriggerEffect(std::move(lptrigger)) { mClickDuration = property_get_int32("ro.vibrator.hal.click.duration", WAVEFORM_CLICK_EFFECT_MS); mTickDuration = property_get_int32("ro.vibrator.hal.tick.duration", WAVEFORM_TICK_EFFECT_MS); + + // This enables effect #1 from the waveform library to be triggered by SLPI + // while the AP is in suspend mode + mLpTriggerEffect << 1 << std::endl; + if (!mLpTriggerEffect) { + ALOGW("Failed to set LP trigger mode (%d): %s", errno, strerror(errno)); + } } Return Vibrator::on(uint32_t timeoutMs, bool forceOpenLoop, bool isWaveform) { diff --git a/vibrator/Vibrator.h b/vibrator/Vibrator.h index 920fb3e6..82d4da20 100644 --- a/vibrator/Vibrator.h +++ b/vibrator/Vibrator.h @@ -32,7 +32,7 @@ public: Vibrator(std::ofstream&& activate, std::ofstream&& duration, std::ofstream&& state, std::ofstream&& rtpinput, std::ofstream&& mode, std::ofstream&& sequencer, - std::ofstream&& scale, std::ofstream&& ctrlloop); + std::ofstream&& scale, std::ofstream&& ctrlloop, std::ofstream&& lptrigger); // Methods from ::android::hardware::vibrator::V1_0::IVibrator follow. using Status = ::android::hardware::vibrator::V1_0::Status; @@ -56,6 +56,7 @@ private: std::ofstream mSequencer; std::ofstream mScale; std::ofstream mCtrlLoop; + std::ofstream mLpTriggerEffect; int32_t mClickDuration; int32_t mTickDuration; }; diff --git a/vibrator/service.cpp b/vibrator/service.cpp index 44577d73..c3af647b 100644 --- a/vibrator/service.cpp +++ b/vibrator/service.cpp @@ -39,6 +39,7 @@ static constexpr char MODE_PATH[] = "/sys/class/leds/vibrator/device/mode"; static constexpr char SEQUENCER_PATH[] = "/sys/class/leds/vibrator/device/set_sequencer"; static constexpr char SCALE_PATH[] = "/sys/class/leds/vibrator/device/scale"; static constexpr char CTRL_LOOP_PATH[] = "/sys/class/leds/vibrator/device/ctrl_loop"; +static constexpr char LP_TRIGGER_PATH[] = "/sys/class/leds/vibrator/device/lp_trigger_effect"; // File path to the calibration file static constexpr char CALIBRATION_FILEPATH[] = "/persist/haptics/drv2624.cal"; @@ -178,13 +179,19 @@ status_t registerVibratorService() { ALOGW("Failed to open %s (%d): %s", CTRL_LOOP_PATH, error, strerror(error)); } + std::ofstream lptrigger{LP_TRIGGER_PATH}; + if (!lptrigger) { + int error = errno; + ALOGW("Failed to open %s (%d): %s", LP_TRIGGER_PATH, error, strerror(error)); + } + if (!loadCalibrationData()) { ALOGW("Failed load calibration data"); } sp vibrator = new Vibrator(std::move(activate), std::move(duration), std::move(state), std::move(rtpinput), std::move(mode), - std::move(sequencer), std::move(scale), std::move(ctrlloop)); + std::move(sequencer), std::move(scale), std::move(ctrlloop), std::move(lptrigger)); vibrator->registerAsService();