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