Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 41 #if defined(OS_ANDROID) | 41 #if defined(OS_ANDROID) |
| 42 #include "base/android/build_info.h" | 42 #include "base/android/build_info.h" |
| 43 #endif | 43 #endif |
| 44 | 44 |
| 45 namespace content { | 45 namespace content { |
| 46 | 46 |
| 47 namespace { | 47 namespace { |
| 48 | 48 |
| 49 const base::FilePath::CharType kDevToolsActivePortFileName[] = | 49 const base::FilePath::CharType kDevToolsActivePortFileName[] = |
| 50 FILE_PATH_LITERAL("DevToolsActivePort"); | 50 FILE_PATH_LITERAL("DevToolsActivePort"); |
| 51 const base::FilePath::CharType kDevToolsBrowserTargetFileName[] = | |
| 52 FILE_PATH_LITERAL("DevToolsBrowserTarget"); | |
| 51 | 53 |
| 52 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread"; | 54 const char kDevToolsHandlerThreadName[] = "Chrome_DevToolsHandlerThread"; |
| 53 | 55 |
| 54 const char kPageUrlPrefix[] = "/devtools/page/"; | 56 const char kPageUrlPrefix[] = "/devtools/page/"; |
| 57 const char kBrowserUrlPrefix[] = "/devtools/browser"; | |
| 55 | 58 |
| 56 const char kTargetIdField[] = "id"; | 59 const char kTargetIdField[] = "id"; |
| 57 const char kTargetParentIdField[] = "parentId"; | 60 const char kTargetParentIdField[] = "parentId"; |
| 58 const char kTargetTypeField[] = "type"; | 61 const char kTargetTypeField[] = "type"; |
| 59 const char kTargetTitleField[] = "title"; | 62 const char kTargetTitleField[] = "title"; |
| 60 const char kTargetDescriptionField[] = "description"; | 63 const char kTargetDescriptionField[] = "description"; |
| 61 const char kTargetUrlField[] = "url"; | 64 const char kTargetUrlField[] = "url"; |
| 62 const char kTargetFaviconUrlField[] = "faviconUrl"; | 65 const char kTargetFaviconUrlField[] = "faviconUrl"; |
| 63 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; | 66 const char kTargetWebSocketDebuggerUrlField[] = "webSocketDebuggerUrl"; |
| 64 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; | 67 const char kTargetDevtoolsFrontendUrlField[] = "devtoolsFrontendUrl"; |
| 65 | 68 |
| 66 // Maximum write buffer size of devtools http/websocket connections. | 69 // Maximum write buffer size of devtools http/websocket connections. |
| 67 // TODO(rmcilroy/pfieldman): Reduce this back to 100Mb when we have | 70 // TODO(rmcilroy/pfieldman): Reduce this back to 100Mb when we have |
| 68 // added back pressure on the TraceComplete message protocol - crbug.com/456845. | 71 // added back pressure on the TraceComplete message protocol - crbug.com/456845. |
| 69 const int32_t kSendBufferSizeForDevTools = 256 * 1024 * 1024; // 256Mb | 72 const int32_t kSendBufferSizeForDevTools = 256 * 1024 * 1024; // 256Mb |
| 70 | 73 |
| 71 } // namespace | 74 } // namespace |
| 72 | 75 |
| 73 // ServerWrapper ------------------------------------------------------------- | 76 // ServerWrapper ------------------------------------------------------------- |
| 74 // All methods in this class are only called on handler thread. | 77 // All methods in this class are only called on handler thread. |
| 75 class ServerWrapper : net::HttpServer::Delegate { | 78 class ServerWrapper : net::HttpServer::Delegate { |
| 76 public: | 79 public: |
| 77 ServerWrapper(base::WeakPtr<DevToolsHttpHandler> handler, | 80 ServerWrapper(base::WeakPtr<DevToolsHttpHandler> handler, |
| 78 std::unique_ptr<net::ServerSocket> socket, | 81 std::unique_ptr<net::ServerSocket> socket, |
| 79 const base::FilePath& frontend_dir, | 82 const base::FilePath& frontend_dir, |
| 83 const std::string& browser_guid, | |
| 80 bool bundles_resources); | 84 bool bundles_resources); |
| 81 | 85 |
| 82 int GetLocalAddress(net::IPEndPoint* address); | 86 int GetLocalAddress(net::IPEndPoint* address); |
| 83 | 87 |
| 84 void AcceptWebSocket(int connection_id, | 88 void AcceptWebSocket(int connection_id, |
| 85 const net::HttpServerRequestInfo& request); | 89 const net::HttpServerRequestInfo& request); |
| 86 void SendOverWebSocket(int connection_id, const std::string& message); | 90 void SendOverWebSocket(int connection_id, const std::string& message); |
| 87 void SendResponse(int connection_id, | 91 void SendResponse(int connection_id, |
| 88 const net::HttpServerResponseInfo& response); | 92 const net::HttpServerResponseInfo& response); |
| 89 void Send200(int connection_id, | 93 void Send200(int connection_id, |
| 90 const std::string& data, | 94 const std::string& data, |
| 91 const std::string& mime_type); | 95 const std::string& mime_type); |
| 92 void Send404(int connection_id); | 96 void Send404(int connection_id); |
| 93 void Send500(int connection_id, const std::string& message); | 97 void Send500(int connection_id, const std::string& message); |
| 94 void Close(int connection_id); | 98 void Close(int connection_id); |
| 95 | 99 |
| 96 void WriteActivePortToUserProfile(const base::FilePath& output_directory); | 100 void WriteActivePortAndGuidToUserProfile( |
| 101 const base::FilePath& output_directory); | |
| 97 | 102 |
| 98 ~ServerWrapper() override {} | 103 ~ServerWrapper() override {} |
| 99 | 104 |
| 100 private: | 105 private: |
| 101 // net::HttpServer::Delegate implementation. | 106 // net::HttpServer::Delegate implementation. |
| 102 void OnConnect(int connection_id) override {} | 107 void OnConnect(int connection_id) override {} |
| 103 void OnHttpRequest(int connection_id, | 108 void OnHttpRequest(int connection_id, |
| 104 const net::HttpServerRequestInfo& info) override; | 109 const net::HttpServerRequestInfo& info) override; |
| 105 void OnWebSocketRequest(int connection_id, | 110 void OnWebSocketRequest(int connection_id, |
| 106 const net::HttpServerRequestInfo& info) override; | 111 const net::HttpServerRequestInfo& info) override; |
| 107 void OnWebSocketMessage(int connection_id, | 112 void OnWebSocketMessage(int connection_id, |
| 108 const std::string& data) override; | 113 const std::string& data) override; |
| 109 void OnClose(int connection_id) override; | 114 void OnClose(int connection_id) override; |
| 110 | 115 |
| 111 base::WeakPtr<DevToolsHttpHandler> handler_; | 116 base::WeakPtr<DevToolsHttpHandler> handler_; |
| 112 std::unique_ptr<net::HttpServer> server_; | 117 std::unique_ptr<net::HttpServer> server_; |
| 113 base::FilePath frontend_dir_; | 118 base::FilePath frontend_dir_; |
| 119 std::string browser_guid_; | |
| 114 bool bundles_resources_; | 120 bool bundles_resources_; |
| 115 }; | 121 }; |
| 116 | 122 |
| 117 ServerWrapper::ServerWrapper(base::WeakPtr<DevToolsHttpHandler> handler, | 123 ServerWrapper::ServerWrapper(base::WeakPtr<DevToolsHttpHandler> handler, |
| 118 std::unique_ptr<net::ServerSocket> socket, | 124 std::unique_ptr<net::ServerSocket> socket, |
| 119 const base::FilePath& frontend_dir, | 125 const base::FilePath& frontend_dir, |
| 126 const std::string& browser_guid, | |
| 120 bool bundles_resources) | 127 bool bundles_resources) |
| 121 : handler_(handler), | 128 : handler_(handler), |
| 122 server_(new net::HttpServer(std::move(socket), this)), | 129 server_(new net::HttpServer(std::move(socket), this)), |
| 123 frontend_dir_(frontend_dir), | 130 frontend_dir_(frontend_dir), |
| 131 browser_guid_(browser_guid), | |
| 124 bundles_resources_(bundles_resources) {} | 132 bundles_resources_(bundles_resources) {} |
| 125 | 133 |
| 126 int ServerWrapper::GetLocalAddress(net::IPEndPoint* address) { | 134 int ServerWrapper::GetLocalAddress(net::IPEndPoint* address) { |
| 127 return server_->GetLocalAddress(address); | 135 return server_->GetLocalAddress(address); |
| 128 } | 136 } |
| 129 | 137 |
| 130 void ServerWrapper::AcceptWebSocket(int connection_id, | 138 void ServerWrapper::AcceptWebSocket(int connection_id, |
| 131 const net::HttpServerRequestInfo& request) { | 139 const net::HttpServerRequestInfo& request) { |
| 132 server_->SetSendBufferSize(connection_id, kSendBufferSizeForDevTools); | 140 server_->SetSendBufferSize(connection_id, kSendBufferSizeForDevTools); |
| 133 server_->AcceptWebSocket(connection_id, request); | 141 server_->AcceptWebSocket(connection_id, request); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 std::unique_ptr<net::IPEndPoint> ip_address) { | 196 std::unique_ptr<net::IPEndPoint> ip_address) { |
| 189 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 197 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 190 if (handler && thread && server_wrapper) { | 198 if (handler && thread && server_wrapper) { |
| 191 handler->ServerStarted(thread, server_wrapper, socket_factory, | 199 handler->ServerStarted(thread, server_wrapper, socket_factory, |
| 192 std::move(ip_address)); | 200 std::move(ip_address)); |
| 193 } else { | 201 } else { |
| 194 TerminateOnUI(thread, server_wrapper, socket_factory); | 202 TerminateOnUI(thread, server_wrapper, socket_factory); |
| 195 } | 203 } |
| 196 } | 204 } |
| 197 | 205 |
| 198 void StartServerOnHandlerThread( | 206 void StartServerOnHandlerThread(base::WeakPtr<DevToolsHttpHandler> handler, |
| 199 base::WeakPtr<DevToolsHttpHandler> handler, | 207 base::Thread* thread, |
| 200 base::Thread* thread, | 208 DevToolsSocketFactory* socket_factory, |
| 201 DevToolsSocketFactory* socket_factory, | 209 const base::FilePath& output_directory, |
| 202 const base::FilePath& output_directory, | 210 const base::FilePath& frontend_dir, |
| 203 const base::FilePath& frontend_dir, | 211 const std::string& browser_guid, |
| 204 bool bundles_resources) { | 212 bool bundles_resources) { |
| 205 DCHECK(thread->task_runner()->BelongsToCurrentThread()); | 213 DCHECK(thread->task_runner()->BelongsToCurrentThread()); |
| 206 ServerWrapper* server_wrapper = nullptr; | 214 ServerWrapper* server_wrapper = nullptr; |
| 207 std::unique_ptr<net::ServerSocket> server_socket = | 215 std::unique_ptr<net::ServerSocket> server_socket = |
| 208 socket_factory->CreateForHttpServer(); | 216 socket_factory->CreateForHttpServer(); |
| 209 std::unique_ptr<net::IPEndPoint> ip_address(new net::IPEndPoint); | 217 std::unique_ptr<net::IPEndPoint> ip_address(new net::IPEndPoint); |
| 210 if (server_socket) { | 218 if (server_socket) { |
| 211 server_wrapper = new ServerWrapper(handler, std::move(server_socket), | 219 server_wrapper = |
| 212 frontend_dir, bundles_resources); | 220 new ServerWrapper(handler, std::move(server_socket), frontend_dir, |
| 221 browser_guid, bundles_resources); | |
| 213 if (!output_directory.empty()) | 222 if (!output_directory.empty()) |
| 214 server_wrapper->WriteActivePortToUserProfile(output_directory); | 223 server_wrapper->WriteActivePortAndGuidToUserProfile(output_directory); |
| 215 | 224 |
| 216 if (server_wrapper->GetLocalAddress(ip_address.get()) != net::OK) | 225 if (server_wrapper->GetLocalAddress(ip_address.get()) != net::OK) |
| 217 ip_address.reset(); | 226 ip_address.reset(); |
| 218 } else { | 227 } else { |
| 219 ip_address.reset(); | 228 ip_address.reset(); |
| 220 LOG(ERROR) << "Cannot start http server for devtools. Stop devtools."; | 229 LOG(ERROR) << "Cannot start http server for devtools. Stop devtools."; |
| 221 } | 230 } |
| 222 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 231 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 223 base::Bind(&ServerStartedOnUI, | 232 base::Bind(&ServerStartedOnUI, |
| 224 handler, | 233 handler, |
| 225 thread, | 234 thread, |
| 226 server_wrapper, | 235 server_wrapper, |
| 227 socket_factory, | 236 socket_factory, |
| 228 base::Passed(&ip_address))); | 237 base::Passed(&ip_address))); |
| 229 } | 238 } |
| 230 | 239 |
| 231 void StartServerOnFile( | 240 void StartServerOnFile(base::WeakPtr<DevToolsHttpHandler> handler, |
| 232 base::WeakPtr<DevToolsHttpHandler> handler, | 241 DevToolsSocketFactory* socket_factory, |
| 233 DevToolsSocketFactory* socket_factory, | 242 const base::FilePath& output_directory, |
| 234 const base::FilePath& output_directory, | 243 const base::FilePath& frontend_dir, |
| 235 const base::FilePath& frontend_dir, | 244 const std::string& browser_guid, |
| 236 bool bundles_resources) { | 245 bool bundles_resources) { |
| 237 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 246 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
| 238 std::unique_ptr<base::Thread> thread( | 247 std::unique_ptr<base::Thread> thread( |
| 239 new base::Thread(kDevToolsHandlerThreadName)); | 248 new base::Thread(kDevToolsHandlerThreadName)); |
| 240 base::Thread::Options options; | 249 base::Thread::Options options; |
| 241 options.message_loop_type = base::MessageLoop::TYPE_IO; | 250 options.message_loop_type = base::MessageLoop::TYPE_IO; |
| 242 if (thread->StartWithOptions(options)) { | 251 if (thread->StartWithOptions(options)) { |
| 243 base::MessageLoop* message_loop = thread->message_loop(); | 252 base::MessageLoop* message_loop = thread->message_loop(); |
| 244 message_loop->task_runner()->PostTask( | 253 message_loop->task_runner()->PostTask( |
| 245 FROM_HERE, | 254 FROM_HERE, base::Bind(&StartServerOnHandlerThread, handler, |
| 246 base::Bind(&StartServerOnHandlerThread, handler, | 255 base::Unretained(thread.release()), |
| 247 base::Unretained(thread.release()), socket_factory, | 256 socket_factory, output_directory, frontend_dir, |
| 248 output_directory, frontend_dir, bundles_resources)); | 257 browser_guid, bundles_resources)); |
| 249 } | 258 } |
| 250 } | 259 } |
| 251 | 260 |
| 252 // DevToolsAgentHostClientImpl ----------------------------------------------- | 261 // DevToolsAgentHostClientImpl ----------------------------------------------- |
| 253 // An internal implementation of DevToolsAgentHostClient that delegates | 262 // An internal implementation of DevToolsAgentHostClient that delegates |
| 254 // messages sent to a DebuggerShell instance. | 263 // messages sent to a DebuggerShell instance. |
| 255 class DevToolsAgentHostClientImpl : public DevToolsAgentHostClient { | 264 class DevToolsAgentHostClientImpl : public DevToolsAgentHostClient { |
| 256 public: | 265 public: |
| 257 DevToolsAgentHostClientImpl(base::MessageLoop* message_loop, | 266 DevToolsAgentHostClientImpl(base::MessageLoop* message_loop, |
| 258 ServerWrapper* server_wrapper, | 267 ServerWrapper* server_wrapper, |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 637 delegate_->GetFrontendResource(path), | 646 delegate_->GetFrontendResource(path), |
| 638 GetMimeType(path)); | 647 GetMimeType(path)); |
| 639 } | 648 } |
| 640 | 649 |
| 641 void DevToolsHttpHandler::OnWebSocketRequest( | 650 void DevToolsHttpHandler::OnWebSocketRequest( |
| 642 int connection_id, | 651 int connection_id, |
| 643 const net::HttpServerRequestInfo& request) { | 652 const net::HttpServerRequestInfo& request) { |
| 644 if (!thread_) | 653 if (!thread_) |
| 645 return; | 654 return; |
| 646 | 655 |
| 647 std::string browser_prefix = "/devtools/browser"; | 656 std::string browser_prefix = kBrowserUrlPrefix; |
| 657 std::string browser_guid = delegate_->GetBrowserTargetGUID(); | |
| 658 if (!browser_guid.empty()) | |
| 659 browser_prefix = browser_prefix + "/" + browser_guid; | |
|
dgozman
2016/11/18 23:25:56
This breaks tethering which tries to communicate o
| |
| 648 if (base::StartsWith(request.path, browser_prefix, | 660 if (base::StartsWith(request.path, browser_prefix, |
| 649 base::CompareCase::SENSITIVE)) { | 661 base::CompareCase::SENSITIVE)) { |
| 650 scoped_refptr<DevToolsAgentHost> browser_agent = | 662 scoped_refptr<DevToolsAgentHost> browser_agent = |
| 651 DevToolsAgentHost::CreateForBrowser( | 663 DevToolsAgentHost::CreateForBrowser( |
| 652 thread_->task_runner(), | 664 thread_->task_runner(), |
| 653 base::Bind(&DevToolsSocketFactory::CreateForTethering, | 665 base::Bind(&DevToolsSocketFactory::CreateForTethering, |
| 654 base::Unretained(socket_factory_))); | 666 base::Unretained(socket_factory_))); |
| 655 connection_to_client_[connection_id].reset(new DevToolsAgentHostClientImpl( | 667 connection_to_client_[connection_id].reset(new DevToolsAgentHostClientImpl( |
| 656 thread_->message_loop(), server_wrapper_, connection_id, | 668 thread_->message_loop(), server_wrapper_, connection_id, |
| 657 browser_agent)); | 669 browser_agent)); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 712 server_wrapper_(nullptr), | 724 server_wrapper_(nullptr), |
| 713 delegate_(delegate), | 725 delegate_(delegate), |
| 714 socket_factory_(nullptr), | 726 socket_factory_(nullptr), |
| 715 weak_factory_(this) { | 727 weak_factory_(this) { |
| 716 bool bundles_resources = frontend_url_.empty(); | 728 bool bundles_resources = frontend_url_.empty(); |
| 717 if (frontend_url_.empty()) | 729 if (frontend_url_.empty()) |
| 718 frontend_url_ = "/devtools/inspector.html"; | 730 frontend_url_ = "/devtools/inspector.html"; |
| 719 | 731 |
| 720 BrowserThread::PostTask( | 732 BrowserThread::PostTask( |
| 721 BrowserThread::FILE, FROM_HERE, | 733 BrowserThread::FILE, FROM_HERE, |
| 722 base::Bind(&StartServerOnFile, | 734 base::Bind(&StartServerOnFile, weak_factory_.GetWeakPtr(), |
| 723 weak_factory_.GetWeakPtr(), | 735 socket_factory.release(), output_directory, debug_frontend_dir, |
| 724 socket_factory.release(), | 736 delegate->GetBrowserTargetGUID(), bundles_resources)); |
| 725 output_directory, | |
| 726 debug_frontend_dir, | |
| 727 bundles_resources)); | |
| 728 } | 737 } |
| 729 | 738 |
| 730 void DevToolsHttpHandler::ServerStarted( | 739 void DevToolsHttpHandler::ServerStarted( |
| 731 base::Thread* thread, | 740 base::Thread* thread, |
| 732 ServerWrapper* server_wrapper, | 741 ServerWrapper* server_wrapper, |
| 733 DevToolsSocketFactory* socket_factory, | 742 DevToolsSocketFactory* socket_factory, |
| 734 std::unique_ptr<net::IPEndPoint> ip_address) { | 743 std::unique_ptr<net::IPEndPoint> ip_address) { |
| 735 thread_ = thread; | 744 thread_ = thread; |
| 736 server_wrapper_ = server_wrapper; | 745 server_wrapper_ = server_wrapper; |
| 737 socket_factory_ = socket_factory; | 746 socket_factory_ = socket_factory; |
| 738 server_ip_address_.swap(ip_address); | 747 server_ip_address_.swap(ip_address); |
| 739 } | 748 } |
| 740 | 749 |
| 741 void ServerWrapper::WriteActivePortToUserProfile( | 750 void ServerWrapper::WriteActivePortAndGuidToUserProfile( |
| 742 const base::FilePath& output_directory) { | 751 const base::FilePath& output_directory) { |
| 743 DCHECK(!output_directory.empty()); | 752 DCHECK(!output_directory.empty()); |
| 744 net::IPEndPoint endpoint; | 753 net::IPEndPoint endpoint; |
| 745 int err; | 754 int err; |
| 746 if ((err = server_->GetLocalAddress(&endpoint)) != net::OK) { | 755 if ((err = server_->GetLocalAddress(&endpoint)) != net::OK) { |
| 747 LOG(ERROR) << "Error " << err << " getting local address"; | 756 LOG(ERROR) << "Error " << err << " getting local address"; |
| 748 return; | 757 return; |
| 749 } | 758 } |
| 750 | 759 |
| 751 // Write this port to a well-known file in the profile directory | 760 // Write this port to a well-known file in the profile directory. |
| 752 // so Telemetry can pick it up. | |
| 753 base::FilePath path = output_directory.Append(kDevToolsActivePortFileName); | 761 base::FilePath path = output_directory.Append(kDevToolsActivePortFileName); |
| 754 std::string port_string = base::UintToString(endpoint.port()); | 762 std::string port_string = base::UintToString(endpoint.port()); |
| 755 if (base::WriteFile(path, port_string.c_str(), | 763 if (base::WriteFile(path, port_string.c_str(), port_string.length()) < 0) { |
| 756 static_cast<int>(port_string.length())) < 0) { | |
| 757 LOG(ERROR) << "Error writing DevTools active port to file"; | 764 LOG(ERROR) << "Error writing DevTools active port to file"; |
| 758 } | 765 } |
| 766 | |
| 767 if (!browser_guid_.empty()) { | |
| 768 std::string browser_address = | |
| 769 base::StringPrintf("ws://%s%s/%s", endpoint.ToString().c_str(), | |
| 770 kBrowserUrlPrefix, browser_guid_.c_str()); | |
| 771 | |
| 772 // Write browser target guid to a well-known file in the profile directory. | |
| 773 path = output_directory.Append(kDevToolsBrowserTargetFileName); | |
| 774 if (base::WriteFile(path, browser_address.c_str(), | |
| 775 browser_address.length()) < 0) { | |
| 776 LOG(ERROR) << "Error writing DevTools browser target path to file"; | |
| 777 } | |
| 778 } | |
| 759 } | 779 } |
| 760 | 780 |
| 761 void DevToolsHttpHandler::SendJson(int connection_id, | 781 void DevToolsHttpHandler::SendJson(int connection_id, |
| 762 net::HttpStatusCode status_code, | 782 net::HttpStatusCode status_code, |
| 763 base::Value* value, | 783 base::Value* value, |
| 764 const std::string& message) { | 784 const std::string& message) { |
| 765 if (!thread_) | 785 if (!thread_) |
| 766 return; | 786 return; |
| 767 | 787 |
| 768 // Serialize value and message. | 788 // Serialize value and message. |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 854 id.c_str(), | 874 id.c_str(), |
| 855 host); | 875 host); |
| 856 dictionary->SetString( | 876 dictionary->SetString( |
| 857 kTargetDevtoolsFrontendUrlField, devtools_frontend_url); | 877 kTargetDevtoolsFrontendUrlField, devtools_frontend_url); |
| 858 } | 878 } |
| 859 | 879 |
| 860 return dictionary; | 880 return dictionary; |
| 861 } | 881 } |
| 862 | 882 |
| 863 } // namespace content | 883 } // namespace content |
| OLD | NEW |