summaryrefslogtreecommitdiff
path: root/Source/WebCore/Modules/vibration/Vibration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/Modules/vibration/Vibration.cpp')
-rw-r--r--Source/WebCore/Modules/vibration/Vibration.cpp130
1 files changed, 130 insertions, 0 deletions
diff --git a/Source/WebCore/Modules/vibration/Vibration.cpp b/Source/WebCore/Modules/vibration/Vibration.cpp
new file mode 100644
index 000000000..860914209
--- /dev/null
+++ b/Source/WebCore/Modules/vibration/Vibration.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "Vibration.h"
+
+#if ENABLE(VIBRATION)
+
+#include "VibrationClient.h"
+
+namespace WebCore {
+
+// Maximum number of entries in a vibration pattern.
+const unsigned MaxVibrationPatternLength = 99;
+// Maximum duration of a vibration in 10 seconds.
+const unsigned MaxVibrationDuration = 10000;
+
+Vibration::Vibration(VibrationClient* client)
+ : m_vibrationClient(client)
+ , m_timer(*this, &Vibration::timerFired)
+ , m_state(State::Idle)
+{
+}
+
+Vibration::~Vibration()
+{
+ m_vibrationClient->vibrationDestroyed();
+}
+
+bool Vibration::vibrate(const VibrationPattern& pattern)
+{
+ VibrationPattern& sanitized = const_cast<VibrationPattern&>(pattern);
+ size_t length = sanitized.size();
+
+ // If the pattern is too long then truncate it.
+ if (length > MaxVibrationPatternLength) {
+ sanitized.shrink(MaxVibrationPatternLength);
+ length = MaxVibrationPatternLength;
+ }
+
+ // If the length of pattern is even and is not zero, then remove the last entry in pattern.
+ if (length && !(length % 2)) {
+ sanitized.removeLast();
+ length--;
+ }
+
+ // If any pattern entry is too long then truncate it.
+ for (auto& duration : sanitized)
+ duration = std::min(duration, MaxVibrationDuration);
+
+ // Pre-exisiting instance need to be canceled when vibrate() is called.
+ if (isVibrating())
+ cancelVibration();
+
+ // If pattern is an empty list, then return true and terminate these steps.
+ if (!length || (length == 1 && !sanitized[0])) {
+ cancelVibration();
+ return true;
+ }
+
+ m_pattern = sanitized;
+
+ m_timer.startOneShot(0);
+ m_state = State::Waiting;
+ return true;
+}
+
+void Vibration::cancelVibration()
+{
+ m_pattern.clear();
+ if (isVibrating()) {
+ m_timer.stop();
+ m_state = State::Idle;
+ m_vibrationClient->cancelVibration();
+ }
+}
+
+void Vibration::timerFired()
+{
+ m_timer.stop();
+
+ if (m_pattern.isEmpty()) {
+ m_state = State::Idle;
+ return;
+ }
+
+ switch (m_state) {
+ case State::Vibrating:
+ m_state = State::Waiting;
+ break;
+ case State::Waiting:
+ case State::Idle:
+ m_state = State::Vibrating;
+ m_vibrationClient->vibrate(m_pattern[0]);
+ break;
+ }
+ m_timer.startOneShot(m_pattern[0] / 1000.0);
+ m_pattern.remove(0);
+}
+
+const char* Vibration::supplementName()
+{
+ return "Vibration";
+}
+
+void provideVibrationTo(Page* page, VibrationClient* client)
+{
+ Vibration::provideTo(page, Vibration::supplementName(), std::make_unique<Vibration>(client));
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(VIBRATION)
+