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 3 // found in the LICENSE file. 4 5 #include "content/browser/appcache/appcache_dispatcher_host.h" 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "content/browser/appcache/chrome_appcache_service.h" 10 #include "content/common/appcache_messages.h" 11 #include "content/public/browser/user_metrics.h" 12 13 namespace content { 14 15 AppCacheDispatcherHost::AppCacheDispatcherHost( 16 ChromeAppCacheService* appcache_service, 17 int process_id) 18 : BrowserMessageFilter(AppCacheMsgStart), 19 appcache_service_(appcache_service), 20 frontend_proxy_(this), 21 process_id_(process_id) { 22 } 23 24 void AppCacheDispatcherHost::OnChannelConnected(int32 peer_pid) { 25 if (appcache_service_.get()) { 26 backend_impl_.Initialize( 27 appcache_service_.get(), &frontend_proxy_, process_id_); 28 get_status_callback_ = 29 base::Bind(&AppCacheDispatcherHost::GetStatusCallback, 30 base::Unretained(this)); 31 start_update_callback_ = 32 base::Bind(&AppCacheDispatcherHost::StartUpdateCallback, 33 base::Unretained(this)); 34 swap_cache_callback_ = 35 base::Bind(&AppCacheDispatcherHost::SwapCacheCallback, 36 base::Unretained(this)); 37 } 38 } 39 40 bool AppCacheDispatcherHost::OnMessageReceived(const IPC::Message& message) { 41 bool handled = true; 42 IPC_BEGIN_MESSAGE_MAP(AppCacheDispatcherHost, message) 43 IPC_MESSAGE_HANDLER(AppCacheHostMsg_RegisterHost, OnRegisterHost) 44 IPC_MESSAGE_HANDLER(AppCacheHostMsg_UnregisterHost, OnUnregisterHost) 45 IPC_MESSAGE_HANDLER(AppCacheHostMsg_SetSpawningHostId, OnSetSpawningHostId) 46 IPC_MESSAGE_HANDLER(AppCacheHostMsg_GetResourceList, OnGetResourceList) 47 IPC_MESSAGE_HANDLER(AppCacheHostMsg_SelectCache, OnSelectCache) 48 IPC_MESSAGE_HANDLER(AppCacheHostMsg_SelectCacheForWorker, 49 OnSelectCacheForWorker) 50 IPC_MESSAGE_HANDLER(AppCacheHostMsg_SelectCacheForSharedWorker, 51 OnSelectCacheForSharedWorker) 52 IPC_MESSAGE_HANDLER(AppCacheHostMsg_MarkAsForeignEntry, 53 OnMarkAsForeignEntry) 54 IPC_MESSAGE_HANDLER_DELAY_REPLY(AppCacheHostMsg_GetStatus, OnGetStatus) 55 IPC_MESSAGE_HANDLER_DELAY_REPLY(AppCacheHostMsg_StartUpdate, OnStartUpdate) 56 IPC_MESSAGE_HANDLER_DELAY_REPLY(AppCacheHostMsg_SwapCache, OnSwapCache) 57 IPC_MESSAGE_UNHANDLED(handled = false) 58 IPC_END_MESSAGE_MAP() 59 60 return handled; 61 } 62 63 AppCacheDispatcherHost::~AppCacheDispatcherHost() {} 64 65 void AppCacheDispatcherHost::BadMessageReceived() { 66 RecordAction(base::UserMetricsAction("BadMessageTerminate_ACDH")); 67 BrowserMessageFilter::BadMessageReceived(); 68 } 69 70 void AppCacheDispatcherHost::OnRegisterHost(int host_id) { 71 if (appcache_service_.get()) { 72 if (!backend_impl_.RegisterHost(host_id)) { 73 BadMessageReceived(); 74 } 75 } 76 } 77 78 void AppCacheDispatcherHost::OnUnregisterHost(int host_id) { 79 if (appcache_service_.get()) { 80 if (!backend_impl_.UnregisterHost(host_id)) { 81 BadMessageReceived(); 82 } 83 } 84 } 85 86 void AppCacheDispatcherHost::OnSetSpawningHostId( 87 int host_id, int spawning_host_id) { 88 if (appcache_service_.get()) { 89 if (!backend_impl_.SetSpawningHostId(host_id, spawning_host_id)) 90 BadMessageReceived(); 91 } 92 } 93 94 void AppCacheDispatcherHost::OnSelectCache( 95 int host_id, const GURL& document_url, 96 int64 cache_document_was_loaded_from, 97 const GURL& opt_manifest_url) { 98 if (appcache_service_.get()) { 99 if (!backend_impl_.SelectCache(host_id, 100 document_url, 101 cache_document_was_loaded_from, 102 opt_manifest_url)) { 103 BadMessageReceived(); 104 } 105 } else { 106 frontend_proxy_.OnCacheSelected(host_id, appcache::AppCacheInfo()); 107 } 108 } 109 110 void AppCacheDispatcherHost::OnSelectCacheForWorker( 111 int host_id, int parent_process_id, int parent_host_id) { 112 if (appcache_service_.get()) { 113 if (!backend_impl_.SelectCacheForWorker( 114 host_id, parent_process_id, parent_host_id)) { 115 BadMessageReceived(); 116 } 117 } else { 118 frontend_proxy_.OnCacheSelected(host_id, appcache::AppCacheInfo()); 119 } 120 } 121 122 void AppCacheDispatcherHost::OnSelectCacheForSharedWorker( 123 int host_id, int64 appcache_id) { 124 if (appcache_service_.get()) { 125 if (!backend_impl_.SelectCacheForSharedWorker(host_id, appcache_id)) 126 BadMessageReceived(); 127 } else { 128 frontend_proxy_.OnCacheSelected(host_id, appcache::AppCacheInfo()); 129 } 130 } 131 132 void AppCacheDispatcherHost::OnMarkAsForeignEntry( 133 int host_id, const GURL& document_url, 134 int64 cache_document_was_loaded_from) { 135 if (appcache_service_.get()) { 136 if (!backend_impl_.MarkAsForeignEntry( 137 host_id, document_url, cache_document_was_loaded_from)) { 138 BadMessageReceived(); 139 } 140 } 141 } 142 143 void AppCacheDispatcherHost::OnGetResourceList( 144 int host_id, std::vector<appcache::AppCacheResourceInfo>* params) { 145 if (appcache_service_.get()) 146 backend_impl_.GetResourceList(host_id, params); 147 } 148 149 void AppCacheDispatcherHost::OnGetStatus(int host_id, IPC::Message* reply_msg) { 150 if (pending_reply_msg_) { 151 BadMessageReceived(); 152 delete reply_msg; 153 return; 154 } 155 156 pending_reply_msg_.reset(reply_msg); 157 if (appcache_service_.get()) { 158 if (!backend_impl_.GetStatusWithCallback( 159 host_id, get_status_callback_, reply_msg)) { 160 BadMessageReceived(); 161 } 162 return; 163 } 164 165 GetStatusCallback(appcache::APPCACHE_STATUS_UNCACHED, reply_msg); 166 } 167 168 void AppCacheDispatcherHost::OnStartUpdate(int host_id, 169 IPC::Message* reply_msg) { 170 if (pending_reply_msg_) { 171 BadMessageReceived(); 172 delete reply_msg; 173 return; 174 } 175 176 pending_reply_msg_.reset(reply_msg); 177 if (appcache_service_.get()) { 178 if (!backend_impl_.StartUpdateWithCallback( 179 host_id, start_update_callback_, reply_msg)) { 180 BadMessageReceived(); 181 } 182 return; 183 } 184 185 StartUpdateCallback(false, reply_msg); 186 } 187 188 void AppCacheDispatcherHost::OnSwapCache(int host_id, IPC::Message* reply_msg) { 189 if (pending_reply_msg_) { 190 BadMessageReceived(); 191 delete reply_msg; 192 return; 193 } 194 195 pending_reply_msg_.reset(reply_msg); 196 if (appcache_service_.get()) { 197 if (!backend_impl_.SwapCacheWithCallback( 198 host_id, swap_cache_callback_, reply_msg)) { 199 BadMessageReceived(); 200 } 201 return; 202 } 203 204 SwapCacheCallback(false, reply_msg); 205 } 206 207 void AppCacheDispatcherHost::GetStatusCallback( 208 appcache::AppCacheStatus status, void* param) { 209 IPC::Message* reply_msg = reinterpret_cast<IPC::Message*>(param); 210 DCHECK_EQ(pending_reply_msg_.get(), reply_msg); 211 AppCacheHostMsg_GetStatus::WriteReplyParams(reply_msg, status); 212 Send(pending_reply_msg_.release()); 213 } 214 215 void AppCacheDispatcherHost::StartUpdateCallback(bool result, void* param) { 216 IPC::Message* reply_msg = reinterpret_cast<IPC::Message*>(param); 217 DCHECK_EQ(pending_reply_msg_.get(), reply_msg); 218 AppCacheHostMsg_StartUpdate::WriteReplyParams(reply_msg, result); 219 Send(pending_reply_msg_.release()); 220 } 221 222 void AppCacheDispatcherHost::SwapCacheCallback(bool result, void* param) { 223 IPC::Message* reply_msg = reinterpret_cast<IPC::Message*>(param); 224 DCHECK_EQ(pending_reply_msg_.get(), reply_msg); 225 AppCacheHostMsg_SwapCache::WriteReplyParams(reply_msg, result); 226 Send(pending_reply_msg_.release()); 227 } 228 229 } // namespace content 230