158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file.
458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/devtools/devtools_embedder_message_dispatcher.h"
658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/bind.h"
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/values.h"
958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace {
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool GetValue(const base::ListValue& list, int pos, std::string& value) {
1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return list.GetString(pos, &value);
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool GetValue(const base::ListValue& list, int pos, int& value) {
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return list.GetInteger(pos, &value);
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool GetValue(const base::ListValue& list, int pos, bool& value) {
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return list.GetBoolean(pos, &value);
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool GetValue(const base::ListValue& list, int pos, gfx::Rect& rect) {
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const base::DictionaryValue* dict;
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!list.GetDictionary(pos, &dict))
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int x = 0;
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int y = 0;
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int width = 0;
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int height = 0;
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!dict->GetInteger("x", &x) ||
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      !dict->GetInteger("y", &y) ||
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      !dict->GetInteger("width", &width) ||
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      !dict->GetInteger("height", &height))
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return false;
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  rect.SetRect(x, y, width, height);
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return true;
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)template <typename T>
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)struct StorageTraits {
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  typedef T StorageType;
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)template <typename T>
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)struct StorageTraits<const T&> {
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  typedef T StorageType;
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)template <class A>
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class Argument {
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  typedef typename StorageTraits<A>::StorageType ValueType;
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Argument(const base::ListValue& list, int pos) {
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    valid_ = GetValue(list, pos, value_);
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ValueType value() const { return value_; }
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool valid() const { return valid_; }
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ValueType value_;
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool valid_;
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool ParseAndHandle0(const base::Callback<void(void)>& handler,
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     const base::ListValue& list) {
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (list.GetSize() != 0)
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return false;
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  handler.Run();
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)template <class A1>
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool ParseAndHandle1(const base::Callback<void(A1)>& handler,
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     const base::ListValue& list) {
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (list.GetSize() != 1)
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Argument<A1> arg1(list, 0);
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!arg1.valid())
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  handler.Run(arg1.value());
8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)template <class A1, class A2>
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool ParseAndHandle2(const base::Callback<void(A1, A2)>& handler,
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     const base::ListValue& list) {
9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (list.GetSize() != 2)
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Argument<A1> arg1(list, 0);
9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!arg1.valid())
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Argument<A2> arg2(list, 1);
9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!arg2.valid())
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  handler.Run(arg1.value(), arg2.value());
10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)template <class A1, class A2, class A3>
10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool ParseAndHandle3(const base::Callback<void(A1, A2, A3)>& handler,
10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                     const base::ListValue& list) {
10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (list.GetSize() != 3)
10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Argument<A1> arg1(list, 0);
10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!arg1.valid())
11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Argument<A2> arg2(list, 1);
11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!arg2.valid())
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Argument<A3> arg3(list, 2);
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!arg3.valid())
11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  handler.Run(arg1.value(), arg2.value(), arg3.value());
11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)template <class A1, class A2, class A3, class A4>
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ParseAndHandle4(const base::Callback<void(A1, A2, A3, A4)>& handler,
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     const base::ListValue& list) {
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (list.GetSize() != 4)
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Argument<A1> arg1(list, 0);
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!arg1.valid())
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Argument<A2> arg2(list, 1);
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!arg2.valid())
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Argument<A3> arg3(list, 2);
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!arg3.valid())
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Argument<A4> arg4(list, 3);
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!arg4.valid())
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return false;
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  handler.Run(arg1.value(), arg2.value(), arg3.value(), arg4.value());
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return true;
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)/**
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * Dispatcher for messages sent from the frontend running in an
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * isolated renderer (chrome-devtools:// or chrome://inspect) to the embedder
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * in the browser.
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * The messages are sent via InspectorFrontendHost.sendMessageToEmbedder or
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * chrome.send method accordingly.
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class DispatcherImpl : public DevToolsEmbedderMessageDispatcher {
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual ~DispatcherImpl() {}
15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual bool Dispatch(const std::string& method,
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        const base::ListValue* params,
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        std::string* error) OVERRIDE {
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    HandlerMap::iterator it = handlers_.find(method);
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (it == handlers_.end())
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return false;
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (it->second.Run(*params))
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return true;
16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (error)
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      *error = "Invalid frontend host message parameters: " + method;
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
17058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  typedef base::Callback<bool(const base::ListValue&)> Handler;
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void RegisterHandler(const std::string& method, const Handler& handler) {
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    handlers_[method] = handler;
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  template<class T>
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void RegisterHandler(const std::string& method,
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       void (T::*handler)(), T* delegate) {
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    handlers_[method] = base::Bind(&ParseAndHandle0,
180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   base::Bind(handler,
181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                              base::Unretained(delegate)));
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  template<class T, class A1>
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void RegisterHandler(const std::string& method,
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       void (T::*handler)(A1), T* delegate) {
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    handlers_[method] = base::Bind(ParseAndHandle1<A1>,
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   base::Bind(handler,
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                              base::Unretained(delegate)));
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  template<class T, class A1, class A2>
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void RegisterHandler(const std::string& method,
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       void (T::*handler)(A1, A2), T* delegate) {
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    handlers_[method] = base::Bind(ParseAndHandle2<A1, A2>,
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   base::Bind(handler,
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                              base::Unretained(delegate)));
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  template<class T, class A1, class A2, class A3>
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void RegisterHandler(const std::string& method,
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       void (T::*handler)(A1, A2, A3), T* delegate) {
203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    handlers_[method] = base::Bind(ParseAndHandle3<A1, A2, A3>,
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   base::Bind(handler,
205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                              base::Unretained(delegate)));
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  template<class T, class A1, class A2, class A3, class A4>
209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void RegisterHandler(const std::string& method,
210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       void (T::*handler)(A1, A2, A3, A4), T* delegate) {
211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    handlers_[method] = base::Bind(ParseAndHandle4<A1, A2, A3, A4>,
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   base::Bind(handler,
213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                              base::Unretained(delegate)));
214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  typedef std::map<std::string, Handler> HandlerMap;
218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  HandlerMap handlers_;
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)DevToolsEmbedderMessageDispatcher*
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DevToolsEmbedderMessageDispatcher::createForDevToolsFrontend(
224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        Delegate* delegate) {
225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DispatcherImpl* d = new DispatcherImpl();
226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("bringToFront", &Delegate::ActivateWindow, delegate);
228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("closeWindow", &Delegate::CloseWindow, delegate);
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  d->RegisterHandler("setInspectedPageBounds",
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                     &Delegate::SetInspectedPageBounds, delegate);
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("inspectElementCompleted",
232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     &Delegate::InspectElementCompleted, delegate);
233010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  d->RegisterHandler("inspectedURLChanged",
234010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                     &Delegate::InspectedURLChanged, delegate);
235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("moveWindowBy", &Delegate::MoveWindow, delegate);
236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("setIsDocked", &Delegate::SetIsDocked, delegate);
237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("openInNewTab", &Delegate::OpenInNewTab, delegate);
238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("save", &Delegate::SaveToFile, delegate);
239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("append", &Delegate::AppendToFile, delegate);
240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("requestFileSystems",
241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     &Delegate::RequestFileSystems, delegate);
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("addFileSystem", &Delegate::AddFileSystem, delegate);
243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("removeFileSystem", &Delegate::RemoveFileSystem, delegate);
244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("upgradeDraggedFileSystemPermissions",
245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     &Delegate::UpgradeDraggedFileSystemPermissions, delegate);
246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("indexPath", &Delegate::IndexPath, delegate);
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("stopIndexing", &Delegate::StopIndexing, delegate);
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("searchInPath", &Delegate::SearchInPath, delegate);
249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  d->RegisterHandler("setWhitelistedShortcuts",
250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                     &Delegate::SetWhitelistedShortcuts, delegate);
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("zoomIn", &Delegate::ZoomIn, delegate);
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("zoomOut", &Delegate::ZoomOut, delegate);
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  d->RegisterHandler("resetZoom", &Delegate::ResetZoom, delegate);
254a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  d->RegisterHandler("openUrlOnRemoteDeviceAndInspect",
255a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                     &Delegate::OpenUrlOnRemoteDeviceAndInspect, delegate);
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  d->RegisterHandler("setDeviceCountUpdatesEnabled",
257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     &Delegate::SetDeviceCountUpdatesEnabled, delegate);
258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  d->RegisterHandler("setDevicesUpdatesEnabled",
259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     &Delegate::SetDevicesUpdatesEnabled, delegate);
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  d->RegisterHandler("sendMessageToBrowser",
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                     &Delegate::SendMessageToBrowser, delegate);
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return d;
26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
264