Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/devtools_bridge/client/web_client.h" | 5 #include "components/devtools_bridge/client/web_client.h" |
| 6 | |
| 7 #include <map> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/json/json_writer.h" | |
| 11 #include "base/memory/weak_ptr.h" | |
| 12 #include "base/stl_util.h" | |
| 13 #include "base/values.h" | |
| 6 #include "content/public/browser/web_contents.h" | 14 #include "content/public/browser/web_contents.h" |
| 7 #include "content/public/browser/web_contents_delegate.h" | 15 #include "content/public/browser/web_contents_delegate.h" |
| 16 #include "content/public/browser/web_ui_message_handler.h" | |
| 8 | 17 |
| 9 namespace devtools_bridge { | 18 namespace devtools_bridge { |
| 10 | 19 |
| 11 namespace { | 20 namespace { |
| 12 | 21 |
| 13 class WebClientImpl : public WebClient, private content::WebContentsDelegate { | 22 class JSProxy : public content::WebUIMessageHandler { |
| 14 public: | 23 public: |
| 15 WebClientImpl(content::BrowserContext* context, Delegate* delegate); | 24 class Delegate { |
| 25 public: | |
| 26 virtual void OnLoaded() = 0; | |
| 27 virtual void SendCommand(int request_id, | |
| 28 const std::string& command) = 0; | |
| 29 }; | |
| 30 | |
| 31 explicit JSProxy(Delegate* delegate); | |
| 32 | |
| 33 void RegisterMessages() override; | |
| 34 | |
| 35 void StartSession(const std::string& device_id); | |
| 36 void StopSession(const std::string& device_id); | |
| 16 | 37 |
| 17 private: | 38 private: |
| 39 void HandleLoaded(const base::ListValue* args); | |
| 40 void HandleSendCommand(const base::ListValue* args); | |
| 41 | |
| 18 Delegate* const delegate_; | 42 Delegate* const delegate_; |
| 43 }; | |
| 44 | |
| 45 class ClientSession { | |
| 46 }; | |
| 47 | |
| 48 class WebClientImpl : public WebClient, | |
| 49 private content::WebContentsDelegate, | |
| 50 private JSProxy::Delegate, | |
| 51 public base::SupportsWeakPtr<WebClientImpl> { | |
| 52 public: | |
| 53 WebClientImpl(content::BrowserContext* context, | |
| 54 WebClient::Delegate* delegate); | |
| 55 ~WebClientImpl(); | |
| 56 | |
| 57 // WebClient implementation. | |
| 58 void Connect(const std::string& device_id) override; | |
| 59 void Disconnect(const std::string& device_id) override; | |
| 60 void DisconnectAll() override; | |
| 61 | |
| 62 private: | |
| 63 typedef std::map<std::string, ClientSession*> ClientSessionMap; | |
| 64 | |
| 65 // JSProxy::Delegate | |
| 66 void OnLoaded() override; | |
| 67 void SendCommand(int request_id, | |
| 68 const std::string& command) override; | |
| 69 | |
| 70 | |
|
mnaganov (inactive)
2014/11/24 11:47:20
nit: extra empty line
| |
| 71 void OnCommandSent(int request_id, | |
| 72 const std::string& response); | |
| 73 void OnCommandFailed(int request_id); | |
| 74 | |
| 75 ClientSessionMap client_session_map_; | |
| 76 WebClient::Delegate* const delegate_; | |
| 77 JSProxy js_proxy_; | |
| 19 const scoped_ptr<content::WebContents> web_contents_; | 78 const scoped_ptr<content::WebContents> web_contents_; |
| 79 bool is_loaded_; | |
| 20 }; | 80 }; |
| 21 | 81 |
| 82 // JSProxy implementation | |
| 83 | |
| 84 JSProxy::JSProxy(Delegate* delegate) | |
| 85 : delegate_(delegate) { | |
| 86 } | |
| 87 | |
| 88 void JSProxy::RegisterMessages() { | |
| 89 web_ui()->RegisterMessageCallback( | |
| 90 "loaded", | |
| 91 base::Bind(&JSProxy::HandleLoaded, base::Unretained(this))); | |
| 92 web_ui()->RegisterMessageCallback( | |
| 93 "sendCommand", | |
| 94 base::Bind(&JSProxy::HandleSendCommand, base::Unretained(this))); | |
| 95 } | |
| 96 | |
| 97 void JSProxy::StartSession(const std::string& device_id) { | |
| 98 web_ui()->CallJavascriptFunction( | |
| 99 "WebClient.instance.startSession", | |
| 100 base::StringValue(device_id)); | |
| 101 } | |
| 102 | |
| 103 void JSProxy::StopSession(const std::string& device_id) { | |
| 104 web_ui()->CallJavascriptFunction( | |
| 105 "WebClient.instance.stopSession", | |
| 106 base::StringValue(device_id)); | |
| 107 } | |
| 108 | |
| 109 void JSProxy::HandleLoaded(const base::ListValue* args) { | |
| 110 delegate_->OnLoaded(); | |
| 111 } | |
| 112 | |
| 113 void JSProxy::HandleSendCommand(const base::ListValue* args) { | |
| 114 if (args->GetSize() != 2) { | |
| 115 DLOG(ERROR) << "Wrong number of arguments"; | |
| 116 return; | |
| 117 } | |
| 118 int request_id; | |
| 119 if (!args->GetInteger(0, &request_id)) { | |
| 120 DLOG(ERROR) << "No request id"; | |
| 121 return; | |
| 122 } | |
| 123 const base::DictionaryValue* command; | |
| 124 if (!args->GetDictionary(1, &command)) { | |
| 125 DLOG(ERROR) << "No message"; | |
| 126 return; | |
| 127 } | |
| 128 | |
| 129 std::string json; | |
| 130 if (!base::JSONWriter::Write(command, &json)) { | |
| 131 DLOG(ERROR) << "Failed to serialize message"; | |
| 132 return; | |
| 133 } | |
| 134 | |
| 135 delegate_->SendCommand(request_id, json); | |
| 136 } | |
| 137 | |
| 138 // WebClientImpl implementation. | |
| 139 | |
| 22 WebClientImpl::WebClientImpl(content::BrowserContext* context, | 140 WebClientImpl::WebClientImpl(content::BrowserContext* context, |
| 23 Delegate* delegate) | 141 WebClient::Delegate* delegate) |
| 24 : delegate_(delegate), | 142 : delegate_(delegate), |
| 143 js_proxy_(this), | |
| 25 web_contents_(content::WebContents::Create( | 144 web_contents_(content::WebContents::Create( |
| 26 content::WebContents::CreateParams(context))) { | 145 content::WebContents::CreateParams(context))), |
| 146 is_loaded_(false) { | |
| 27 web_contents_->SetDelegate(this); | 147 web_contents_->SetDelegate(this); |
| 148 GURL url("chrome-devtools://bridge/web_client.html"); | |
| 149 web_contents_->GetController().LoadURL(url, | |
| 150 content::Referrer(), | |
| 151 ui::PAGE_TRANSITION_AUTO_TOPLEVEL, | |
| 152 std::string()); | |
| 153 web_contents_->GetWebUI()->AddMessageHandler(&js_proxy_); | |
| 154 } | |
| 155 | |
| 156 WebClientImpl::~WebClientImpl() { | |
| 157 STLDeleteValues(&client_session_map_); | |
| 158 } | |
| 159 | |
| 160 void WebClientImpl::Connect(const std::string& device_id) { | |
| 161 if (client_session_map_.find(device_id) != client_session_map_.end()) | |
| 162 return; | |
| 163 | |
| 164 if (is_loaded_) | |
| 165 js_proxy_.StartSession(device_id); | |
| 166 | |
| 167 client_session_map_.insert(std::make_pair(device_id, new ClientSession())); | |
| 168 } | |
| 169 | |
| 170 void WebClientImpl::Disconnect(const std::string& device_id) { | |
| 171 ClientSessionMap::iterator session = client_session_map_.find(device_id); | |
| 172 if (session == client_session_map_.end()) | |
| 173 return; | |
| 174 if (is_loaded_) | |
| 175 js_proxy_.StartSession(device_id); | |
| 176 | |
| 177 delete session->second; | |
| 178 client_session_map_.erase(session); | |
| 179 } | |
| 180 | |
| 181 void WebClientImpl::DisconnectAll() { | |
| 182 if (is_loaded_) { | |
| 183 for (ClientSessionMap::iterator i = client_session_map_.begin(); | |
| 184 i != client_session_map_.end(); ++i) { | |
| 185 js_proxy_.StopSession(i->first); | |
| 186 } | |
| 187 } | |
| 188 STLDeleteValues(&client_session_map_); | |
| 189 client_session_map_.clear(); | |
| 190 } | |
| 191 | |
| 192 void WebClientImpl::OnLoaded() { | |
| 193 DCHECK(!is_loaded_); | |
| 194 for (ClientSessionMap::iterator i = client_session_map_.begin(); | |
| 195 i != client_session_map_.end(); ++i) { | |
| 196 js_proxy_.StartSession(i->first); | |
| 197 } | |
| 198 } | |
| 199 | |
| 200 void WebClientImpl::SendCommand(int request_id, | |
| 201 const std::string& command) { | |
| 202 delegate_->SendCommand( | |
| 203 command, | |
| 204 base::Bind(&WebClientImpl::OnCommandSent, AsWeakPtr(), request_id), | |
| 205 base::Bind(&WebClientImpl::OnCommandFailed, AsWeakPtr(), request_id)); | |
| 206 } | |
| 207 | |
| 208 void WebClientImpl::OnCommandSent(int request_id, | |
| 209 const std::string& response) { | |
| 210 // TODO(serya): implement | |
| 211 } | |
| 212 | |
| 213 void WebClientImpl::OnCommandFailed(int request_id) { | |
| 214 // TODO(serya): implement | |
| 28 } | 215 } |
| 29 | 216 |
| 30 } // namespace | 217 } // namespace |
| 31 | 218 |
| 32 scoped_ptr<WebClient> WebClient::CreateInstance( | 219 scoped_ptr<WebClient> WebClient::CreateInstance( |
| 33 content::BrowserContext* context, Delegate* delegate) { | 220 content::BrowserContext* context, Delegate* delegate) { |
| 34 return make_scoped_ptr(new WebClientImpl(context, delegate)); | 221 return make_scoped_ptr(new WebClientImpl(context, delegate)); |
| 35 } | 222 } |
| 36 | 223 |
| 37 } // namespace devtools_bridge | 224 } // namespace devtools_bridge |
| OLD | NEW |