root/chrome/browser/devtools/devtools_embedder_message_dispatcher.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. GetValue
  2. GetValue
  3. GetValue
  4. GetValue
  5. GetValue
  6. value
  7. valid
  8. ParseAndHandle0
  9. ParseAndHandle1
  10. ParseAndHandle2
  11. ParseAndHandle3
  12. ParseAndHandle4
  13. Dispatch
  14. RegisterHandler
  15. RegisterHandler
  16. RegisterHandler
  17. RegisterHandler
  18. RegisterHandler
  19. RegisterHandler
  20. createForDevToolsFrontend

// Copyright 2013 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 "chrome/browser/devtools/devtools_embedder_message_dispatcher.h"

#include "base/bind.h"
#include "base/values.h"

namespace {

bool GetValue(const base::ListValue& list, int pos, std::string& value) {
  return list.GetString(pos, &value);
}

bool GetValue(const base::ListValue& list, int pos, int& value) {
  return list.GetInteger(pos, &value);
}

bool GetValue(const base::ListValue& list, int pos, bool& value) {
  return list.GetBoolean(pos, &value);
}

bool GetValue(const base::ListValue& list, int pos, gfx::Insets& insets) {
  const base::DictionaryValue* dict;
  if (!list.GetDictionary(pos, &dict))
    return false;
  int top = 0;
  int left = 0;
  int bottom = 0;
  int right = 0;
  if (!dict->GetInteger("top", &top) ||
      !dict->GetInteger("left", &left) ||
      !dict->GetInteger("bottom", &bottom) ||
      !dict->GetInteger("right", &right))
    return false;
  insets.Set(top, left, bottom, right);
  return true;
}

bool GetValue(const base::ListValue& list, int pos, gfx::Size& size) {
  const base::DictionaryValue* dict;
  if (!list.GetDictionary(pos, &dict))
    return false;
  int width = 0;
  int height = 0;
  if (!dict->GetInteger("width", &width) ||
      !dict->GetInteger("height", &height))
    return false;
  size.SetSize(width, height);
  return true;
}

template <typename T>
struct StorageTraits {
  typedef T StorageType;
};

template <typename T>
struct StorageTraits<const T&> {
  typedef T StorageType;
};

template <class A>
class Argument {
 public:
  typedef typename StorageTraits<A>::StorageType ValueType;

  Argument(const base::ListValue& list, int pos) {
    valid_ = GetValue(list, pos, value_);
  }

  ValueType value() const { return value_; }
  bool valid() const { return valid_; }

 private:
  ValueType value_;
  bool valid_;
};

bool ParseAndHandle0(const base::Callback<void(void)>& handler,
                     const base::ListValue& list) {
  if (list.GetSize() != 0)
      return false;
  handler.Run();
  return true;
}

template <class A1>
bool ParseAndHandle1(const base::Callback<void(A1)>& handler,
                     const base::ListValue& list) {
  if (list.GetSize() != 1)
    return false;
  Argument<A1> arg1(list, 0);
  if (!arg1.valid())
    return false;
  handler.Run(arg1.value());
  return true;
}

template <class A1, class A2>
bool ParseAndHandle2(const base::Callback<void(A1, A2)>& handler,
                     const base::ListValue& list) {
  if (list.GetSize() != 2)
    return false;
  Argument<A1> arg1(list, 0);
  if (!arg1.valid())
    return false;
  Argument<A2> arg2(list, 1);
  if (!arg2.valid())
    return false;
  handler.Run(arg1.value(), arg2.value());
  return true;
}

template <class A1, class A2, class A3>
bool ParseAndHandle3(const base::Callback<void(A1, A2, A3)>& handler,
                     const base::ListValue& list) {
  if (list.GetSize() != 3)
    return false;
  Argument<A1> arg1(list, 0);
  if (!arg1.valid())
    return false;
  Argument<A2> arg2(list, 1);
  if (!arg2.valid())
    return false;
  Argument<A3> arg3(list, 2);
  if (!arg3.valid())
    return false;
  handler.Run(arg1.value(), arg2.value(), arg3.value());
  return true;
}

template <class A1, class A2, class A3, class A4>
bool ParseAndHandle4(const base::Callback<void(A1, A2, A3, A4)>& handler,
                     const base::ListValue& list) {
  if (list.GetSize() != 4)
    return false;
  Argument<A1> arg1(list, 0);
  if (!arg1.valid())
    return false;
  Argument<A2> arg2(list, 1);
  if (!arg2.valid())
    return false;
  Argument<A3> arg3(list, 2);
  if (!arg3.valid())
    return false;
  Argument<A4> arg4(list, 3);
  if (!arg4.valid())
    return false;
  handler.Run(arg1.value(), arg2.value(), arg3.value(), arg4.value());
  return true;
}

} // namespace

