1// Copyright (c) 2011 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_backend_impl.h"
6
7#include "base/stl_util.h"
8#include "content/browser/appcache/appcache.h"
9#include "content/browser/appcache/appcache_group.h"
10#include "content/browser/appcache/appcache_service_impl.h"
11
12namespace content {
13
14AppCacheBackendImpl::AppCacheBackendImpl()
15    : service_(NULL),
16      frontend_(NULL),
17      process_id_(0) {
18}
19
20AppCacheBackendImpl::~AppCacheBackendImpl() {
21  STLDeleteValues(&hosts_);
22  if (service_)
23    service_->UnregisterBackend(this);
24}
25
26void AppCacheBackendImpl::Initialize(AppCacheServiceImpl* service,
27                                     AppCacheFrontend* frontend,
28                                     int process_id) {
29  DCHECK(!service_ && !frontend_ && frontend && service);
30  service_ = service;
31  frontend_ = frontend;
32  process_id_ = process_id;
33  service_->RegisterBackend(this);
34}
35
36bool AppCacheBackendImpl::RegisterHost(int id) {
37  if (GetHost(id))
38    return false;
39
40  hosts_.insert(
41      HostMap::value_type(id, new AppCacheHost(id, frontend_, service_)));
42  return true;
43}
44
45bool AppCacheBackendImpl::UnregisterHost(int id) {
46  HostMap::iterator found = hosts_.find(id);
47  if (found == hosts_.end())
48    return false;
49
50  delete found->second;
51  hosts_.erase(found);
52  return true;
53}
54
55bool AppCacheBackendImpl::SetSpawningHostId(
56    int host_id,
57    int spawning_host_id) {
58  AppCacheHost* host = GetHost(host_id);
59  if (!host)
60    return false;
61  host->SetSpawningHostId(process_id_, spawning_host_id);
62  return true;
63}
64
65bool AppCacheBackendImpl::SelectCache(
66    int host_id,
67    const GURL& document_url,
68    const int64 cache_document_was_loaded_from,
69    const GURL& manifest_url) {
70  AppCacheHost* host = GetHost(host_id);
71  if (!host)
72    return false;
73
74  host->SelectCache(document_url, cache_document_was_loaded_from,
75                    manifest_url);
76  return true;
77}
78
79bool AppCacheBackendImpl::SelectCacheForWorker(
80    int host_id, int parent_process_id, int parent_host_id) {
81  AppCacheHost* host = GetHost(host_id);
82  if (!host)
83    return false;
84
85  host->SelectCacheForWorker(parent_process_id, parent_host_id);
86  return true;
87}
88
89bool AppCacheBackendImpl::SelectCacheForSharedWorker(
90    int host_id, int64 appcache_id) {
91  AppCacheHost* host = GetHost(host_id);
92  if (!host)
93    return false;
94
95  host->SelectCacheForSharedWorker(appcache_id);
96  return true;
97}
98
99bool AppCacheBackendImpl::MarkAsForeignEntry(
100    int host_id,
101    const GURL& document_url,
102    int64 cache_document_was_loaded_from) {
103  AppCacheHost* host = GetHost(host_id);
104  if (!host)
105    return false;
106
107  host->MarkAsForeignEntry(document_url, cache_document_was_loaded_from);
108  return true;
109}
110
111bool AppCacheBackendImpl::GetStatusWithCallback(
112    int host_id, const GetStatusCallback& callback, void* callback_param) {
113  AppCacheHost* host = GetHost(host_id);
114  if (!host)
115    return false;
116
117  host->GetStatusWithCallback(callback, callback_param);
118  return true;
119}
120
121bool AppCacheBackendImpl::StartUpdateWithCallback(
122    int host_id, const StartUpdateCallback& callback, void* callback_param) {
123  AppCacheHost* host = GetHost(host_id);
124  if (!host)
125    return false;
126
127  host->StartUpdateWithCallback(callback, callback_param);
128  return true;
129}
130
131bool AppCacheBackendImpl::SwapCacheWithCallback(
132    int host_id, const SwapCacheCallback& callback, void* callback_param) {
133  AppCacheHost* host = GetHost(host_id);
134  if (!host)
135    return false;
136
137  host->SwapCacheWithCallback(callback, callback_param);
138  return true;
139}
140
141void AppCacheBackendImpl::GetResourceList(
142    int host_id, std::vector<AppCacheResourceInfo>* resource_infos) {
143  AppCacheHost* host = GetHost(host_id);
144  if (!host)
145    return;
146
147  host->GetResourceList(resource_infos);
148}
149
150scoped_ptr<AppCacheHost> AppCacheBackendImpl::TransferHostOut(int host_id) {
151  HostMap::iterator found = hosts_.find(host_id);
152  if (found == hosts_.end()) {
153    NOTREACHED();
154    return scoped_ptr<AppCacheHost>();
155  }
156
157  AppCacheHost* transferree = found->second;
158
159  // Put a new empty host in its place.
160  found->second = new AppCacheHost(host_id, frontend_, service_);
161
162  // We give up ownership.
163  transferree->PrepareForTransfer();
164  return scoped_ptr<AppCacheHost>(transferree);
165}
166
167void AppCacheBackendImpl::TransferHostIn(
168    int new_host_id, scoped_ptr<AppCacheHost> host) {
169  HostMap::iterator found = hosts_.find(new_host_id);
170  if (found == hosts_.end()) {
171    NOTREACHED();
172    return;
173  }
174
175  delete found->second;
176
177  // We take onwership.
178  host->CompleteTransfer(new_host_id, frontend_);
179  found->second = host.release();
180}
181
182}  // namespace content
183