Index: chrome_frame/chrome_frame_automation.cc |
=================================================================== |
--- chrome_frame/chrome_frame_automation.cc (revision 37418) |
+++ chrome_frame/chrome_frame_automation.cc (working copy) |
@@ -408,6 +408,7 @@ |
handle_top_level_requests_(false), |
tab_handle_(-1), |
external_tab_cookie_(NULL), |
+ url_fetcher_(NULL), |
navigate_after_initialization_(false) { |
} |
@@ -493,8 +494,10 @@ |
tab_ = NULL; // scoped_refptr::Release |
} |
- // Clean up any outstanding requests |
- CleanupRequests(); |
+ if (url_fetcher_) { |
+ // Clean up any outstanding requests |
+ url_fetcher_->StopAllRequests(); |
+ } |
// Wait for the background thread to exit. |
ReleaseAutomationServer(); |
@@ -850,10 +853,54 @@ |
// kind of beings. |
// By default we marshal the IPC message to the main/GUI thread and from there |
// we safely invoke chrome_frame_delegate_->OnMessageReceived(msg). |
+ |
+ |
+bool ChromeFrameAutomationClient::ProcessUrlRequestMessage(TabProxy* tab, |
+ const IPC::Message& msg, bool ui_thread) { |
+ // Either directly call appropriate url_fetcher function |
+ // or postpone call to the UI thread. |
+ bool invoke = ui_thread || thread_safe_url_fetcher_; |
+ uint16 msg_type = msg.type(); |
+ switch (msg_type) { |
+ default: |
+ return false; |
+ |
+ case AutomationMsg_RequestStart::ID: |
+ if (invoke) |
+ AutomationMsg_RequestStart::Dispatch(&msg, url_fetcher_, |
+ &PluginUrlRequestManager::StartUrlRequest); |
+ break; |
+ |
+ case AutomationMsg_RequestRead::ID: |
+ if (invoke) |
+ AutomationMsg_RequestRead::Dispatch(&msg, url_fetcher_, |
+ &PluginUrlRequestManager::ReadUrlRequest); |
+ break; |
+ |
+ case AutomationMsg_RequestEnd::ID: |
+ if (invoke) |
+ AutomationMsg_RequestEnd::Dispatch(&msg, url_fetcher_, |
+ &PluginUrlRequestManager::EndUrlRequest); |
+ break; |
+ } |
+ |
+ if (!invoke) { |
+ PostTask(FROM_HERE, NewRunnableMethod(this, |
+ &ChromeFrameAutomationClient::ProcessUrlRequestMessage, |
+ tab, msg, true)); |
+ } |
+ |
+ return true; |
+} |
+ |
void ChromeFrameAutomationClient::OnMessageReceived(TabProxy* tab, |
const IPC::Message& msg) { |
DCHECK(tab == tab_.get()); |
+ // Quickly process network related messages. |
+ if (url_fetcher_ && ProcessUrlRequestMessage(tab, msg, false)) |
+ return; |
+ |
// Early check to avoid needless marshaling |
if (chrome_frame_delegate_ == NULL) |
return; |
@@ -998,119 +1045,9 @@ |
tab_->PrintAsync(); |
} |
-// IPC:Message::Sender implementation |
-bool ChromeFrameAutomationClient::Send(IPC::Message* msg) { |
- if (automation_server_) { |
- return automation_server_->Send(msg); |
- } |
- return false; |
-} |
- |
-bool ChromeFrameAutomationClient::AddRequest(PluginUrlRequest* request) { |
- DCHECK_EQ(PlatformThread::CurrentId(), ui_thread_id_); |
- |
- if (!request) { |
- NOTREACHED(); |
- return false; |
- } |
- |
-#ifndef NDEBUG |
- RequestMap::const_iterator it = request_map_.find(request->id()); |
- scoped_refptr<PluginUrlRequest> other(request_map_.end() == it ? |
- NULL : (*it).second); |
- DCHECK(other.get() == NULL); |
-#endif |
- request_map_[request->id()] = request; |
- return true; |
-} |
- |
-bool ChromeFrameAutomationClient::ReadRequest( |
- int request_id, int bytes_to_read) { |
- bool result = false; |
- PluginUrlRequest* request = LookupRequest(request_id); |
- if (request) |
- result = request->Read(bytes_to_read); |
- |
- return result; |
-} |
- |
-void ChromeFrameAutomationClient::RemoveRequest(PluginUrlRequest* request) { |
- DCHECK_EQ(PlatformThread::CurrentId(), ui_thread_id_); |
- |
- // We check if the request pointer passed in is actually present in the map |
- // before going ahead and deleting it. This avoids the issue where we would |
- // incorrectly delete a different request with the same request id. |
- if (IsValidRequest(request)) { |
- request_map_.erase(request->id()); |
- } |
-} |
- |
-void ChromeFrameAutomationClient::RemoveRequest(int request_id, bool abort) { |
- DCHECK_EQ(PlatformThread::CurrentId(), ui_thread_id_); |
- PluginUrlRequest* request = LookupRequest(request_id); |
- if (request) { |
- if (abort) { |
- // The request object will get removed asynchronously. |
- request->Stop(); |
- } else { |
- request_map_.erase(request_id); |
- } |
- } |
-} |
- |
-PluginUrlRequest* ChromeFrameAutomationClient::LookupRequest( |
- int request_id) const { |
- DCHECK_EQ(PlatformThread::CurrentId(), ui_thread_id_); |
- PluginUrlRequest* request = NULL; |
- RequestMap::const_iterator it = request_map_.find(request_id); |
- if (request_map_.end() != it) |
- request = (*it).second; |
- return request; |
-} |
- |
-bool ChromeFrameAutomationClient::IsValidRequest( |
- PluginUrlRequest* request) const { |
- DCHECK_EQ(PlatformThread::CurrentId(), ui_thread_id_); |
- bool is_valid = false; |
- // if request is invalid then request->id() won't work |
- // hence perform reverse map lookup for validity of the |
- // request pointer. |
- if (request) { |
- for (RequestMap::const_iterator it = request_map_.begin(); |
- it != request_map_.end(); it++) { |
- if (request == (*it).second) { |
- is_valid = true; |
- break; |
- } |
- } |
- } |
- |
- return is_valid; |
-} |
- |
-void ChromeFrameAutomationClient::CleanupRequests() { |
- DCHECK_EQ(PlatformThread::CurrentId(), ui_thread_id_); |
- |
- std::vector<scoped_refptr<PluginUrlRequest> > request_list; |
- // We copy the pending requests into a temporary vector as the Stop |
- // function in the request could also try to delete the request from |
- // the request map and the iterator could end up being invalid. |
- RequestMap::iterator index = request_map_.begin(); |
- while (index != request_map_.end()) { |
- PluginUrlRequest* request = (*index).second; |
- DCHECK(request != NULL); |
- request_list.push_back(request); |
- index++; |
- } |
- request_map_.clear(); |
- |
- for (unsigned int index = 0; index < request_list.size(); ++index) { |
- request_list[index]->Stop(); |
- } |
-} |
- |
bool ChromeFrameAutomationClient::Reinitialize( |
- ChromeFrameDelegate* delegate) { |
+ ChromeFrameDelegate* delegate, |
+ PluginUrlRequestManager* url_fetcher) { |
if (!tab_.get() || !::IsWindow(chrome_window_)) { |
NOTREACHED(); |
DLOG(WARNING) << "ChromeFrameAutomationClient instance reused " |
@@ -1123,8 +1060,9 @@ |
return false; |
} |
- CleanupRequests(); |
+ url_fetcher_->StopAllRequests(); |
chrome_frame_delegate_ = delegate; |
+ SetUrlFetcher(url_fetcher); |
SetParentWindow(NULL); |
return true; |
} |
@@ -1146,6 +1084,43 @@ |
return; |
} |
- Send(new AutomationMsg_SetPageFontSize(0, tab_handle_, font_size)); |
+ automation_server_->Send( |
+ new AutomationMsg_SetPageFontSize(0, tab_handle_, font_size)); |
} |
+ |
+////////////////////////////////////////////////////////////////////////// |
+// PluginUrlRequestDelegate implementation. |
+// Forward network related responses to Chrome. |
+ |
+void ChromeFrameAutomationClient::OnResponseStarted(int request_id, |
+ const char* mime_type, const char* headers, int size, |
+ base::Time last_modified, const std::string& peristent_cookies, |
+ const std::string& redirect_url, int redirect_status) { |
+ const IPC::AutomationURLResponse response = { |
+ mime_type, |
+ headers ? headers : "", |
+ size, |
+ last_modified, |
+ peristent_cookies, |
+ redirect_url, |
+ redirect_status |
+ }; |
+ |
+ automation_server_->Send(new AutomationMsg_RequestStarted(0, |
+ tab_->handle(), request_id, response)); |
+} |
+ |
+void ChromeFrameAutomationClient::OnReadComplete(int request_id, |
+ const void* buffer, int len) { |
+ std::string data(reinterpret_cast<const char*>(buffer), len); |
+ automation_server_->Send(new AutomationMsg_RequestData(0, tab_->handle(), |
+ request_id, data)); |
+} |
+ |
+void ChromeFrameAutomationClient::OnResponseEnd(int request_id, |
+ const URLRequestStatus& status) { |
+ automation_server_->Send(new AutomationMsg_RequestEnd(0, tab_->handle(), |
+ request_id, status)); |
+} |
+ |