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     : 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, 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, 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, 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<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_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     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