mediatek: vibrator: Make strength relative to kernel reported maximum
* Different devices will have different maximum intensities of
  strength that their vibrators can support.
* Make the strength relative to the maximum strength reported by the
  kernel, so that the it can work on many devices without needing
  modifications.

Signed-off-by: bengris32 <bengris32@protonmail.ch>
Change-Id: I1eba5b1649e271aae4672bda8dd2f6293952060a
diff --git a/vibrator/Vibrator.cpp b/vibrator/Vibrator.cpp
index 842ae87..3295042 100644
--- a/vibrator/Vibrator.cpp
+++ b/vibrator/Vibrator.cpp
@@ -26,7 +26,10 @@
 namespace vibrator {
 
 Vibrator::Vibrator() {
-    mVibratorStrengthSupported = nodeExists(kVibratorStrength);
+    if (nodeExists(kVibratorStrength)) {
+        mVibratorStrengthSupported = true;
+        mVibratorStrengthMax = getNode(kVibratorStrengthMax, 9);
+    }
 }
 
 ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) {
@@ -80,7 +83,9 @@
         return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
 
     if (mVibratorStrengthSupported) {
-        status = setNode(kVibratorStrength, vibStrengths[strength]);
+        // Vibration strength is relative to the max strength reported by the kernel.
+        int vib_strength = static_cast<int>(mVibratorStrengthMax * vibStrengths[strength] / 10.0 + 0.5);
+        status = setNode(kVibratorStrength, vib_strength);
         if (!status.isOk())
             return status;
     }
@@ -210,6 +215,22 @@
     return setNode(path, std::to_string(value));
 }
 
+/*
+ * Read integer from path
+ */
+int Vibrator::getNode(const std::string path, const int fallback) {
+    std::ifstream file(path);
+    int value;
+
+    if (!file.is_open()) {
+        LOG(ERROR) << "failed to read from " << path.c_str();
+        return fallback;
+    }
+
+    file >> value;
+    return value;
+}
+
 bool Vibrator::nodeExists(const std::string path) {
     std::ofstream file(path);
     return file.is_open();
diff --git a/vibrator/include/vibrator-impl/Vibrator.h b/vibrator/include/vibrator-impl/Vibrator.h
index 25b4a77..555d1f8 100644
--- a/vibrator/include/vibrator-impl/Vibrator.h
+++ b/vibrator/include/vibrator-impl/Vibrator.h
@@ -24,10 +24,11 @@
 namespace hardware {
 namespace vibrator {
 
-const std::string kVibratorState    = "/sys/class/leds/vibrator/state";
-const std::string kVibratorDuration = "/sys/class/leds/vibrator/duration";
-const std::string kVibratorActivate = "/sys/class/leds/vibrator/activate";
-const std::string kVibratorStrength = "/sys/kernel/thunderquake_engine/level";
+const std::string kVibratorState       = "/sys/class/leds/vibrator/state";
+const std::string kVibratorDuration    = "/sys/class/leds/vibrator/duration";
+const std::string kVibratorActivate    = "/sys/class/leds/vibrator/activate";
+const std::string kVibratorStrength    = "/sys/kernel/thunderquake_engine/level";
+const std::string kVibratorStrengthMax = "/sys/kernel/thunderquake_engine/max";
 
 static std::map<Effect, int32_t> vibEffects = {
     { Effect::CLICK, 50 },
@@ -37,9 +38,9 @@
 };
 
 static std::map<EffectStrength, int32_t> vibStrengths = {
-    { EffectStrength::LIGHT, 5},
-    { EffectStrength::MEDIUM, 7},
-    { EffectStrength::STRONG, 11}
+    { EffectStrength::LIGHT, 4},
+    { EffectStrength::MEDIUM, 6},
+    { EffectStrength::STRONG, 10}
 };
 
 class Vibrator : public BnVibrator {
@@ -79,10 +80,12 @@
 private:
     static ndk::ScopedAStatus setNode(const std::string path, const std::string value);
     static ndk::ScopedAStatus setNode(const std::string path, const int32_t value);
+    static int getNode(const std::string path, const int fallback);
     static bool nodeExists(const std::string path);
 
     ndk::ScopedAStatus activate(const int32_t timeoutMs);
     bool mVibratorStrengthSupported;
+    int mVibratorStrengthMax;
 };
 
 }  // namespace vibrator