Index: content/browser/appcache/appcache_dispatcher_host.cc |
diff --git a/content/browser/appcache/appcache_dispatcher_host.cc b/content/browser/appcache/appcache_dispatcher_host.cc |
index 2eb90dd5189e5630c4b3baadc6cb9d40995e4791..2d523b54fa0b9fd29c17f87abe24b54d055bafd2 100644 |
--- a/content/browser/appcache/appcache_dispatcher_host.cc |
+++ b/content/browser/appcache/appcache_dispatcher_host.cc |
@@ -4,12 +4,22 @@ |
#include "content/browser/appcache/appcache_dispatcher_host.h" |
+#include <map> |
#include "base/bind.h" |
#include "base/bind_helpers.h" |
#include "content/browser/appcache/chrome_appcache_service.h" |
#include "content/browser/bad_message.h" |
#include "content/common/appcache_messages.h" |
+#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/user_metrics.h" |
+#include "content/public/common/browser_side_navigation_policy.h" |
+ |
+namespace { |
+ |
+typedef std::map<int, content::AppCacheDispatcherHost*> ProcessIdToHostMap; |
+base::LazyInstance<ProcessIdToHostMap> g_process_id_host_map; |
+ |
+} // namespace |
namespace content { |
@@ -21,22 +31,22 @@ AppCacheDispatcherHost::AppCacheDispatcherHost( |
frontend_proxy_(this), |
process_id_(process_id), |
weak_factory_(this) { |
+ g_process_id_host_map.Get()[process_id] = this; |
} |
void AppCacheDispatcherHost::OnChannelConnected(int32_t peer_pid) { |
- if (appcache_service_.get()) { |
- backend_impl_.Initialize( |
- appcache_service_.get(), &frontend_proxy_, process_id_); |
- get_status_callback_ = |
- base::Bind(&AppCacheDispatcherHost::GetStatusCallback, |
- weak_factory_.GetWeakPtr()); |
- start_update_callback_ = |
- base::Bind(&AppCacheDispatcherHost::StartUpdateCallback, |
- weak_factory_.GetWeakPtr()); |
- swap_cache_callback_ = |
- base::Bind(&AppCacheDispatcherHost::SwapCacheCallback, |
- weak_factory_.GetWeakPtr()); |
- } |
+ if (!appcache_service_.get() || backend_impl_.get()) |
+ return; |
+ |
+ backend_impl_.reset(new AppCacheBackendImpl); |
+ backend_impl_->Initialize(appcache_service_.get(), &frontend_proxy_, |
+ process_id_, -1); |
+ get_status_callback_ = base::Bind(&AppCacheDispatcherHost::GetStatusCallback, |
+ weak_factory_.GetWeakPtr()); |
+ start_update_callback_ = base::Bind( |
+ &AppCacheDispatcherHost::StartUpdateCallback, weak_factory_.GetWeakPtr()); |
+ swap_cache_callback_ = base::Bind(&AppCacheDispatcherHost::SwapCacheCallback, |
+ weak_factory_.GetWeakPtr()); |
} |
bool AppCacheDispatcherHost::OnMessageReceived(const IPC::Message& message) { |
@@ -62,11 +72,66 @@ bool AppCacheDispatcherHost::OnMessageReceived(const IPC::Message& message) { |
return handled; |
} |
-AppCacheDispatcherHost::~AppCacheDispatcherHost() {} |
+void AppCacheDispatcherHost::RegisterPendingHost(int host_id) { |
+ DCHECK(IsBrowserSideNavigationEnabled()); |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ DCHECK(host_id != kAppCacheNoHostId); |
+ DCHECK(pending_hosts_.find(host_id) == pending_hosts_.end()); |
+ pending_hosts_.insert(host_id); |
+} |
+ |
+AppCacheDispatcherHost::~AppCacheDispatcherHost() { |
+ ProcessIdToHostMap::iterator index = |
+ g_process_id_host_map.Get().find(process_id_); |
+ if ((index != g_process_id_host_map.Get().end()) && index->second == this) |
+ g_process_id_host_map.Get().erase(index); |
+} |
+ |
+void AppCacheDispatcherHost::FrameNavigationCommitted( |
+ std::unique_ptr<AppCacheBackendImpl> backend) { |
+ DCHECK(backend.get()); |
+ DCHECK(IsBrowserSideNavigationEnabled()); |
+ |
+ // Before switching the backends we do the following: |
+ // 1. Mark hosts registered with the |backend| as pending so we can avoid |
+ // registering them again in the AppCacheHostMsg_RegisterHost IPC. |
+ // 2. Unregister the backend we currently have in this class. |
+ // 3. Copy registered hosts to the new backend. |
+ // 4. Update the AppCacheFrontEnd and the AppCacheServiceImpl pointers in the |
+ // new backend as they may have changed. |
+ // 5. Register the new backend with the service. |
+ AppCacheBackendImpl::HostMap::const_iterator host_index; |
+ for (host_index = backend->hosts().begin(); |
+ host_index != backend->hosts().end(); ++host_index) { |
+ RegisterPendingHost(host_index->first); |
+ } |
+ |
+ if (backend_impl_.get()) { |
+ appcache_service_->UnregisterBackend(backend_impl_.get()); |
+ backend->CopyExistingHosts(backend_impl_.get()); |
+ } |
+ |
+ backend_impl_ = std::move(backend); |
+ |
+ backend_impl_->FrameNavigationCommitted(&frontend_proxy_, |
+ appcache_service_.get()); |
michaeln
2016/11/22 00:17:27
it doesn't make sense to me that the service objec
ananta
2016/11/23 04:05:14
Reverted.
|
+ |
+ appcache_service_->RegisterBackend(backend_impl_.get()); |
+} |
void AppCacheDispatcherHost::OnRegisterHost(int host_id) { |
if (appcache_service_.get()) { |
- if (!backend_impl_.RegisterHost(host_id)) { |
+ // PlzNavigate. If the |host_id| is the pending_backends_ list, it means |
+ // it was registered via the RegisterPendingHost() function. We remove the |
+ // host from the pending list and return without registering the host. |
+ if (IsBrowserSideNavigationEnabled()) { |
+ std::set<int>::iterator pending_host_index = pending_hosts_.find(host_id); |
michaeln
2016/11/22 00:17:27
readability nit: auto found = x.find(id)
ananta
2016/11/23 04:05:14
Done.
|
+ if (pending_host_index != pending_hosts_.end()) { |
+ pending_hosts_.erase(pending_host_index); |
+ return; |
+ } |
+ } |
+ if (!backend_impl_->RegisterHost(host_id)) { |
bad_message::ReceivedBadMessage(this, bad_message::ACDH_REGISTER); |
} |
} |
@@ -74,7 +139,7 @@ void AppCacheDispatcherHost::OnRegisterHost(int host_id) { |
void AppCacheDispatcherHost::OnUnregisterHost(int host_id) { |
if (appcache_service_.get()) { |
- if (!backend_impl_.UnregisterHost(host_id)) { |
+ if (!backend_impl_->UnregisterHost(host_id)) { |
bad_message::ReceivedBadMessage(this, bad_message::ACDH_UNREGISTER); |
} |
} |
@@ -83,7 +148,7 @@ void AppCacheDispatcherHost::OnUnregisterHost(int host_id) { |
void AppCacheDispatcherHost::OnSetSpawningHostId( |
int host_id, int spawning_host_id) { |
if (appcache_service_.get()) { |
- if (!backend_impl_.SetSpawningHostId(host_id, spawning_host_id)) |
+ if (!backend_impl_->SetSpawningHostId(host_id, spawning_host_id)) |
bad_message::ReceivedBadMessage(this, bad_message::ACDH_SET_SPAWNING); |
} |
} |
@@ -94,10 +159,9 @@ void AppCacheDispatcherHost::OnSelectCache( |
int64_t cache_document_was_loaded_from, |
const GURL& opt_manifest_url) { |
if (appcache_service_.get()) { |
- if (!backend_impl_.SelectCache(host_id, |
- document_url, |
- cache_document_was_loaded_from, |
- opt_manifest_url)) { |
+ if (!backend_impl_->SelectCache(host_id, document_url, |
+ cache_document_was_loaded_from, |
+ opt_manifest_url)) { |
bad_message::ReceivedBadMessage(this, bad_message::ACDH_SELECT_CACHE); |
} |
} else { |
@@ -108,8 +172,8 @@ void AppCacheDispatcherHost::OnSelectCache( |
void AppCacheDispatcherHost::OnSelectCacheForWorker( |
int host_id, int parent_process_id, int parent_host_id) { |
if (appcache_service_.get()) { |
- if (!backend_impl_.SelectCacheForWorker( |
- host_id, parent_process_id, parent_host_id)) { |
+ if (!backend_impl_->SelectCacheForWorker(host_id, parent_process_id, |
+ parent_host_id)) { |
bad_message::ReceivedBadMessage( |
this, bad_message::ACDH_SELECT_CACHE_FOR_WORKER); |
} |
@@ -121,7 +185,7 @@ void AppCacheDispatcherHost::OnSelectCacheForWorker( |
void AppCacheDispatcherHost::OnSelectCacheForSharedWorker(int host_id, |
int64_t appcache_id) { |
if (appcache_service_.get()) { |
- if (!backend_impl_.SelectCacheForSharedWorker(host_id, appcache_id)) |
+ if (!backend_impl_->SelectCacheForSharedWorker(host_id, appcache_id)) |
bad_message::ReceivedBadMessage( |
this, bad_message::ACDH_SELECT_CACHE_FOR_SHARED_WORKER); |
} else { |
@@ -134,8 +198,8 @@ void AppCacheDispatcherHost::OnMarkAsForeignEntry( |
const GURL& document_url, |
int64_t cache_document_was_loaded_from) { |
if (appcache_service_.get()) { |
- if (!backend_impl_.MarkAsForeignEntry( |
- host_id, document_url, cache_document_was_loaded_from)) { |
+ if (!backend_impl_->MarkAsForeignEntry(host_id, document_url, |
+ cache_document_was_loaded_from)) { |
bad_message::ReceivedBadMessage(this, |
bad_message::ACDH_MARK_AS_FOREIGN_ENTRY); |
} |
@@ -145,7 +209,7 @@ void AppCacheDispatcherHost::OnMarkAsForeignEntry( |
void AppCacheDispatcherHost::OnGetResourceList( |
int host_id, std::vector<AppCacheResourceInfo>* params) { |
if (appcache_service_.get()) |
- backend_impl_.GetResourceList(host_id, params); |
+ backend_impl_->GetResourceList(host_id, params); |
} |
void AppCacheDispatcherHost::OnGetStatus(int host_id, IPC::Message* reply_msg) { |
@@ -158,8 +222,8 @@ void AppCacheDispatcherHost::OnGetStatus(int host_id, IPC::Message* reply_msg) { |
pending_reply_msg_.reset(reply_msg); |
if (appcache_service_.get()) { |
- if (!backend_impl_.GetStatusWithCallback( |
- host_id, get_status_callback_, reply_msg)) { |
+ if (!backend_impl_->GetStatusWithCallback(host_id, get_status_callback_, |
+ reply_msg)) { |
bad_message::ReceivedBadMessage(this, bad_message::ACDH_GET_STATUS); |
} |
return; |
@@ -179,8 +243,8 @@ void AppCacheDispatcherHost::OnStartUpdate(int host_id, |
pending_reply_msg_.reset(reply_msg); |
if (appcache_service_.get()) { |
- if (!backend_impl_.StartUpdateWithCallback( |
- host_id, start_update_callback_, reply_msg)) { |
+ if (!backend_impl_->StartUpdateWithCallback(host_id, start_update_callback_, |
+ reply_msg)) { |
bad_message::ReceivedBadMessage(this, bad_message::ACDH_START_UPDATE); |
} |
return; |
@@ -199,8 +263,8 @@ void AppCacheDispatcherHost::OnSwapCache(int host_id, IPC::Message* reply_msg) { |
pending_reply_msg_.reset(reply_msg); |
if (appcache_service_.get()) { |
- if (!backend_impl_.SwapCacheWithCallback( |
- host_id, swap_cache_callback_, reply_msg)) { |
+ if (!backend_impl_->SwapCacheWithCallback(host_id, swap_cache_callback_, |
+ reply_msg)) { |
bad_message::ReceivedBadMessage(this, bad_message::ACDH_SWAP_CACHE); |
} |
return; |
@@ -231,4 +295,14 @@ void AppCacheDispatcherHost::SwapCacheCallback(bool result, void* param) { |
Send(pending_reply_msg_.release()); |
} |
+// static |
+scoped_refptr<AppCacheDispatcherHost> AppCacheDispatcherHost::GetHostForProcess( |
+ int process_id) { |
+ ProcessIdToHostMap::iterator index = |
+ g_process_id_host_map.Get().find(process_id); |
+ if (index == g_process_id_host_map.Get().end()) |
+ return scoped_refptr<AppCacheDispatcherHost>(); |
+ return index->second; |
+} |
+ |
} // namespace content |