Merge "Add vibrator state listener support for input device vibrator" into sc-dev
diff --git a/services/inputflinger/InputClassifier.cpp b/services/inputflinger/InputClassifier.cpp
index f5f0400..a9cbd5a 100644
--- a/services/inputflinger/InputClassifier.cpp
+++ b/services/inputflinger/InputClassifier.cpp
@@ -396,6 +396,11 @@
     mListener->notifySensor(args);
 }
 
+void InputClassifier::notifyVibratorState(const NotifyVibratorStateArgs* args) {
+    // pass through
+    mListener->notifyVibratorState(args);
+}
+
 void InputClassifier::notifySwitch(const NotifySwitchArgs* args) {
     // pass through
     mListener->notifySwitch(args);
diff --git a/services/inputflinger/InputClassifier.h b/services/inputflinger/InputClassifier.h
index bf10920..1eef020 100644
--- a/services/inputflinger/InputClassifier.h
+++ b/services/inputflinger/InputClassifier.h
@@ -230,6 +230,7 @@
     virtual void notifyMotion(const NotifyMotionArgs* args) override;
     virtual void notifySwitch(const NotifySwitchArgs* args) override;
     virtual void notifySensor(const NotifySensorArgs* args) override;
+    virtual void notifyVibratorState(const NotifyVibratorStateArgs* args) override;
     virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) override;
     void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) override;
 
diff --git a/services/inputflinger/InputListener.cpp b/services/inputflinger/InputListener.cpp
index 4be49b1..4b1f350 100644
--- a/services/inputflinger/InputListener.cpp
+++ b/services/inputflinger/InputListener.cpp
@@ -246,6 +246,24 @@
     listener->notifySensor(this);
 }
 
+// --- NotifyVibratorStateArgs ---
+
+NotifyVibratorStateArgs::NotifyVibratorStateArgs(int32_t id, nsecs_t eventTime, int32_t deviceId,
+                                                 bool isOn)
+      : NotifyArgs(id, eventTime), deviceId(deviceId), isOn(isOn) {}
+
+NotifyVibratorStateArgs::NotifyVibratorStateArgs(const NotifyVibratorStateArgs& other)
+      : NotifyArgs(other.id, other.eventTime), deviceId(other.deviceId), isOn(other.isOn) {}
+
+bool NotifyVibratorStateArgs::operator==(const NotifyVibratorStateArgs rhs) const {
+    return id == rhs.id && eventTime == rhs.eventTime && deviceId == rhs.deviceId &&
+            isOn == rhs.isOn;
+}
+
+void NotifyVibratorStateArgs::notify(const sp<InputListenerInterface>& listener) const {
+    listener->notifyVibratorState(this);
+}
+
 // --- NotifyDeviceResetArgs ---
 
 NotifyDeviceResetArgs::NotifyDeviceResetArgs(int32_t id, nsecs_t eventTime, int32_t deviceId)
@@ -326,6 +344,11 @@
     mArgsQueue.push_back(new NotifySensorArgs(*args));
 }
 
+void QueuedInputListener::notifyVibratorState(const NotifyVibratorStateArgs* args) {
+    traceEvent(__func__, args->id);
+    mArgsQueue.push_back(new NotifyVibratorStateArgs(*args));
+}
+
 void QueuedInputListener::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
     traceEvent(__func__, args->id);
     mArgsQueue.push_back(new NotifyDeviceResetArgs(*args));
diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index 887bdd4..d6b7259 100644
--- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
+++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
@@ -79,6 +79,8 @@
     void notifySensorAccuracy(int32_t deviceId, InputDeviceSensorType sensorType,
                               InputDeviceSensorAccuracy accuracy) override {}
 
+    void notifyVibratorState(int32_t deviceId, bool isOn) override {}
+
     void notifyUntrustedTouch(const std::string& obscuringPackage) override {}
 
     void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) override {
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 0495d68..5a577d4 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -3747,6 +3747,14 @@
     }
 }
 
+void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs* args) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d,  isOn=%d", args->eventTime,
+          args->deviceId, args->isOn);
+#endif
+    mPolicy->notifyVibratorState(args->deviceId, args->isOn);
+}
+
 bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
     return mInputFilterEnabled;
 }
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 02f5b87..c93d74e 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -96,6 +96,7 @@
     virtual void notifyMotion(const NotifyMotionArgs* args) override;
     virtual void notifySwitch(const NotifySwitchArgs* args) override;
     virtual void notifySensor(const NotifySensorArgs* args) override;
+    virtual void notifyVibratorState(const NotifyVibratorStateArgs* args) override;
     virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) override;
     virtual void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) override;
 
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
index b976129..909ce54 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
@@ -84,6 +84,7 @@
                                    const std::vector<float>& values) = 0;
     virtual void notifySensorAccuracy(int32_t deviceId, InputDeviceSensorType sensorType,
                                       InputDeviceSensorAccuracy accuracy) = 0;
+    virtual void notifyVibratorState(int32_t deviceId, bool isOn) = 0;
 
     /* Notifies the system that an untrusted touch occurred. */
     virtual void notifyUntrustedTouch(const std::string& obscuringPackage) = 0;
