[Title] [CherryPick] Vibration cannot be canceled during pattern vibration.
[Issue] N/A
[Problem] Vibration cannot be canceled during pattern vibration
[Cause] If resting time which are even numbers of pattern m_isVibraing is false, therefore if cancel is called it is returned.
In addition, m_timerStart need to stop in the cancelVibration() with m_timerStop.stop().
If cancelVibration is called right after m_timerStart is fired, timerStartFired function can be called even if vibration is already canceled because of timing issue of timer.
[Solution] Cherry picked
[Cherry-Picker] Jiyeon Kim
https://bugs.webkit.org/show_bug.cgi?id=117822
Change-Id: If6c3332bf7b4867abb47b5f295cbf16458edfda2
--- /dev/null
+Tests the cancelVibration during pattern vibration is working.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS internals.isVibrating() is false
+PASS internals.isVibrating() is true
+PASS internals.isVibrating() is false
+PASS internals.isVibrating() is true
+PASS internals.isVibrating() is false
+PASS internals.isVibrating() is true
+PASS internals.isVibrating() is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<html>
+<head>
+<script src="../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<script>
+description('Tests the cancelVibration during pattern vibration is working.');
+
+var count = 0;
+var cancelingTime = 80;
+
+if (window.testRunner) {
+ function vibrate() {
+ navigator.vibrate([100, 100, 100, 100, 100]);
+ shouldBeTrue('internals.isVibrating()');
+ cancelVibration(cancelingTime + count * 100);
+ }
+
+ function cancelVibration(time) {
+ setTimeout(function() {
+ navigator.vibrate(0);
+ shouldBeFalse('internals.isVibrating()');
+ if (count++ == 2)
+ finishJSTest();
+ vibrate();
+ }, time);
+ }
+
+ shouldBeFalse('internals.isVibrating()');
+ vibrate();
+ window.jsTestIsAsync = true;
+} else
+ debug('This test can not be run without the TestRunner');
+</script>
+<script src="../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
\ No newline at end of file
}
m_pattern.append(time);
m_timerStart.startOneShot(0);
+ m_isVibrating = true;
}
void Vibration::vibrate(const VibrationPattern& pattern)
void Vibration::cancelVibration()
{
- if (m_isVibrating) {
- m_vibrationClient->cancelVibration();
- m_isVibrating = false;
- m_timerStop.stop();
- }
+ m_pattern.clear();
+ if (m_isVibrating)
+ stopVibration();
}
void Vibration::suspendVibration()
return;
m_pattern.insert(0, m_timerStop.nextFireInterval());
- m_timerStop.stop();
- cancelVibration();
+ stopVibration();
}
void Vibration::resumeVibration()
{
m_timerStart.startOneShot(0);
+ m_isVibrating = true;
+}
+
+void Vibration::stopVibration()
+{
+ m_timerStart.stop();
+ m_timerStop.stop();
+ m_vibrationClient->cancelVibration();
+ m_isVibrating = false;
}
void Vibration::timerStartFired(Timer<Vibration>* timer)
m_timerStop.stop();
m_isVibrating = false;
- if (m_pattern.size()) {
+ if (!m_pattern.isEmpty()) {
m_timerStart.startOneShot(m_pattern[0] / 1000.0);
m_pattern.remove(0);
+ if (m_pattern.isEmpty())
+ m_isVibrating = false;
}
}
static Vibration* from(Page* page) { return static_cast<Vibration*>(Supplement<Page>::from(page, supplementName())); }
static bool isActive(Page*);
+ bool isVibrating() { return m_isVibrating; }
+
private:
+ void stopVibration();
+
VibrationClient* m_vibrationClient;
Timer<Vibration> m_timerStart;
Timer<Vibration> m_timerStop;