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