NavigatorVibration::VibrationPattern NavigatorVibration::sanitizeVibrationPattern(const UnsignedLongOrUnsignedLongSequence& pattern)
{
    VibrationPattern sanitized;

    if (pattern.isUnsignedLong())
        sanitized.append(pattern.getAsUnsignedLong());
    else if (pattern.isUnsignedLongSequence())
        sanitized = pattern.getAsUnsignedLongSequence();

    return sanitizeVibrationPatternInternal(sanitized);
}
bool NavigatorVibration::vibrate(const VibrationPattern& pattern)
{
    // Cancelling clears the stored pattern so do it before setting the new one.
    if (m_isVibrating)
        cancelVibration();

    m_pattern = sanitizeVibrationPatternInternal(pattern);

    if (m_timerStart.isActive())
        m_timerStart.stop();

    if (!m_pattern.size())
        return true;

    if (m_pattern.size() == 1 && !m_pattern[0]) {
        m_pattern.clear();
        return true;
    }

    m_timerStart.startOneShot(0, FROM_HERE);
    m_isVibrating = true;
    return true;
}
bool VibrationController::vibrate(const VibrationPattern& pattern) {
  // Cancel clears the stored pattern and cancels any ongoing vibration.
  cancel();

  m_pattern = sanitizeVibrationPatternInternal(pattern);

  if (!m_pattern.size())
    return true;

  if (m_pattern.size() == 1 && !m_pattern[0]) {
    m_pattern.clear();
    return true;
  }

  m_isRunning = true;

  // This may be a bit racy with |didCancel| being called as a mojo callback,
  // it also starts the timer. This is not a problem as calling |startOneShot|
  // repeatedly will just update the time at which to run |doVibrate|, it will
  // not be called more than once.
  m_timerDoVibrate.startOneShot(0, BLINK_FROM_HERE);

  return true;
}