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 |