Home | History | Annotate | Download | only in appcache
      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