/**
 * Dispatcher for messages sent from the frontend running in an
 * isolated renderer (chrome-devtools:// or chrome://inspect) to the embedder
 * in the browser.
 *
 * The messages are sent via InspectorFrontendHost.sendMessageToEmbedder or
 * chrome.send method accordingly.
 */
class DispatcherImpl : public DevToolsEmbedderMessageDispatcher {
 public:
  virtual ~DispatcherImpl() {}

  virtual bool Dispatch(const std::string& method,
                        const base::ListValue* params,
                        std::string* error) OVERRIDE {
    HandlerMap::iterator it = handlers_.find(method);
    if (it == handlers_.end())
      return false;

    if (it->second.Run(*params))
      return true;

    if (error)
      *error = "Invalid frontend host message parameters: " + method;
    return false;
  }

  typedef base::Callback<bool(const base::ListValue&)> Handler;
  void RegisterHandler(const std::string& method, const Handler& handler) {
    handlers_[method] = handler;
  }

  template<class T>
  void RegisterHandler(const std::string& method,
                       void (T::*handler)(), T* delegate) {
    handlers_[method] = base::Bind(&ParseAndHandle0,
                                   base::Bind(handler,
                                              base::Unretained(delegate)));
  }

  template<class T, class A1>
  void RegisterHandler(const std::string& method,
                       void (T::*handler)(A1), T* delegate) {
    handlers_[method] = base::Bind(ParseAndHandle1<A1>,
                                   base::Bind(handler,
                                              base::Unretained(delegate)));
  }

  template<class T, class A1, class A2>
  void RegisterHandler(const std::string& method,
                       void (T::*handler)(A1, A2), T* delegate) {
    handlers_[method] = base::Bind(ParseAndHandle2<A1, A2>,
                                   base::Bind(handler,
                                              base::Unretained(delegate)));
  }

  template<class T, class A1, class A2, class A3>
  void RegisterHandler(const std::string& method,
                       void (T::*handler)(A1, A2, A3), T* delegate) {
    handlers_[method] = base::Bind(ParseAndHandle3<A1, A2, A3>,
                                   base::Bind(handler,
                                              base::Unretained(delegate)));
  }

  template<class T, class A1, class A2, class A3, class A4>
  void RegisterHandler(const std::string& method,
                       void (T::*handler)(A1, A2, A3, A4), T* delegate) {
    handlers_[method] = base::Bind(ParseAndHandle4<A1, A2, A3, A4>,
                                   base::Bind(handler,
                                              base::Unretained(delegate)));
  }

 private:
  typedef std::map<std::string, Handler> HandlerMap;
  HandlerMap handlers_;
};


DevToolsEmbedderMessageDispatcher*
    DevToolsEmbedderMessageDispatcher::createForDevToolsFrontend(
        Delegate* delegate) {
  DispatcherImpl* d = new DispatcherImpl();

  d->RegisterHandler("bringToFront", &Delegate::ActivateWindow, delegate);
  d->RegisterHandler("closeWindow", &Delegate::CloseWindow, delegate);
  d->RegisterHandler("setContentsInsets",
                     &Delegate::SetContentsInsets, delegate);
  d->RegisterHandler("setContentsResizingStrategy",
                     &Delegate::SetContentsResizingStrategy, delegate);
  d->RegisterHandler("inspectElementCompleted",
                     &Delegate::InspectElementCompleted, delegate);
  d->RegisterHandler("moveWindowBy", &Delegate::MoveWindow, delegate);
  d->RegisterHandler("setIsDocked", &Delegate::SetIsDocked, delegate);
  d->RegisterHandler("openInNewTab", &Delegate::OpenInNewTab, delegate);
  d->RegisterHandler("save", &Delegate::SaveToFile, delegate);
  d->RegisterHandler("append", &Delegate::AppendToFile, delegate);
  d->RegisterHandler("requestFileSystems",
                     &Delegate::RequestFileSystems, delegate);
  d->RegisterHandler("addFileSystem", &Delegate::AddFileSystem, delegate);
  d->RegisterHandler("removeFileSystem", &Delegate::RemoveFileSystem, delegate);
  d->RegisterHandler("upgradeDraggedFileSystemPermissions",
                     &Delegate::UpgradeDraggedFileSystemPermissions, delegate);
  d->RegisterHandler("indexPath", &Delegate::IndexPath, delegate);
  d->RegisterHandler("stopIndexing", &Delegate::StopIndexing, delegate);
  d->RegisterHandler("searchInPath", &Delegate::SearchInPath, delegate);
  d->RegisterHandler("zoomIn", &Delegate::ZoomIn, delegate);
  d->RegisterHandler("zoomOut", &Delegate::ZoomOut, delegate);
  d->RegisterHandler("resetZoom", &Delegate::ResetZoom, delegate);

  return d;
}

/* [<][>][^][v][top][bottom][index][help] */