Support combined vibration effects with input device.

Support combined vibration effects with multi-channel FF effect input
device.

Bug: 161629089
Test: atest InputDeviceVibratorTest
Change-Id: I566f6cdd601f716b34c2f70e3705340ef8906897
diff --git a/services/inputflinger/reader/mapper/InputMapper.cpp b/services/inputflinger/reader/mapper/InputMapper.cpp
index 1db829f..913cef7 100644
--- a/services/inputflinger/reader/mapper/InputMapper.cpp
+++ b/services/inputflinger/reader/mapper/InputMapper.cpp
@@ -56,11 +56,18 @@
     return false;
 }
 
-void InputMapper::vibrate(const std::vector<VibrationElement>& pattern, ssize_t repeat,
-                          int32_t token) {}
+void InputMapper::vibrate(const VibrationSequence& sequence, ssize_t repeat, int32_t token) {}
 
 void InputMapper::cancelVibrate(int32_t token) {}
 
+bool InputMapper::isVibrating() {
+    return false;
+}
+
+std::vector<int32_t> InputMapper::getVibratorIds() {
+    return {};
+}
+
 void InputMapper::cancelTouch(nsecs_t when) {}
 
 int32_t InputMapper::getMetaState() {
diff --git a/services/inputflinger/reader/mapper/InputMapper.h b/services/inputflinger/reader/mapper/InputMapper.h
index 56ab928..088dbd8 100644
--- a/services/inputflinger/reader/mapper/InputMapper.h
+++ b/services/inputflinger/reader/mapper/InputMapper.h
@@ -63,9 +63,10 @@
     virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
     virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
                                        const int32_t* keyCodes, uint8_t* outFlags);
-    virtual void vibrate(const std::vector<VibrationElement>& pattern, ssize_t repeat,
-                         int32_t token);
+    virtual void vibrate(const VibrationSequence& sequence, ssize_t repeat, int32_t token);
     virtual void cancelVibrate(int32_t token);
+    virtual bool isVibrating();
+    virtual std::vector<int32_t> getVibratorIds();
     virtual void cancelTouch(nsecs_t when);
 
     virtual int32_t getMetaState();
diff --git a/services/inputflinger/reader/mapper/VibratorInputMapper.cpp b/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
index ac7c266..f25e59a 100644
--- a/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
@@ -21,7 +21,7 @@
 namespace android {
 
 VibratorInputMapper::VibratorInputMapper(InputDeviceContext& deviceContext)
-      : InputMapper(deviceContext), mVibrating(false) {}
+      : InputMapper(deviceContext), mVibrating(false), mSequence(0) {}
 
 VibratorInputMapper::~VibratorInputMapper() {}
 
@@ -39,17 +39,15 @@
     // TODO: Handle FF_STATUS, although it does not seem to be widely supported.
 }
 
-void VibratorInputMapper::vibrate(const std::vector<VibrationElement>& pattern, ssize_t repeat,
+void VibratorInputMapper::vibrate(const VibrationSequence& sequence, ssize_t repeat,
                                   int32_t token) {
 #if DEBUG_VIBRATOR
-    std::string patternStr;
-    dumpPattern(patternStr);
     ALOGD("vibrate: deviceId=%d, pattern=[%s], repeat=%zd, token=%d", getDeviceId(),
-          patternStr.c_str(), repeat, token);
+          sequence.toString().c_str(), repeat, token);
 #endif
 
     mVibrating = true;
-    mPattern = pattern;
+    mSequence = sequence;
     mRepeat = repeat;
     mToken = token;
     mIndex = -1;
@@ -67,6 +65,14 @@
     }
 }
 
+bool VibratorInputMapper::isVibrating() {
+    return mVibrating;
+}
+
+std::vector<int32_t> VibratorInputMapper::getVibratorIds() {
+    return getDeviceContext().getVibratorIds();
+}
+
 void VibratorInputMapper::timeoutExpired(nsecs_t when) {
     if (mVibrating) {
         if (when >= mNextStepTime) {
@@ -79,7 +85,7 @@
 
 void VibratorInputMapper::nextStep() {
     mIndex += 1;
-    if (size_t(mIndex) >= mPattern.size()) {
+    if (size_t(mIndex) >= mSequence.pattern.size()) {
         if (mRepeat < 0) {
             // We are done.
             stopVibrating();
@@ -88,7 +94,7 @@
         mIndex = mRepeat;
     }
 
-    const VibrationElement& element = mPattern[mIndex];
+    const VibrationElement& element = mSequence.pattern[mIndex];
     if (element.isOn()) {
 #if DEBUG_VIBRATOR
         std::string description = element.toString();
@@ -125,23 +131,10 @@
     dump += StringPrintf(INDENT3 "Vibrating: %s\n", toString(mVibrating));
     if (mVibrating) {
         dump += INDENT3 "Pattern: ";
-        dumpPattern(dump);
+        dump += mSequence.toString();
         dump += "\n";
         dump += StringPrintf(INDENT3 "Repeat Index: %zd\n", mRepeat);
     }
 }
 
-void VibratorInputMapper::dumpPattern(std::string& dump) const {
-    dump += "[";
-
-    for (auto it = mPattern.begin(); it != mPattern.end(); ++it) {
-        dump += it->toString();
-        if (std::next(it) != mPattern.end()) {
-            dump += ", ";
-        }
-    }
-
-    dump += "]";
-}
-
 } // namespace android
diff --git a/services/inputflinger/reader/mapper/VibratorInputMapper.h b/services/inputflinger/reader/mapper/VibratorInputMapper.h
index bfa5ec1..7ce621a 100644
--- a/services/inputflinger/reader/mapper/VibratorInputMapper.h
+++ b/services/inputflinger/reader/mapper/VibratorInputMapper.h
@@ -30,21 +30,21 @@
     virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) override;
     virtual void process(const RawEvent* rawEvent) override;
 
-    virtual void vibrate(const std::vector<VibrationElement>& pattern, ssize_t repeat,
-                         int32_t token) override;
+    virtual void vibrate(const VibrationSequence& sequence, ssize_t repeat, int32_t token) override;
     virtual void cancelVibrate(int32_t token) override;
+    virtual bool isVibrating() override;
+    virtual std::vector<int32_t> getVibratorIds() override;
     virtual void timeoutExpired(nsecs_t when) override;
     virtual void dump(std::string& dump) override;
 
 private:
     bool mVibrating;
-    std::vector<VibrationElement> mPattern;
+    VibrationSequence mSequence;
     ssize_t mRepeat;
     int32_t mToken;
     ssize_t mIndex;
     nsecs_t mNextStepTime;
 
-    void dumpPattern(std::string& dump) const;
     void nextStep();
     void stopVibrating();
 };