Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/devtools/devtools_embedder_message_dispatcher.h" | 5 #include "chrome/browser/devtools/devtools_embedder_message_dispatcher.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/values.h" | 8 #include "base/values.h" |
| 9 | 9 |
| 10 namespace { | 10 namespace { |
| 11 | 11 |
| 12 bool GetValue(const base::ListValue& list, int pos, std::string& value) { | 12 bool GetValue(const base::Value* value, std::string* result) { |
| 13 return list.GetString(pos, &value); | 13 return value->GetAsString(result); |
| 14 } | 14 } |
| 15 | 15 |
| 16 bool GetValue(const base::ListValue& list, int pos, int& value) { | 16 bool GetValue(const base::Value* value, int* result) { |
| 17 return list.GetInteger(pos, &value); | 17 return value->GetAsInteger(result); |
| 18 } | 18 } |
| 19 | 19 |
| 20 bool GetValue(const base::ListValue& list, int pos, bool& value) { | 20 bool GetValue(const base::Value* value, bool* result) { |
| 21 return list.GetBoolean(pos, &value); | 21 return value->GetAsBoolean(result); |
| 22 } | 22 } |
| 23 | 23 |
| 24 bool GetValue(const base::ListValue& list, int pos, gfx::Rect& rect) { | 24 bool GetValue(const base::Value* value, gfx::Rect* rect) { |
| 25 const base::DictionaryValue* dict; | 25 const base::DictionaryValue* dict; |
| 26 if (!list.GetDictionary(pos, &dict)) | 26 if (!value->GetAsDictionary(&dict)) |
| 27 return false; | 27 return false; |
| 28 int x = 0; | 28 int x = 0; |
| 29 int y = 0; | 29 int y = 0; |
| 30 int width = 0; | 30 int width = 0; |
| 31 int height = 0; | 31 int height = 0; |
| 32 if (!dict->GetInteger("x", &x) || | 32 if (!dict->GetInteger("x", &x) || |
| 33 !dict->GetInteger("y", &y) || | 33 !dict->GetInteger("y", &y) || |
| 34 !dict->GetInteger("width", &width) || | 34 !dict->GetInteger("width", &width) || |
| 35 !dict->GetInteger("height", &height)) | 35 !dict->GetInteger("height", &height)) |
| 36 return false; | 36 return false; |
| 37 rect.SetRect(x, y, width, height); | 37 rect->SetRect(x, y, width, height); |
| 38 return true; | 38 return true; |
| 39 } | 39 } |
| 40 | 40 |
| 41 template <typename T> | 41 template <typename T> |
| 42 struct StorageTraits { | 42 struct StorageTraits { |
| 43 typedef T StorageType; | 43 using StorageType = T; |
| 44 }; | 44 }; |
| 45 | 45 |
| 46 template <typename T> | 46 template <typename T> |
| 47 struct StorageTraits<const T&> { | 47 struct StorageTraits<const T&> { |
| 48 typedef T StorageType; | 48 using StorageType = T; |
| 49 }; | 49 }; |
| 50 | 50 |
| 51 template <class A> | 51 template <typename... Ts> |
| 52 class Argument { | 52 struct Tuple { |
|
Tom Sepez
2015/01/29 17:33:04
nit: worry about confusion with base::Tuple or any
vkuzkokov
2015/01/29 17:49:28
Renamed to ParamTuple.
| |
| 53 public: | 53 bool Parse(const base::ListValue& list, |
| 54 typedef typename StorageTraits<A>::StorageType ValueType; | 54 const base::ListValue::const_iterator& it) { |
| 55 | 55 return it == list.end(); |
| 56 Argument(const base::ListValue& list, int pos) { | |
| 57 valid_ = GetValue(list, pos, value_); | |
| 58 } | 56 } |
| 59 | 57 |
| 60 ValueType value() const { return value_; } | 58 template <typename H, typename... As> |
| 61 bool valid() const { return valid_; } | 59 void Apply(const H& handler, As... args) { |
| 62 | 60 handler.Run(args...); |
| 63 private: | 61 } |
| 64 ValueType value_; | |
| 65 bool valid_; | |
| 66 }; | 62 }; |
| 67 | 63 |
| 68 bool ParseAndHandle0(const base::Callback<void(void)>& handler, | 64 template <typename T, typename... Ts> |
| 69 const base::ListValue& list) { | 65 struct Tuple<T, Ts...> { |
| 70 if (list.GetSize() != 0) | 66 bool Parse(const base::ListValue& list, |
| 67 const base::ListValue::const_iterator& it) { | |
| 68 if (it == list.end()) | |
| 71 return false; | 69 return false; |
| 72 handler.Run(); | 70 if (!GetValue(*it, &head)) |
| 71 return false; | |
| 72 return tail.Parse(list, it + 1); | |
| 73 } | |
| 74 | |
| 75 template <typename H, typename... As> | |
| 76 void Apply(const H& handler, As... args) { | |
| 77 tail.template Apply<H, As..., T>(handler, args..., head); | |
|
dgozman
2015/01/29 10:43:44
Doesn't this reverse the arguments order?
vkuzkokov
2015/01/29 16:11:32
No. |args| is arguments that are already calculate
| |
| 78 } | |
| 79 | |
| 80 typename StorageTraits<T>::StorageType head; | |
| 81 Tuple<Ts...> tail; | |
| 82 }; | |
| 83 | |
| 84 template<typename... As> | |
| 85 bool ParseAndHandle(const base::Callback<void(As...)>& handler, | |
| 86 const base::ListValue& list) { | |
| 87 Tuple<As...> tuple; | |
| 88 if (!tuple.Parse(list, list.begin())) | |
| 89 return false; | |
| 90 tuple.Apply(handler); | |
| 73 return true; | 91 return true; |
| 74 } | 92 } |
| 75 | 93 |
| 76 template <class A1> | |
| 77 bool ParseAndHandle1(const base::Callback<void(A1)>& handler, | |
| 78 const base::ListValue& list) { | |
| 79 if (list.GetSize() != 1) | |
| 80 return false; | |
| 81 Argument<A1> arg1(list, 0); | |
| 82 if (!arg1.valid()) | |
| 83 return false; | |
| 84 handler.Run(arg1.value()); | |
| 85 return true; | |
| 86 } | |
| 87 | |
| 88 template <class A1, class A2> | |
| 89 bool ParseAndHandle2(const base::Callback<void(A1, A2)>& handler, | |
| 90 const base::ListValue& list) { | |
| 91 if (list.GetSize() != 2) | |
| 92 return false; | |
| 93 Argument<A1> arg1(list, 0); | |
| 94 if (!arg1.valid()) | |
| 95 return false; | |
| 96 Argument<A2> arg2(list, 1); | |
| 97 if (!arg2.valid()) | |
| 98 return false; | |
| 99 handler.Run(arg1.value(), arg2.value()); | |
| 100 return true; | |
| 101 } | |
| 102 | |
| 103 template <class A1, class A2, class A3> | |
| 104 bool ParseAndHandle3(const base::Callback<void(A1, A2, A3)>& handler, | |
| 105 const base::ListValue& list) { | |
| 106 if (list.GetSize() != 3) | |
| 107 return false; | |
| 108 Argument<A1> arg1(list, 0); | |
| 109 if (!arg1.valid()) | |
| 110 return false; | |
| 111 Argument<A2> arg2(list, 1); | |
| 112 if (!arg2.valid()) | |
| 113 return false; | |
| 114 Argument<A3> arg3(list, 2); | |
| 115 if (!arg3.valid()) | |
| 116 return false; | |
| 117 handler.Run(arg1.value(), arg2.value(), arg3.value()); | |
| 118 return true; | |
| 119 } | |
| 120 | |
| 121 template <class A1, class A2, class A3, class A4> | |
| 122 bool ParseAndHandle4(const base::Callback<void(A1, A2, A3, A4)>& handler, | |
| 123 const base::ListValue& list) { | |
| 124 if (list.GetSize() != 4) | |
| 125 return false; | |
| 126 Argument<A1> arg1(list, 0); | |
| 127 if (!arg1.valid()) | |
| 128 return false; | |
| 129 Argument<A2> arg2(list, 1); | |
| 130 if (!arg2.valid()) | |
| 131 return false; | |
| 132 Argument<A3> arg3(list, 2); | |
| 133 if (!arg3.valid()) | |
| 134 return false; | |
| 135 Argument<A4> arg4(list, 3); | |
| 136 if (!arg4.valid()) | |
| 137 return false; | |
| 138 handler.Run(arg1.value(), arg2.value(), arg3.value(), arg4.value()); | |
| 139 return true; | |
| 140 } | |
| 141 | |
| 142 } // namespace | 94 } // namespace |
| 143 | 95 |
| 144 /** | 96 /** |
| 145 * Dispatcher for messages sent from the frontend running in an | 97 * Dispatcher for messages sent from the frontend running in an |
| 146 * isolated renderer (chrome-devtools:// or chrome://inspect) to the embedder | 98 * isolated renderer (chrome-devtools:// or chrome://inspect) to the embedder |
| 147 * in the browser. | 99 * in the browser. |
| 148 * | 100 * |
| 149 * The messages are sent via InspectorFrontendHost.sendMessageToEmbedder or | 101 * The messages are sent via InspectorFrontendHost.sendMessageToEmbedder or |
| 150 * chrome.send method accordingly. | 102 * chrome.send method accordingly. |
| 151 */ | 103 */ |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 166 if (error) | 118 if (error) |
| 167 *error = "Invalid frontend host message parameters: " + method; | 119 *error = "Invalid frontend host message parameters: " + method; |
| 168 return false; | 120 return false; |
| 169 } | 121 } |
| 170 | 122 |
| 171 typedef base::Callback<bool(const base::ListValue&)> Handler; | 123 typedef base::Callback<bool(const base::ListValue&)> Handler; |
| 172 void RegisterHandler(const std::string& method, const Handler& handler) { | 124 void RegisterHandler(const std::string& method, const Handler& handler) { |
| 173 handlers_[method] = handler; | 125 handlers_[method] = handler; |
| 174 } | 126 } |
| 175 | 127 |
| 176 template<class T> | 128 template<typename T, typename... As> |
| 177 void RegisterHandler(const std::string& method, | 129 void RegisterHandler(const std::string& method, |
| 178 void (T::*handler)(), T* delegate) { | 130 void (T::*handler)(As...), T* delegate) { |
| 179 handlers_[method] = base::Bind(&ParseAndHandle0, | 131 handlers_[method] = base::Bind(&ParseAndHandle<As...>, |
| 180 base::Bind(handler, | 132 base::Bind(handler, |
| 181 base::Unretained(delegate))); | 133 base::Unretained(delegate))); |
| 182 } | 134 } |
| 183 | |
| 184 template<class T, class A1> | |
| 185 void RegisterHandler(const std::string& method, | |
| 186 void (T::*handler)(A1), T* delegate) { | |
| 187 handlers_[method] = base::Bind(ParseAndHandle1<A1>, | |
| 188 base::Bind(handler, | |
| 189 base::Unretained(delegate))); | |
| 190 } | |
| 191 | |
| 192 template<class T, class A1, class A2> | |
| 193 void RegisterHandler(const std::string& method, | |
| 194 void (T::*handler)(A1, A2), T* delegate) { | |
| 195 handlers_[method] = base::Bind(ParseAndHandle2<A1, A2>, | |
| 196 base::Bind(handler, | |
| 197 base::Unretained(delegate))); | |
| 198 } | |
| 199 | |
| 200 template<class T, class A1, class A2, class A3> | |
| 201 void RegisterHandler(const std::string& method, | |
| 202 void (T::*handler)(A1, A2, A3), T* delegate) { | |
| 203 handlers_[method] = base::Bind(ParseAndHandle3<A1, A2, A3>, | |
| 204 base::Bind(handler, | |
| 205 base::Unretained(delegate))); | |
| 206 } | |
| 207 | |
| 208 template<class T, class A1, class A2, class A3, class A4> | |
| 209 void RegisterHandler(const std::string& method, | |
| 210 void (T::*handler)(A1, A2, A3, A4), T* delegate) { | |
| 211 handlers_[method] = base::Bind(ParseAndHandle4<A1, A2, A3, A4>, | |
| 212 base::Bind(handler, | |
| 213 base::Unretained(delegate))); | |
| 214 } | |
| 215 | 135 |
| 216 private: | 136 private: |
| 217 typedef std::map<std::string, Handler> HandlerMap; | 137 typedef std::map<std::string, Handler> HandlerMap; |
| 218 HandlerMap handlers_; | 138 HandlerMap handlers_; |
| 219 }; | 139 }; |
| 220 | 140 |
| 221 | 141 |
| 222 DevToolsEmbedderMessageDispatcher* | 142 DevToolsEmbedderMessageDispatcher* |
| 223 DevToolsEmbedderMessageDispatcher::createForDevToolsFrontend( | 143 DevToolsEmbedderMessageDispatcher::createForDevToolsFrontend( |
| 224 Delegate* delegate) { | 144 Delegate* delegate) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 256 d->RegisterHandler("setDeviceCountUpdatesEnabled", | 176 d->RegisterHandler("setDeviceCountUpdatesEnabled", |
| 257 &Delegate::SetDeviceCountUpdatesEnabled, delegate); | 177 &Delegate::SetDeviceCountUpdatesEnabled, delegate); |
| 258 d->RegisterHandler("setDevicesUpdatesEnabled", | 178 d->RegisterHandler("setDevicesUpdatesEnabled", |
| 259 &Delegate::SetDevicesUpdatesEnabled, delegate); | 179 &Delegate::SetDevicesUpdatesEnabled, delegate); |
| 260 d->RegisterHandler("sendMessageToBrowser", | 180 d->RegisterHandler("sendMessageToBrowser", |
| 261 &Delegate::SendMessageToBrowser, delegate); | 181 &Delegate::SendMessageToBrowser, delegate); |
| 262 d->RegisterHandler("recordActionUMA", | 182 d->RegisterHandler("recordActionUMA", |
| 263 &Delegate::RecordActionUMA, delegate); | 183 &Delegate::RecordActionUMA, delegate); |
| 264 return d; | 184 return d; |
| 265 } | 185 } |
| OLD | NEW |