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
AppCacheDispatcherHost(ChromeAppCacheService * appcache_service,int process_id)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
OnChannelConnected(int32 peer_pid)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
OnMessageReceived(const IPC::Message & message)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
~AppCacheDispatcherHost()63 AppCacheDispatcherHost::~AppCacheDispatcherHost() {}
64
BadMessageReceived()65 void AppCacheDispatcherHost::BadMessageReceived() {
66 RecordAction(base::UserMetricsAction("BadMessageTerminate_ACDH"));
67 BrowserMessageFilter::BadMessageReceived();
68 }
69
OnRegisterHost(int host_id)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
OnUnregisterHost(int host_id)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
OnSetSpawningHostId(int host_id,int spawning_host_id)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
OnSelectCache(int host_id,const GURL & document_url,int64 cache_document_was_loaded_from,const GURL & opt_manifest_url)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
OnSelectCacheForWorker(int host_id,int parent_process_id,int parent_host_id)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
OnSelectCacheForSharedWorker(int host_id,int64 appcache_id)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
OnMarkAsForeignEntry(int host_id,const GURL & document_url,int64 cache_document_was_loaded_from)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
OnGetResourceList(int host_id,std::vector<appcache::AppCacheResourceInfo> * params)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
OnGetStatus(int host_id,IPC::Message * reply_msg)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
OnStartUpdate(int host_id,IPC::Message * reply_msg)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
OnSwapCache(int host_id,IPC::Message * reply_msg)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
GetStatusCallback(appcache::AppCacheStatus status,void * param)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
StartUpdateCallback(bool result,void * param)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
SwapCacheCallback(bool result,void * param)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