| Index: content/renderer/gpu/actions_runner.cc | 
| diff --git a/content/renderer/gpu/actions_runner.cc b/content/renderer/gpu/actions_runner.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..677d579f7ee9f20462883e6dab591635ccd30bf7 | 
| --- /dev/null | 
| +++ b/content/renderer/gpu/actions_runner.cc | 
| @@ -0,0 +1,208 @@ | 
| +// Copyright (c) 2016 The Chromium Authors. All rights reserved. | 
| +// Use of this source code is governed by a BSD-style license that can be | 
| +// found in the LICENSE file. | 
| + | 
| +#include "content/renderer/gpu/actions_runner.h" | 
| + | 
| +#include "base/format_macros.h" | 
| +#include "base/memory/ptr_util.h" | 
| +#include "base/strings/stringprintf.h" | 
| +#include "base/values.h" | 
| + | 
| +namespace content { | 
| + | 
| +namespace { | 
| + | 
| +SyntheticPointerActionParams::PointerActionType ToSyntheticPointerActionType( | 
| +    std::string action_type) { | 
| +  if (action_type == "pointerDown") | 
| +    return SyntheticPointerActionParams::PointerActionType::PRESS; | 
| +  if (action_type == "pointerMove") | 
| +    return SyntheticPointerActionParams::PointerActionType::MOVE; | 
| +  if (action_type == "pointerUp") | 
| +    return SyntheticPointerActionParams::PointerActionType::RELEASE; | 
| +  if (action_type == "pause") | 
| +    return SyntheticPointerActionParams::PointerActionType::IDLE; | 
| +  NOTREACHED() << "Invalid SyntheticPointerActionParams::PointerActionType."; | 
| +  return SyntheticPointerActionParams::PointerActionType::NOT_INITIALIZED; | 
| +} | 
| + | 
| +SyntheticGestureParams::GestureSourceType ToSyntheticGestureSourceType( | 
| +    std::string source_type) { | 
| +  if (source_type == "touch") | 
| +    return SyntheticGestureParams::TOUCH_INPUT; | 
| +  else if (source_type == "mouse") | 
| +    return SyntheticGestureParams::MOUSE_INPUT; | 
| +  else | 
| +    return SyntheticGestureParams::DEFAULT_INPUT; | 
| +} | 
| + | 
| +}  // namespace | 
| + | 
| +ActionsRunner::ActionsRunner(base::Value* value) | 
| +    : longest_action_sequence_(0), value_(value), index_(0) {} | 
| + | 
| +ActionsRunner::~ActionsRunner() {} | 
| + | 
| +bool ActionsRunner::ParseSources() { | 
| +  const base::DictionaryValue* actions; | 
| +  if (!value_->GetAsDictionary(&actions)) { | 
| +    error_message_ = | 
| +        base::StringPrintf("actions is missing or not a dictionary"); | 
| +    return false; | 
| +  } | 
| + | 
| +  std::string source_type; | 
| +  if (!actions->GetString("source", &source_type)) { | 
| +    error_message_ = | 
| +        base::StringPrintf("source type is missing or not a string"); | 
| +    return false; | 
| +  } else if (source_type != "touch" && source_type != "mouse" && | 
| +             source_type != "pointer") { | 
| +    error_message_ = | 
| +        base::StringPrintf("source type is an unsupported input source"); | 
| +    return false; | 
| +  } | 
| + | 
| +#if defined(OS_MACOSX) | 
| +  if (source_type == "touch") { | 
| +    error_message_ = | 
| +        base::StringPrintf("Mac OS does not support touch events"); | 
| +    return false; | 
| +  } | 
| +#endif  // defined(OS_MACOSX) | 
| + | 
| +  const base::ListValue* pointer_list; | 
| +  if (!actions->GetList("pointer", &pointer_list)) { | 
| +    error_message_ = | 
| +        base::StringPrintf("pointer_list is missing or not a list"); | 
| +    return false; | 
| +  } | 
| + | 
| +  for (i = 0; i < pointer_list->GetSize(); i++) { | 
| +    const base::DictionaryValue* pointer_actions; | 
| +    if (!pointer_list->GetDictionary(i, &pointer_actions)) { | 
| +      error_message_ = | 
| +          base::StringPrintf("pointer actions is missing or not a dictionary"); | 
| +      return false; | 
| +    } else if (!ParsePointerActions(*pointer_actions)) { | 
| +      return false; | 
| +    } | 
| +  } | 
| + | 
| +  if (!gesture_params_) | 
| +    gesture_params_ = base::MakeUnique<SyntheticPointerActionListParams>(); | 
| + | 
| +  gesture_params_->gesture_source_type = | 
| +      ToSyntheticGestureSourceType(source_type); | 
| +  // Group a list of actions from all pointers into a | 
| +  // SyntheticPointerActionListParams object, which is a list of actions, which | 
| +  // will be dispatched together. | 
| +  for (size_t action_index = 0; action_index < longest_action_sequence_; | 
| +       ++action_index) { | 
| +    SyntheticPointerActionListParams::ParamList param_list; | 
| +    for (size_t pointer_index = 0; pointer_index < ids_.size(); | 
| +         ++pointer_index) { | 
| +      if (pointer_actions_list_[pointer_index].size() > action_index) | 
| +        param_list.push_back( | 
| +            pointer_actions_list_[pointer_index][action_index]); | 
| +    } | 
| +    gesture_params_->PushPointerActionParamsList(param_list); | 
| +  } | 
| + | 
| +  return true; | 
| +} | 
| + | 
| +bool ActionsRunner::ParsePointerActions( | 
| +    const base::DictionaryValue& pointer_actions) { | 
| +  if (!pointer_actions.GetInteger("id", &index_)) { | 
| +    error_message_ = | 
| +        base::StringPrintf("actions[%" PRIuS "].id is missing or not a int", i); | 
| +    return false; | 
| +  } else if (ids_.find(index_) != ids_.end()) { | 
| +    error_message_ = | 
| +        base::StringPrintf("actions[%" PRIuS "].id is not unique", i); | 
| +    return false; | 
| +  } | 
| +  ids_.insert(index_); | 
| + | 
| +  const base::ListValue* actions; | 
| +  if (!pointer_actions.GetList("actions", &actions)) { | 
| +    error_message_ = base::StringPrintf( | 
| +        "actions[%" PRIuS "].actions is missing or not a list", i); | 
| +    return false; | 
| +  } | 
| + | 
| +  if (actions->GetSize() > longest_action_sequence_) | 
| +    longest_action_sequence_ = actions->GetSize(); | 
| +  if (!ParseActions(*actions)) | 
| +    return false; | 
| + | 
| +  return true; | 
| +} | 
| + | 
| +bool ActionsRunner::ParseActions(const base::ListValue& actions) { | 
| +  SyntheticPointerActionListParams::ParamList param_list; | 
| +  for (j = 0; j < actions.GetSize(); j++) { | 
| +    const base::DictionaryValue* action; | 
| +    if (!actions.GetDictionary(j, &action)) { | 
| +      error_message_ = base::StringPrintf("actions[%" PRIuS "].actions[%" PRIuS | 
| +                                          "] is missing or not a dictionary", | 
| +                                          i, j); | 
| +      return false; | 
| +    } else if (!ParseAction(*action, param_list)) { | 
| +      return false; | 
| +    } | 
| +  } | 
| +  pointer_actions_list_.push_back(param_list); | 
| +  return true; | 
| +} | 
| + | 
| +bool ActionsRunner::ParseAction( | 
| +    const base::DictionaryValue& action, | 
| +    SyntheticPointerActionListParams::ParamList& param_list) { | 
| +  SyntheticPointerActionParams::PointerActionType pointer_action_type = | 
| +      SyntheticPointerActionParams::PointerActionType::NOT_INITIALIZED; | 
| +  std::string name; | 
| +  if (!action.GetString("name", &name)) { | 
| +    error_message_ = base::StringPrintf("actions[%" PRIuS "].actions[%" PRIuS | 
| +                                        "].name is missing or not a string", | 
| +                                        i, j); | 
| +    return false; | 
| +  } | 
| +  if (name != "pointerDown" && name != "pointerUp" && name != "pointerMove" && | 
| +      name != "pause") { | 
| +    error_message_ = base::StringPrintf("actions[%" PRIuS "].actions[%" PRIuS | 
| +                                        "].name is an unsupported action name", | 
| +                                        i, j); | 
| +    return false; | 
| +  } | 
| +  pointer_action_type = ToSyntheticPointerActionType(name); | 
| + | 
| +  double position_x = 0; | 
| +  double position_y = 0; | 
| +  if (action.HasKey("x") && !action.GetDouble("x", &position_x)) { | 
| +    error_message_ = base::StringPrintf( | 
| +        "actions[%" PRIuS "].actions[%" PRIuS "].x is not a number", i, j); | 
| +    return false; | 
| +  } | 
| + | 
| +  if (action.HasKey("y") && !action.GetDouble("y", &position_y)) { | 
| +    error_message_ = base::StringPrintf( | 
| +        "actions[%" PRIuS "].actions[%" PRIuS "].y is not a number", i, j); | 
| +    return false; | 
| +  } | 
| + | 
| +  SyntheticPointerActionParams action_param(pointer_action_type); | 
| +  action_param.set_index(index_); | 
| +  if (pointer_action_type == | 
| +          SyntheticPointerActionParams::PointerActionType::PRESS || | 
| +      pointer_action_type == | 
| +          SyntheticPointerActionParams::PointerActionType::MOVE) { | 
| +    action_param.set_position(gfx::PointF(position_x, position_y)); | 
| +  } | 
| +  param_list.push_back(action_param); | 
| +  return true; | 
| +} | 
| + | 
| +}  // namespace content | 
|  |