diff --git a/services/inputflinger/include/InputListener.h b/services/inputflinger/include/InputListener.h
index 11f726d..094bc0c 100644
--- a/services/inputflinger/include/InputListener.h
+++ b/services/inputflinger/include/InputListener.h
@@ -223,6 +223,24 @@
     virtual void notify(const sp<InputListenerInterface>& listener) const;
 };
 
+/* Describes a vibrator state event. */
+struct NotifyVibratorStateArgs : public NotifyArgs {
+    int32_t deviceId;
+    bool isOn;
+
+    inline NotifyVibratorStateArgs() {}
+
+    NotifyVibratorStateArgs(int32_t id, nsecs_t eventTIme, int32_t deviceId, bool isOn);
+
+    NotifyVibratorStateArgs(const NotifyVibratorStateArgs& other);
+
+    bool operator==(const NotifyVibratorStateArgs rhs) const;
+
+    virtual ~NotifyVibratorStateArgs() {}
+
+    virtual void notify(const sp<InputListenerInterface>& listener) const;
+};
+
 /*
  * The interface used by the InputReader to notify the InputListener about input events.
  */
@@ -237,6 +255,7 @@
     virtual void notifyMotion(const NotifyMotionArgs* args) = 0;
     virtual void notifySwitch(const NotifySwitchArgs* args) = 0;
     virtual void notifySensor(const NotifySensorArgs* args) = 0;
+    virtual void notifyVibratorState(const NotifyVibratorStateArgs* args) = 0;
     virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) = 0;
     virtual void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) = 0;
 };
@@ -259,6 +278,7 @@
     virtual void notifySwitch(const NotifySwitchArgs* args) override;
     virtual void notifySensor(const NotifySensorArgs* args) override;
     virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) override;
+    void notifyVibratorState(const NotifyVibratorStateArgs* args) override;
     void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) override;
 
     void flush();
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index de5d0e6..c044393 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -928,6 +928,11 @@
     mReader->mQueuedListener->notifySensor(&args);
 }
 
+void InputReader::ContextImpl::notifyVibratorState(nsecs_t when, int32_t deviceId, bool isOn) {
+    NotifyVibratorStateArgs args(mIdGenerator.nextId(), when, deviceId, isOn);
+    mReader->mQueuedListener->notifyVibratorState(&args);
+}
+
 void InputReader::ContextImpl::notifySwitch(nsecs_t eventTime, uint32_t switchValues,
                                             uint32_t switchMask) {
     NotifySwitchArgs args(mIdGenerator.nextId(), eventTime, 0 /*policyFlags*/, switchValues,
diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h
index e2558bc..5f78149 100644
--- a/services/inputflinger/reader/include/InputReader.h
+++ b/services/inputflinger/reader/include/InputReader.h
@@ -152,6 +152,7 @@
         void notifySensor(nsecs_t when, int32_t deviceId, InputDeviceSensorType sensorType,
                           InputDeviceSensorAccuracy accuracy, bool accuracyChanged,
                           nsecs_t timestamp, std::vector<float> values) override;
+        void notifyVibratorState(nsecs_t when, int32_t deviceId, bool isOn) override;
         void notifyDeviceReset(nsecs_t when, int32_t deviceId) override;
         void notifyPointerCaptureChanged(nsecs_t when, bool hasCapture) override;
 
diff --git a/services/inputflinger/reader/include/InputReaderContext.h b/services/inputflinger/reader/include/InputReaderContext.h
index edab312..e6ea523 100644
--- a/services/inputflinger/reader/include/InputReaderContext.h
+++ b/services/inputflinger/reader/include/InputReaderContext.h
@@ -80,6 +80,7 @@
     virtual void notifySensor(nsecs_t when, int32_t deviceId, InputDeviceSensorType sensorType,
                               InputDeviceSensorAccuracy accuracy, bool accuracyChanged,
                               nsecs_t timestamp, std::vector<float> values) = 0;
+    virtual void notifyVibratorState(nsecs_t when, int32_t deviceId, bool isOn) = 0;
     virtual void notifyDeviceReset(nsecs_t when, int32_t deviceId) = 0;
     virtual void notifyPointerCaptureChanged(nsecs_t when, bool hasCapture) = 0;
 };
diff --git a/services/inputflinger/reader/mapper/VibratorInputMapper.cpp b/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
index f25e59a..2e4ab45 100644
--- a/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/VibratorInputMapper.cpp
@@ -52,6 +52,8 @@
     mToken = token;
     mIndex = -1;
 
+    // Request InputReader to notify InputManagerService for vibration started.
+    getContext()->notifyVibratorState(systemTime(), getDeviceId(), true);
     nextStep();
 }
 
