Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: content/browser/devtools/devtools_http_handler_impl.cc

Issue 497223003: Revert of Replace StreamListenSocket with StreamSocket in HttpServer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/browser/devtools/devtools_http_handler_impl.h" 5 #include "content/browser/devtools/devtools_http_handler_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 21 matching lines...) Expand all
32 #include "content/public/common/url_constants.h" 32 #include "content/public/common/url_constants.h"
33 #include "content/public/common/user_agent.h" 33 #include "content/public/common/user_agent.h"
34 #include "content/public/common/user_agent.h" 34 #include "content/public/common/user_agent.h"
35 #include "grit/devtools_resources_map.h" 35 #include "grit/devtools_resources_map.h"
36 #include "net/base/escape.h" 36 #include "net/base/escape.h"
37 #include "net/base/io_buffer.h" 37 #include "net/base/io_buffer.h"
38 #include "net/base/ip_endpoint.h" 38 #include "net/base/ip_endpoint.h"
39 #include "net/base/net_errors.h" 39 #include "net/base/net_errors.h"
40 #include "net/server/http_server_request_info.h" 40 #include "net/server/http_server_request_info.h"
41 #include "net/server/http_server_response_info.h" 41 #include "net/server/http_server_response_info.h"
42 #include "net/socket/server_socket.h"
43 42
44 #if defined(OS_ANDROID) 43 #if defined(OS_ANDROID)
45 #include "base/android/build_info.h" 44 #include "base/android/build_info.h"
46 #endif 45 #endif
47 46
48 namespace content { 47 namespace content {
49 48
50 namespace { 49 namespace {
51 50
52 const base::FilePath::CharType kDevToolsActivePortFileName[] = 51 const base::FilePath::CharType kDevToolsActivePortFileName[] =
53 FILE_PATH_LITERAL("DevToolsActivePort"); 52 FILE_PATH_LITERAL("DevToolsActivePort");
54 53
55 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread"; 54 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread";
56 55
57 const char kThumbUrlPrefix[] = "/thumb/"; 56 const char kThumbUrlPrefix[] = "/thumb/";
58 const char kPageUrlPrefix[] = "/devtools/page/"; 57 const char kPageUrlPrefix[] = "/devtools/page/";
59 58
60 const char kTargetIdField[] = "id"; 59 const char kTargetIdField[] = "id";
61 const char kTargetParentIdField[] = "parentId"; 60 const char kTargetParentIdField[] = "parentId";
62 const char kTargetTypeField[] = "type"; 61 const char kTargetTypeField[] = "type";
63 const char kTargetTitleField[] = "title"; 62 const char kTargetTitleField[] = "title";
64 const char kTargetDescriptionField[] = "description"; 63 const char kTargetDescriptionField[] = "description";
65 const char kTargetUrlField[] = "url"; 64 const char kTargetUrlField[] = "url";
66 const char kTargetThumbnailUrlField[] = "thumbnailUrl"; 65 const char kTargetThumbnailUrlField[] = "thumbnailUrl";
67 const char kTargetFaviconUrlField[] = "faviconUrl"; 66 const char kTargetFaviconUrlField[] = "faviconUrl";
68 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; 67 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl";
69 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; 68 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl";
70 69
71 // Maximum write buffer size of devtools http/websocket connectinos.
72 const int32 kSendBufferSizeForDevTools = 100 * 1024 * 1024; // 100Mb
73
74 // An internal implementation of DevToolsAgentHostClient that delegates 70 // An internal implementation of DevToolsAgentHostClient that delegates
75 // messages sent to a DebuggerShell instance. 71 // messages sent to a DebuggerShell instance.
76 class DevToolsAgentHostClientImpl : public DevToolsAgentHostClient { 72 class DevToolsAgentHostClientImpl : public DevToolsAgentHostClient {
77 public: 73 public:
78 DevToolsAgentHostClientImpl(base::MessageLoop* message_loop, 74 DevToolsAgentHostClientImpl(base::MessageLoop* message_loop,
79 net::HttpServer* server, 75 net::HttpServer* server,
80 int connection_id, 76 int connection_id,
81 DevToolsAgentHost* agent_host) 77 DevToolsAgentHost* agent_host)
82 : message_loop_(message_loop), 78 : message_loop_(message_loop),
83 server_(server), 79 server_(server),
(...skipping 17 matching lines...) Expand all
101 notification.SetString( 97 notification.SetString(
102 devtools::Inspector::detached::kParamReason, 98 devtools::Inspector::detached::kParamReason,
103 replaced_with_another_client ? 99 replaced_with_another_client ?
104 "replaced_with_devtools" : "target_closed"); 100 "replaced_with_devtools" : "target_closed");
105 std::string response = DevToolsProtocol::CreateNotification( 101 std::string response = DevToolsProtocol::CreateNotification(
106 devtools::Inspector::detached::kName, 102 devtools::Inspector::detached::kName,
107 notification.DeepCopy())->Serialize(); 103 notification.DeepCopy())->Serialize();
108 message_loop_->PostTask( 104 message_loop_->PostTask(
109 FROM_HERE, 105 FROM_HERE,
110 base::Bind(&net::HttpServer::SendOverWebSocket, 106 base::Bind(&net::HttpServer::SendOverWebSocket,
111 base::Unretained(server_), 107 server_,
112 connection_id_, 108 connection_id_,
113 response)); 109 response));
114 110
115 message_loop_->PostTask( 111 message_loop_->PostTask(
116 FROM_HERE, 112 FROM_HERE,
117 base::Bind(&net::HttpServer::Close, 113 base::Bind(&net::HttpServer::Close, server_, connection_id_));
118 base::Unretained(server_),
119 connection_id_));
120 } 114 }
121 115
122 virtual void DispatchProtocolMessage( 116 virtual void DispatchProtocolMessage(
123 DevToolsAgentHost* agent_host, const std::string& message) OVERRIDE { 117 DevToolsAgentHost* agent_host, const std::string& message) OVERRIDE {
124 DCHECK(agent_host == agent_host_.get()); 118 DCHECK(agent_host == agent_host_.get());
125 message_loop_->PostTask( 119 message_loop_->PostTask(
126 FROM_HERE, 120 FROM_HERE,
127 base::Bind(&net::HttpServer::SendOverWebSocket, 121 base::Bind(&net::HttpServer::SendOverWebSocket,
128 base::Unretained(server_), 122 server_,
129 connection_id_, 123 connection_id_,
130 message)); 124 message));
131 } 125 }
132 126
133 void OnMessage(const std::string& message) { 127 void OnMessage(const std::string& message) {
134 if (agent_host_) 128 if (agent_host_)
135 agent_host_->DispatchProtocolMessage(message); 129 agent_host_->DispatchProtocolMessage(message);
136 } 130 }
137 131
138 private: 132 private:
139 base::MessageLoop* const message_loop_; 133 base::MessageLoop* message_loop_;
140 net::HttpServer* const server_; 134 net::HttpServer* server_;
141 const int connection_id_; 135 int connection_id_;
142 scoped_refptr<DevToolsAgentHost> agent_host_; 136 scoped_refptr<DevToolsAgentHost> agent_host_;
143 }; 137 };
144 138
145 static bool TimeComparator(const DevToolsTarget* target1, 139 static bool TimeComparator(const DevToolsTarget* target1,
146 const DevToolsTarget* target2) { 140 const DevToolsTarget* target2) {
147 return target1->GetLastActivityTime() > target2->GetLastActivityTime(); 141 return target1->GetLastActivityTime() > target2->GetLastActivityTime();
148 } 142 }
149 143
150 } // namespace 144 } // namespace
151 145
152 // static 146 // static
153 bool DevToolsHttpHandler::IsSupportedProtocolVersion( 147 bool DevToolsHttpHandler::IsSupportedProtocolVersion(
154 const std::string& version) { 148 const std::string& version) {
155 return devtools::IsSupportedProtocolVersion(version); 149 return devtools::IsSupportedProtocolVersion(version);
156 } 150 }
157 151
158 // static 152 // static
159 int DevToolsHttpHandler::GetFrontendResourceId(const std::string& name) { 153 int DevToolsHttpHandler::GetFrontendResourceId(const std::string& name) {
160 for (size_t i = 0; i < kDevtoolsResourcesSize; ++i) { 154 for (size_t i = 0; i < kDevtoolsResourcesSize; ++i) {
161 if (name == kDevtoolsResources[i].name) 155 if (name == kDevtoolsResources[i].name)
162 return kDevtoolsResources[i].value; 156 return kDevtoolsResources[i].value;
163 } 157 }
164 return -1; 158 return -1;
165 } 159 }
166 160
167 // static 161 // static
168 DevToolsHttpHandler* DevToolsHttpHandler::Start( 162 DevToolsHttpHandler* DevToolsHttpHandler::Start(
169 scoped_ptr<ServerSocketFactory> server_socket_factory, 163 const net::StreamListenSocketFactory* socket_factory,
170 const std::string& frontend_url, 164 const std::string& frontend_url,
171 DevToolsHttpHandlerDelegate* delegate, 165 DevToolsHttpHandlerDelegate* delegate,
172 const base::FilePath& active_port_output_directory) { 166 const base::FilePath& active_port_output_directory) {
173 DevToolsHttpHandlerImpl* http_handler = 167 DevToolsHttpHandlerImpl* http_handler =
174 new DevToolsHttpHandlerImpl(server_socket_factory.Pass(), 168 new DevToolsHttpHandlerImpl(socket_factory,
175 frontend_url, 169 frontend_url,
176 delegate, 170 delegate,
177 active_port_output_directory); 171 active_port_output_directory);
178 http_handler->Start(); 172 http_handler->Start();
179 return http_handler; 173 return http_handler;
180 } 174 }
181 175
182 DevToolsHttpHandler::ServerSocketFactory::ServerSocketFactory(
183 const std::string& address,
184 int port,
185 int backlog)
186 : address_(address),
187 port_(port),
188 backlog_(backlog) {
189 }
190
191 DevToolsHttpHandler::ServerSocketFactory::~ServerSocketFactory() {
192 }
193
194 scoped_ptr<net::ServerSocket>
195 DevToolsHttpHandler::ServerSocketFactory::CreateAndListen() const {
196 scoped_ptr<net::ServerSocket> socket = Create();
197 if (socket &&
198 socket->ListenWithAddressAndPort(address_, port_, backlog_) == net::OK) {
199 return socket.Pass();
200 }
201 return scoped_ptr<net::ServerSocket>();
202 }
203
204 DevToolsHttpHandlerImpl::~DevToolsHttpHandlerImpl() { 176 DevToolsHttpHandlerImpl::~DevToolsHttpHandlerImpl() {
205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
206 // Stop() must be called prior to destruction. 178 // Stop() must be called prior to destruction.
207 DCHECK(server_.get() == NULL); 179 DCHECK(server_.get() == NULL);
208 DCHECK(thread_.get() == NULL); 180 DCHECK(thread_.get() == NULL);
209 STLDeleteValues(&target_map_); 181 STLDeleteValues(&target_map_);
210 } 182 }
211 183
212 void DevToolsHttpHandlerImpl::Start() { 184 void DevToolsHttpHandlerImpl::Start() {
213 if (thread_) 185 if (thread_)
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 LOG(ERROR) << "GetMimeType doesn't know mime type for: " 255 LOG(ERROR) << "GetMimeType doesn't know mime type for: "
284 << filename 256 << filename
285 << " text/plain will be returned"; 257 << " text/plain will be returned";
286 NOTREACHED(); 258 NOTREACHED();
287 return "text/plain"; 259 return "text/plain";
288 } 260 }
289 261
290 void DevToolsHttpHandlerImpl::OnHttpRequest( 262 void DevToolsHttpHandlerImpl::OnHttpRequest(
291 int connection_id, 263 int connection_id,
292 const net::HttpServerRequestInfo& info) { 264 const net::HttpServerRequestInfo& info) {
293 server_->SetSendBufferSize(connection_id, kSendBufferSizeForDevTools);
294
295 if (info.path.find("/json") == 0) { 265 if (info.path.find("/json") == 0) {
296 BrowserThread::PostTask( 266 BrowserThread::PostTask(
297 BrowserThread::UI, 267 BrowserThread::UI,
298 FROM_HERE, 268 FROM_HERE,
299 base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequestUI, 269 base::Bind(&DevToolsHttpHandlerImpl::OnJsonRequestUI,
300 this, 270 this,
301 connection_id, 271 connection_id,
302 info)); 272 info));
303 return; 273 return;
304 } 274 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 browser_target->RegisterDomainHandler( 344 browser_target->RegisterDomainHandler(
375 TetheringHandler::kDomain, 345 TetheringHandler::kDomain,
376 new TetheringHandler(delegate_.get()), 346 new TetheringHandler(delegate_.get()),
377 false /* handle on this thread */); 347 false /* handle on this thread */);
378 browser_target->RegisterDomainHandler( 348 browser_target->RegisterDomainHandler(
379 devtools::SystemInfo::kName, 349 devtools::SystemInfo::kName,
380 new DevToolsSystemInfoHandler(), 350 new DevToolsSystemInfoHandler(),
381 true /* handle on UI thread */); 351 true /* handle on UI thread */);
382 browser_targets_[connection_id] = browser_target; 352 browser_targets_[connection_id] = browser_target;
383 353
384 server_->SetSendBufferSize(connection_id, kSendBufferSizeForDevTools);
385 server_->AcceptWebSocket(connection_id, request); 354 server_->AcceptWebSocket(connection_id, request);
386 return; 355 return;
387 } 356 }
388 357
389 BrowserThread::PostTask( 358 BrowserThread::PostTask(
390 BrowserThread::UI, 359 BrowserThread::UI,
391 FROM_HERE, 360 FROM_HERE,
392 base::Bind( 361 base::Bind(
393 &DevToolsHttpHandlerImpl::OnWebSocketRequestUI, 362 &DevToolsHttpHandlerImpl::OnWebSocketRequestUI,
394 this, 363 this,
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 connection_to_client_ui_.find(connection_id); 644 connection_to_client_ui_.find(connection_id);
676 if (it != connection_to_client_ui_.end()) { 645 if (it != connection_to_client_ui_.end()) {
677 DevToolsAgentHostClientImpl* client = 646 DevToolsAgentHostClientImpl* client =
678 static_cast<DevToolsAgentHostClientImpl*>(it->second); 647 static_cast<DevToolsAgentHostClientImpl*>(it->second);
679 delete client; 648 delete client;
680 connection_to_client_ui_.erase(connection_id); 649 connection_to_client_ui_.erase(connection_id);
681 } 650 }
682 } 651 }
683 652
684 DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl( 653 DevToolsHttpHandlerImpl::DevToolsHttpHandlerImpl(
685 scoped_ptr<ServerSocketFactory> server_socket_factory, 654 const net::StreamListenSocketFactory* socket_factory,
686 const std::string& frontend_url, 655 const std::string& frontend_url,
687 DevToolsHttpHandlerDelegate* delegate, 656 DevToolsHttpHandlerDelegate* delegate,
688 const base::FilePath& active_port_output_directory) 657 const base::FilePath& active_port_output_directory)
689 : frontend_url_(frontend_url), 658 : frontend_url_(frontend_url),
690 server_socket_factory_(server_socket_factory.Pass()), 659 socket_factory_(socket_factory),
691 delegate_(delegate), 660 delegate_(delegate),
692 active_port_output_directory_(active_port_output_directory) { 661 active_port_output_directory_(active_port_output_directory) {
693 if (frontend_url_.empty()) 662 if (frontend_url_.empty())
694 frontend_url_ = "/devtools/devtools.html"; 663 frontend_url_ = "/devtools/devtools.html";
695 664
696 // Balanced in ResetHandlerThreadAndRelease(). 665 // Balanced in ResetHandlerThreadAndRelease().
697 AddRef(); 666 AddRef();
698 } 667 }
699 668
700 // Runs on the handler thread 669 // Runs on the handler thread
701 void DevToolsHttpHandlerImpl::Init() { 670 void DevToolsHttpHandlerImpl::Init() {
702 server_.reset(new net::HttpServer(server_socket_factory_->CreateAndListen(), 671 server_ = new net::HttpServer(*socket_factory_.get(), this);
703 this));
704 if (!active_port_output_directory_.empty()) 672 if (!active_port_output_directory_.empty())
705 WriteActivePortToUserProfile(); 673 WriteActivePortToUserProfile();
706 } 674 }
707 675
708 // Runs on the handler thread 676 // Runs on the handler thread
709 void DevToolsHttpHandlerImpl::Teardown() { 677 void DevToolsHttpHandlerImpl::Teardown() {
710 server_.reset(NULL); 678 server_ = NULL;
711 } 679 }
712 680
713 // Runs on FILE thread to make sure that it is serialized against 681 // Runs on FILE thread to make sure that it is serialized against
714 // {Start|Stop}HandlerThread and to allow calling pthread_join. 682 // {Start|Stop}HandlerThread and to allow calling pthread_join.
715 void DevToolsHttpHandlerImpl::StopHandlerThread() { 683 void DevToolsHttpHandlerImpl::StopHandlerThread() {
716 if (!thread_->message_loop()) 684 if (!thread_->message_loop())
717 return; 685 return;
718 thread_->message_loop()->PostTask( 686 thread_->message_loop()->PostTask(
719 FROM_HERE, 687 FROM_HERE,
720 base::Bind(&DevToolsHttpHandlerImpl::Teardown, this)); 688 base::Bind(&DevToolsHttpHandlerImpl::Teardown, this));
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 std::string json_message; 726 std::string json_message;
759 scoped_ptr<base::Value> message_object(new base::StringValue(message)); 727 scoped_ptr<base::Value> message_object(new base::StringValue(message));
760 base::JSONWriter::Write(message_object.get(), &json_message); 728 base::JSONWriter::Write(message_object.get(), &json_message);
761 729
762 net::HttpServerResponseInfo response(status_code); 730 net::HttpServerResponseInfo response(status_code);
763 response.SetBody(json_value + message, "application/json; charset=UTF-8"); 731 response.SetBody(json_value + message, "application/json; charset=UTF-8");
764 732
765 thread_->message_loop()->PostTask( 733 thread_->message_loop()->PostTask(
766 FROM_HERE, 734 FROM_HERE,
767 base::Bind(&net::HttpServer::SendResponse, 735 base::Bind(&net::HttpServer::SendResponse,
768 base::Unretained(server_.get()), 736 server_.get(),
769 connection_id, 737 connection_id,
770 response)); 738 response));
771 } 739 }
772 740
773 void DevToolsHttpHandlerImpl::Send200(int connection_id, 741 void DevToolsHttpHandlerImpl::Send200(int connection_id,
774 const std::string& data, 742 const std::string& data,
775 const std::string& mime_type) { 743 const std::string& mime_type) {
776 if (!thread_) 744 if (!thread_)
777 return; 745 return;
778 thread_->message_loop()->PostTask( 746 thread_->message_loop()->PostTask(
779 FROM_HERE, 747 FROM_HERE,
780 base::Bind(&net::HttpServer::Send200, 748 base::Bind(&net::HttpServer::Send200,
781 base::Unretained(server_.get()), 749 server_.get(),
782 connection_id, 750 connection_id,
783 data, 751 data,
784 mime_type)); 752 mime_type));
785 } 753 }
786 754
787 void DevToolsHttpHandlerImpl::Send404(int connection_id) { 755 void DevToolsHttpHandlerImpl::Send404(int connection_id) {
788 if (!thread_) 756 if (!thread_)
789 return; 757 return;
790 thread_->message_loop()->PostTask( 758 thread_->message_loop()->PostTask(
791 FROM_HERE, 759 FROM_HERE,
792 base::Bind(&net::HttpServer::Send404, 760 base::Bind(&net::HttpServer::Send404, server_.get(), connection_id));
793 base::Unretained(server_.get()),
794 connection_id));
795 } 761 }
796 762
797 void DevToolsHttpHandlerImpl::Send500(int connection_id, 763 void DevToolsHttpHandlerImpl::Send500(int connection_id,
798 const std::string& message) { 764 const std::string& message) {
799 if (!thread_) 765 if (!thread_)
800 return; 766 return;
801 thread_->message_loop()->PostTask( 767 thread_->message_loop()->PostTask(
802 FROM_HERE, 768 FROM_HERE,
803 base::Bind(&net::HttpServer::Send500, 769 base::Bind(&net::HttpServer::Send500, server_.get(), connection_id,
804 base::Unretained(server_.get()),
805 connection_id,
806 message)); 770 message));
807 } 771 }
808 772
809 void DevToolsHttpHandlerImpl::AcceptWebSocket( 773 void DevToolsHttpHandlerImpl::AcceptWebSocket(
810 int connection_id, 774 int connection_id,
811 const net::HttpServerRequestInfo& request) { 775 const net::HttpServerRequestInfo& request) {
812 if (!thread_) 776 if (!thread_)
813 return; 777 return;
814 thread_->message_loop()->PostTask( 778 thread_->message_loop()->PostTask(
815 FROM_HERE, 779 FROM_HERE,
816 base::Bind(&net::HttpServer::SetSendBufferSize, 780 base::Bind(&net::HttpServer::AcceptWebSocket, server_.get(),
817 base::Unretained(server_.get()), 781 connection_id, request));
818 connection_id,
819 kSendBufferSizeForDevTools));
820 thread_->message_loop()->PostTask(
821 FROM_HERE,
822 base::Bind(&net::HttpServer::AcceptWebSocket,
823 base::Unretained(server_.get()),
824 connection_id,
825 request));
826 } 782 }
827 783
828 base::DictionaryValue* DevToolsHttpHandlerImpl::SerializeTarget( 784 base::DictionaryValue* DevToolsHttpHandlerImpl::SerializeTarget(
829 const DevToolsTarget& target, 785 const DevToolsTarget& target,
830 const std::string& host) { 786 const std::string& host) {
831 base::DictionaryValue* dictionary = new base::DictionaryValue; 787 base::DictionaryValue* dictionary = new base::DictionaryValue;
832 788
833 std::string id = target.GetId(); 789 std::string id = target.GetId();
834 dictionary->SetString(kTargetIdField, id); 790 dictionary->SetString(kTargetIdField, id);
835 std::string parent_id = target.GetParentId(); 791 std::string parent_id = target.GetParentId();
(...skipping 26 matching lines...) Expand all
862 id.c_str(), 818 id.c_str(),
863 host); 819 host);
864 dictionary->SetString( 820 dictionary->SetString(
865 kTargetDevtoolsFrontendUrlField, devtools_frontend_url); 821 kTargetDevtoolsFrontendUrlField, devtools_frontend_url);
866 } 822 }
867 823
868 return dictionary; 824 return dictionary;
869 } 825 }
870 826
871 } // namespace content 827 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/devtools/devtools_http_handler_impl.h ('k') | content/browser/devtools/devtools_http_handler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698