appcache_dispatcher_host.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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
13namespace content {
14
15AppCacheDispatcherHost::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
23void AppCacheDispatcherHost::OnChannelConnected(int32 peer_pid) {
24  BrowserMessageFilter::OnChannelConnected(peer_pid);
25  if (appcache_service_) {
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
40bool 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
64AppCacheDispatcherHost::~AppCacheDispatcherHost() {}
65
66void AppCacheDispatcherHost::BadMessageReceived() {
67  RecordAction(UserMetricsAction("BadMessageTerminate_ACDH"));
68  BrowserMessageFilter::BadMessageReceived();
69}
70
71void AppCacheDispatcherHost::OnRegisterHost(int host_id) {
72  if (appcache_service_) {
73    if (!backend_impl_.RegisterHost(host_id)) {
74      BadMessageReceived();
75    }
76  }
77}
78
79void AppCacheDispatcherHost::OnUnregisterHost(int host_id) {
80  if (appcache_service_) {
81    if (!backend_impl_.UnregisterHost(host_id)) {
82      BadMessageReceived();
83    }
84  }
85}
86
87void AppCacheDispatcherHost::OnSetSpawningHostId(
88    int host_id, int spawning_host_id) {
89  if (appcache_service_) {
90    if (!backend_impl_.SetSpawningHostId(host_id, spawning_host_id))
91      BadMessageReceived();
92  }
93}
94
95void 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_) {
100    if (!backend_impl_.SelectCache(host_id, 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
110void AppCacheDispatcherHost::OnSelectCacheForWorker(
111    int host_id, int parent_process_id, int parent_host_id) {
112  if (appcache_service_) {
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
122void AppCacheDispatcherHost::OnSelectCacheForSharedWorker(
123    int host_id, int64 appcache_id) {
124  if (appcache_service_) {
125    if (!backend_impl_.SelectCacheForSharedWorker(host_id, appcache_id))
126      BadMessageReceived();
127  } else {
128    frontend_proxy_.OnCacheSelected(host_id, appcache::AppCacheInfo());
129  }
130}
131
132void AppCacheDispatcherHost::OnMarkAsForeignEntry(
133    int host_id, const GURL& document_url,
134    int64 cache_document_was_loaded_from) {
135  if (appcache_service_) {
136    if (!backend_impl_.MarkAsForeignEntry(host_id, document_url,
137                                          cache_document_was_loaded_from)) {
138      BadMessageReceived();
139    }
140  }
141}
142
143void AppCacheDispatcherHost::OnGetResourceList(
144    int host_id, std::vector<appcache::AppCacheResourceInfo>* params) {
145  if (appcache_service_)
146    backend_impl_.GetResourceList(host_id, params);
147}
148
149void 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_) {
158    if (!backend_impl_.GetStatusWithCallback(host_id, get_status_callback_,
159                                             reply_msg)) {
160      BadMessageReceived();
161    }
162    return;
163  }
164
165  GetStatusCallback(appcache::UNCACHED, reply_msg);
166}
167
168void 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_) {
178    if (!backend_impl_.StartUpdateWithCallback(host_id, start_update_callback_,
179                                               reply_msg)) {
180      BadMessageReceived();
181    }
182    return;
183  }
184
185  StartUpdateCallback(false, reply_msg);
186}
187
188void 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_) {
197    if (!backend_impl_.SwapCacheWithCallback(host_id, swap_cache_callback_,
198                                             reply_msg)) {
199      BadMessageReceived();
200    }
201    return;
202  }
203
204  SwapCacheCallback(false, reply_msg);
205}
206
207void AppCacheDispatcherHost::GetStatusCallback(
208    appcache::Status 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
215void 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
222void 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