Chromium Code Reviews| Index: chrome/browser/devtools/devtools_ui_bindings.cc |
| diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc |
| index 8ecab6e921c5ba4fae985a046276644eb4e783a1..56f102d98ba83d96d07c7a650ea57459f83543e5 100644 |
| --- a/chrome/browser/devtools/devtools_ui_bindings.cc |
| +++ b/chrome/browser/devtools/devtools_ui_bindings.cc |
| @@ -79,10 +79,14 @@ static const int kDevToolsPanelShownBoundary = 20; |
| // the constant at shell_devtools_frontend.cc. |
| const size_t kMaxMessageChunkSize = IPC::Channel::kMaximumMessageSize / 4; |
| -typedef std::vector<DevToolsUIBindings*> DevToolsUIBindingsList; |
| +using DevToolsUIBindingsList = std::vector<DevToolsUIBindings*>; |
| base::LazyInstance<DevToolsUIBindingsList>::Leaky g_instances = |
| LAZY_INSTANCE_INITIALIZER; |
| +using StreamOwners = std::map<int, DevToolsUIBindings*>; |
| +base::LazyInstance<StreamOwners>::Leaky g_stream_owners = |
| + LAZY_INSTANCE_INITIALIZER; |
| + |
| std::string SkColorToRGBAString(SkColor color) { |
| // We avoid StringPrintf because it will use locale specific formatters for |
| // the double (e.g. ',' instead of '.' in German). |
| @@ -242,7 +246,7 @@ InfoBarService* DefaultBindingsDelegate::GetInfoBarService() { |
| class ResponseWriter : public net::URLFetcherResponseWriter { |
| public: |
| - ResponseWriter(DevToolsUIBindings* bindings, int stream_id); |
| + explicit ResponseWriter(int stream_id); |
| ~ResponseWriter() override; |
| // URLFetcherResponseWriter overrides: |
| @@ -253,16 +257,13 @@ class ResponseWriter : public net::URLFetcherResponseWriter { |
| int Finish(const net::CompletionCallback& callback) override; |
| private: |
| - DevToolsUIBindings* bindings_; |
| int stream_id_; |
| DISALLOW_COPY_AND_ASSIGN(ResponseWriter); |
| }; |
| -ResponseWriter::ResponseWriter(DevToolsUIBindings* bindings, |
| - int stream_id) |
| - : bindings_(bindings), |
| - stream_id_(stream_id) { |
| +ResponseWriter::ResponseWriter(int stream_id) |
| + : stream_id_(stream_id) { |
| } |
| ResponseWriter::~ResponseWriter() { |
| @@ -272,20 +273,39 @@ int ResponseWriter::Initialize(const net::CompletionCallback& callback) { |
| return net::OK; |
| } |
| +static void WriteResponseOnUI(int stream_id, const std::string& chunk) { |
| + auto it = g_stream_owners.Get().find(stream_id); |
| + if (it != g_stream_owners.Get().end()) { |
| + base::FundamentalValue id(stream_id); |
| + base::StringValue value(chunk); |
| + it->second->CallClientFunction( |
| + "DevToolsAPI.streamWrite", &id, &value, nullptr); |
| + } |
| +} |
| + |
| int ResponseWriter::Write(net::IOBuffer* buffer, |
| int num_bytes, |
| const net::CompletionCallback& callback) { |
| - base::FundamentalValue id(stream_id_); |
| - base::StringValue chunk(std::string(buffer->data(), num_bytes)); |
| - bindings_->CallClientFunction( |
| - "DevToolsAPI.streamWrite", &id, &chunk, nullptr); |
| + content::BrowserThread::PostTask( |
| + content::BrowserThread::UI, FROM_HERE, |
| + base::Bind(&WriteResponseOnUI, stream_id_, |
| + std::string(buffer->data(), num_bytes))); |
| return num_bytes; |
| } |
| +static void FinishResponseOnUI(int stream_id) { |
| + auto it = g_stream_owners.Get().find(stream_id); |
| + if (it != g_stream_owners.Get().end()) { |
| + base::FundamentalValue id(stream_id); |
| + it->second->CallClientFunction( |
| + "DevToolsAPI.streamFinish", &id, nullptr, nullptr); |
| + } |
| +} |
| + |
| int ResponseWriter::Finish(const net::CompletionCallback& callback) { |
| - base::FundamentalValue id(stream_id_); |
| - bindings_->CallClientFunction( |
| - "DevToolsAPI.streamFinish", &id, nullptr, nullptr); |
| + content::BrowserThread::PostTask( |
| + content::BrowserThread::UI, FROM_HERE, |
| + base::Bind(&FinishResponseOnUI, stream_id_)); |
| return net::OK; |
| } |
| @@ -442,6 +462,14 @@ DevToolsUIBindings::~DevToolsUIBindings() { |
| for (const auto& pair : pending_requests_) |
| delete pair.first; |
| + for (auto it = g_stream_owners.Get().begin(); |
| + it != g_stream_owners.Get().end(); ) { |
| + if (it->second == this) |
| + g_stream_owners.Get().erase(it); |
| + else |
| + ++it; |
| + } |
| + |
| if (agent_host_.get()) |
| agent_host_->DetachClient(); |
| @@ -581,13 +609,15 @@ void DevToolsUIBindings::LoadNetworkResource(int request_id, |
| return; |
| } |
| + g_stream_owners.Get()[stream_id] = this; |
|
dgozman
2015/02/28 16:06:13
This will make streams from different DevTools cla
|
| + |
| net::URLFetcher* fetcher = |
| net::URLFetcher::Create(gurl, net::URLFetcher::GET, this); |
| - pending_requests_[fetcher] = request_id; |
| + pending_requests_[fetcher] = std::make_pair(request_id, stream_id); |
| fetcher->SetRequestContext(profile_->GetRequestContext()); |
| fetcher->SetExtraRequestHeaders(headers); |
| fetcher->SaveResponseWithWriter(scoped_ptr<net::URLFetcherResponseWriter>( |
| - new ResponseWriter(this, stream_id))); |
| + new ResponseWriter(stream_id))); |
| fetcher->Start(); |
| } |
| @@ -803,7 +833,10 @@ void DevToolsUIBindings::OnURLFetchComplete(const net::URLFetcher* source) { |
| while (rh && rh->EnumerateHeaderLines(&iterator, &name, &value)) |
| headers->SetString(name, value); |
| - SendMessageAck(it->second, &response); |
| + int request_id = it->second.first; |
| + int stream_id = it->second.second; |
| + SendMessageAck(request_id, &response); |
| + g_stream_owners.Get().erase(stream_id); |
| pending_requests_.erase(it); |
| delete source; |
| } |