@@ -84,6 +86,9 @@
 }
 
 void VibratorInputMapper::nextStep() {
+#if DEBUG_VIBRATOR
+    ALOGD("nextStep: index=%d, vibrate deviceId=%d", (int)mIndex, getDeviceId());
+#endif
     mIndex += 1;
     if (size_t(mIndex) >= mSequence.pattern.size()) {
         if (mRepeat < 0) {
@@ -124,6 +129,9 @@
     ALOGD("stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId());
 #endif
     getDeviceContext().cancelVibrate();
+
+    // Request InputReader to notify InputManagerService for vibration complete.
+    getContext()->notifyVibratorState(systemTime(), getDeviceId(), false);
 }
 
 void VibratorInputMapper::dump(std::string& dump) {
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index c7e05eb..e063dfc 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -331,6 +331,8 @@
     void notifySensorAccuracy(int deviceId, InputDeviceSensorType sensorType,
                               InputDeviceSensorAccuracy accuracy) override {}
 
+    void notifyVibratorState(int32_t deviceId, bool isOn) override {}
+
     void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) override {
         *outConfig = mConfig;
     }
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 0e88312..bea9932 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -2678,6 +2678,7 @@
 
 TEST_F(VibratorInputMapperTest, Vibrate) {
     constexpr uint8_t DEFAULT_AMPLITUDE = 192;
+    constexpr int32_t VIBRATION_TOKEN = 100;
     VibratorInputMapper& mapper = addMapperAndConfigure<VibratorInputMapper>();
 
     VibrationElement pattern(2);
@@ -2695,8 +2696,23 @@
     std::vector<uint8_t> amplitudes = {DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE / 2};
 
     ASSERT_FALSE(mapper.isVibrating());
-    mapper.vibrate(sequence, -1 /* repeat */, 0 /* token */);
+    // Start vibrating
+    mapper.vibrate(sequence, -1 /* repeat */, VIBRATION_TOKEN);
     ASSERT_TRUE(mapper.isVibrating());
+    // Verify vibrator state listener was notified.
+    mReader->loopOnce();
+    NotifyVibratorStateArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyVibratorStateWasCalled(&args));
+    ASSERT_EQ(DEVICE_ID, args.deviceId);
+    ASSERT_TRUE(args.isOn);
+    // Stop vibrating
+    mapper.cancelVibrate(VIBRATION_TOKEN);
+    ASSERT_FALSE(mapper.isVibrating());
+    // Verify vibrator state listener was notified.
+    mReader->loopOnce();
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyVibratorStateWasCalled(&args));
+    ASSERT_EQ(DEVICE_ID, args.deviceId);
+    ASSERT_FALSE(args.isOn);
 }
 
 // --- SensorInputMapperTest ---
diff --git a/services/inputflinger/tests/TestInputListener.cpp b/services/inputflinger/tests/TestInputListener.cpp
index 295c6e3..fb7de97 100644
--- a/services/inputflinger/tests/TestInputListener.cpp
+++ b/services/inputflinger/tests/TestInputListener.cpp
@@ -86,6 +86,12 @@
                                            "Expected notifySensor() to have been called."));
 }
 
+void TestInputListener::assertNotifyVibratorStateWasCalled(NotifyVibratorStateArgs* outEventArgs) {
+    ASSERT_NO_FATAL_FAILURE(assertCalled<NotifyVibratorStateArgs>(outEventArgs,
+                                                                  "Expected notifyVibratorState() "
+                                                                  "to have been called."));
+}
+
 void TestInputListener::assertNotifyCaptureWasCalled(
         NotifyPointerCaptureChangedArgs* outEventArgs) {
     ASSERT_NO_FATAL_FAILURE(
@@ -165,4 +171,8 @@
     notify<NotifySensorArgs>(args);
 }
 
+void TestInputListener::notifyVibratorState(const NotifyVibratorStateArgs* args) {
+    notify<NotifyVibratorStateArgs>(args);
+}
+
 } // namespace android
diff --git a/services/inputflinger/tests/TestInputListener.h b/services/inputflinger/tests/TestInputListener.h
index e54350a..0ffcaaa 100644
--- a/services/inputflinger/tests/TestInputListener.h
+++ b/services/inputflinger/tests/TestInputListener.h
@@ -56,6 +56,7 @@
 
     void assertNotifyCaptureWasCalled(NotifyPointerCaptureChangedArgs* outEventArgs = nullptr);
     void assertNotifySensorWasCalled(NotifySensorArgs* outEventArgs = nullptr);
+    void assertNotifyVibratorStateWasCalled(NotifyVibratorStateArgs* outEventArgs = nullptr);
 
 private:
     template <class NotifyArgsType>
@@ -79,6 +80,8 @@
 
     virtual void notifySensor(const NotifySensorArgs* args) override;
 
+    virtual void notifyVibratorState(const NotifyVibratorStateArgs* args) override;
+
     virtual void notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs* args) override;
 
     std::mutex mLock;
@@ -92,6 +95,7 @@
                std::vector<NotifyMotionArgs>,                //
                std::vector<NotifySwitchArgs>,                //
                std::vector<NotifySensorArgs>,                //
+               std::vector<NotifyVibratorStateArgs>,         //
                std::vector<NotifyPointerCaptureChangedArgs>> //
             mQueues GUARDED_BY(mLock);
 };