866df10e37278cf6e97047d30013eb2167fc0e2b
[platform/framework/web/crosswalk.git] / src / net / disk_cache / cache_creator.cc
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 "base/files/file_path.h"
6 #include "base/metrics/field_trial.h"
7 #include "base/strings/stringprintf.h"
8 #include "net/base/cache_type.h"
9 #include "net/base/net_errors.h"
10 #include "net/disk_cache/blockfile/backend_impl.h"
11 #include "net/disk_cache/cache_util.h"
12 #include "net/disk_cache/disk_cache.h"
13 #include "net/disk_cache/memory/mem_backend_impl.h"
14 #include "net/disk_cache/simple/simple_backend_impl.h"
15
16 #ifdef USE_TRACING_CACHE_BACKEND
17 #include "net/disk_cache/tracing_cache_backend.h"
18 #endif
19
20 namespace {
21
22 // Builds an instance of the backend depending on platform, type, experiments
23 // etc. Takes care of the retry state. This object will self-destroy when
24 // finished.
25 class CacheCreator {
26  public:
27   CacheCreator(const base::FilePath& path, bool force, int max_bytes,
28                net::CacheType type, net::BackendType backend_type, uint32 flags,
29                base::MessageLoopProxy* thread, net::NetLog* net_log,
30                scoped_ptr<disk_cache::Backend>* backend,
31                const net::CompletionCallback& callback);
32
33   // Creates the backend.
34   int Run();
35
36  private:
37   ~CacheCreator();
38
39   void DoCallback(int result);
40
41   void OnIOComplete(int result);
42
43   const base::FilePath path_;
44   bool force_;
45   bool retry_;
46   int max_bytes_;
47   net::CacheType type_;
48   net::BackendType backend_type_;
49   uint32 flags_;
50   scoped_refptr<base::MessageLoopProxy> thread_;
51   scoped_ptr<disk_cache::Backend>* backend_;
52   net::CompletionCallback callback_;
53   scoped_ptr<disk_cache::Backend> created_cache_;
54   net::NetLog* net_log_;
55
56   DISALLOW_COPY_AND_ASSIGN(CacheCreator);
57 };
58
59 CacheCreator::CacheCreator(
60     const base::FilePath& path, bool force, int max_bytes,
61     net::CacheType type, net::BackendType backend_type, uint32 flags,
62     base::MessageLoopProxy* thread, net::NetLog* net_log,
63     scoped_ptr<disk_cache::Backend>* backend,
64     const net::CompletionCallback& callback)
65     : path_(path),
66       force_(force),
67       retry_(false),
68       max_bytes_(max_bytes),
69       type_(type),
70       backend_type_(backend_type),
71       flags_(flags),
72       thread_(thread),
73       backend_(backend),
74       callback_(callback),
75       net_log_(net_log) {
76 }
77
78 CacheCreator::~CacheCreator() {
79 }
80
81 int CacheCreator::Run() {
82 #if defined(OS_ANDROID)
83   static const bool kSimpleBackendIsDefault = true;
84 #else
85   static const bool kSimpleBackendIsDefault = false;
86 #endif
87   if (backend_type_ == net::CACHE_BACKEND_SIMPLE ||
88       (backend_type_ == net::CACHE_BACKEND_DEFAULT &&
89        kSimpleBackendIsDefault)) {
90     disk_cache::SimpleBackendImpl* simple_cache =
91         new disk_cache::SimpleBackendImpl(path_, max_bytes_, type_,
92                                           thread_.get(), net_log_);
93     created_cache_.reset(simple_cache);
94     return simple_cache->Init(
95         base::Bind(&CacheCreator::OnIOComplete, base::Unretained(this)));
96   }
97
98   // Avoid references to blockfile functions on Android to reduce binary size.
99 #if defined(OS_ANDROID)
100   return net::ERR_FAILED;
101 #else
102   disk_cache::BackendImpl* new_cache =
103       new disk_cache::BackendImpl(path_, thread_.get(), net_log_);
104   created_cache_.reset(new_cache);
105   new_cache->SetMaxSize(max_bytes_);
106   new_cache->SetType(type_);
107   new_cache->SetFlags(flags_);
108   int rv = new_cache->Init(
109       base::Bind(&CacheCreator::OnIOComplete, base::Unretained(this)));
110   DCHECK_EQ(net::ERR_IO_PENDING, rv);
111   return rv;
112 #endif
113 }
114
115 void CacheCreator::DoCallback(int result) {
116   DCHECK_NE(net::ERR_IO_PENDING, result);
117   if (result == net::OK) {
118 #ifndef USE_TRACING_CACHE_BACKEND
119     *backend_ = created_cache_.Pass();
120 #else
121     *backend_.reset(
122         new disk_cache::TracingCacheBackend(created_cache_.Pass()));
123 #endif
124   } else {
125     LOG(ERROR) << "Unable to create cache";
126     created_cache_.reset();
127   }
128   callback_.Run(result);
129   delete this;
130 }
131
132 // If the initialization of the cache fails, and |force| is true, we will
133 // discard the whole cache and create a new one.
134 void CacheCreator::OnIOComplete(int result) {
135   if (result == net::OK || !force_ || retry_)
136     return DoCallback(result);
137
138   // This is a failure and we are supposed to try again, so delete the object,
139   // delete all the files, and try again.
140   retry_ = true;
141   created_cache_.reset();
142   if (!disk_cache::DelayedCacheCleanup(path_))
143     return DoCallback(result);
144
145   // The worker thread will start deleting files soon, but the original folder
146   // is not there anymore... let's create a new set of files.
147   int rv = Run();
148   DCHECK_EQ(net::ERR_IO_PENDING, rv);
149 }
150
151 }  // namespace
152
153 namespace disk_cache {
154
155 int CreateCacheBackend(net::CacheType type,
156                        net::BackendType backend_type,
157                        const base::FilePath& path,
158                        int max_bytes,
159                        bool force, base::MessageLoopProxy* thread,
160                        net::NetLog* net_log, scoped_ptr<Backend>* backend,
161                        const net::CompletionCallback& callback) {
162   DCHECK(!callback.is_null());
163   if (type == net::MEMORY_CACHE) {
164     *backend = disk_cache::MemBackendImpl::CreateBackend(max_bytes, net_log);
165     return *backend ? net::OK : net::ERR_FAILED;
166   }
167   DCHECK(thread);
168   CacheCreator* creator = new CacheCreator(path, force, max_bytes, type,
169                                            backend_type, kNone,
170                                            thread, net_log, backend, callback);
171   return creator->Run();
172 }
173
174 }  // namespace disk_cache