storage_partition_impl.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
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/storage_partition_impl.h"
6
7#include "base/sequenced_task_runner.h"
8#include "base/strings/utf_string_conversions.h"
9#include "content/browser/browser_main_loop.h"
10#include "content/browser/fileapi/browser_file_system_helper.h"
11#include "content/browser/gpu/shader_disk_cache.h"
12#include "content/common/dom_storage/dom_storage_types.h"
13#include "content/public/browser/browser_context.h"
14#include "content/public/browser/browser_thread.h"
15#include "content/public/browser/dom_storage_context.h"
16#include "content/public/browser/indexed_db_context.h"
17#include "content/public/browser/local_storage_usage_info.h"
18#include "content/public/browser/session_storage_usage_info.h"
19#include "net/base/completion_callback.h"
20#include "net/base/net_errors.h"
21#include "net/cookies/cookie_monster.h"
22#include "net/url_request/url_request_context.h"
23#include "net/url_request/url_request_context_getter.h"
24#include "webkit/browser/database/database_tracker.h"
25#include "webkit/browser/quota/quota_manager.h"
26
27namespace content {
28
29namespace {
30
31int GenerateQuotaClientMask(uint32 remove_mask) {
32  int quota_client_mask = 0;
33
34  if (remove_mask & StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS)
35    quota_client_mask |= quota::QuotaClient::kFileSystem;
36  if (remove_mask & StoragePartition::REMOVE_DATA_MASK_WEBSQL)
37    quota_client_mask |= quota::QuotaClient::kDatabase;
38  if (remove_mask & StoragePartition::REMOVE_DATA_MASK_APPCACHE)
39    quota_client_mask |= quota::QuotaClient::kAppcache;
40  if (remove_mask & StoragePartition::REMOVE_DATA_MASK_INDEXEDDB)
41    quota_client_mask |= quota::QuotaClient::kIndexedDatabase;
42
43  return quota_client_mask;
44}
45
46void OnClearedCookies(const base::Closure& callback, int num_deleted) {
47  // The final callback needs to happen from UI thread.
48  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
49    BrowserThread::PostTask(
50        BrowserThread::UI, FROM_HERE,
51        base::Bind(&OnClearedCookies, callback, num_deleted));
52    return;
53  }
54
55  callback.Run();
56}
57
58void ClearCookiesOnIOThread(
59    const scoped_refptr<net::URLRequestContextGetter>& rq_context,
60    const base::Time begin,
61    const base::Time end,
62    const GURL& remove_origin,
63    const base::Closure& callback) {
64  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
65  net::CookieStore* cookie_store = rq_context->
66      GetURLRequestContext()->cookie_store();
67  if (remove_origin.is_empty()) {
68    cookie_store->GetCookieMonster()->DeleteAllCreatedBetweenAsync(
69        begin,
70        end,
71        base::Bind(&OnClearedCookies, callback));
72  } else {
73    cookie_store->GetCookieMonster()->DeleteAllCreatedBetweenForHostAsync(
74        begin,
75        end,
76        remove_origin, base::Bind(&OnClearedCookies, callback));
77  }
78}
79
80void OnQuotaManagedOriginDeleted(const GURL& origin,
81                                 quota::StorageType type,
82                                 size_t* origins_to_delete_count,
83                                 const base::Closure& callback,
84                                 quota::QuotaStatusCode status) {
85  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
86  DCHECK_GT(*origins_to_delete_count, 0u);
87  if (status != quota::kQuotaStatusOk) {
88    DLOG(ERROR) << "Couldn't remove data of type " << type << " for origin "
89                << origin << ". Status: " << status;
90  }
91
92  (*origins_to_delete_count)--;
93  if (*origins_to_delete_count == 0) {
94    delete origins_to_delete_count;
95    callback.Run();
96  }
97}
98
99void ClearQuotaManagedOriginsOnIOThread(quota::QuotaManager* quota_manager,
100                                        uint32 remove_mask,
101                                        const base::Closure& callback,
102                                        const std::set<GURL>& origins,
103                                        quota::StorageType quota_storage_type) {
104  // The QuotaManager manages all storage other than cookies, LocalStorage,
105  // and SessionStorage. This loop wipes out most HTML5 storage for the given
106  // origins.
107  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
108
109  if (!origins.size()) {
110    // No origins to clear.
111    callback.Run();
112    return;
113  }
114
115  size_t* origins_to_delete_count = new size_t(origins.size());
116  for (std::set<GURL>::const_iterator origin = origins.begin();
117       origin != origins.end(); ++origin) {
118    quota_manager->DeleteOriginData(
119        *origin, quota_storage_type,
120        GenerateQuotaClientMask(remove_mask),
121        base::Bind(&OnQuotaManagedOriginDeleted,
122                   origin->GetOrigin(), quota_storage_type,
123                   origins_to_delete_count, callback));
124  }
125}
126
127void ClearedShaderCache(const base::Closure& callback) {
128  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
129    BrowserThread::PostTask(
130        BrowserThread::UI, FROM_HERE,
131        base::Bind(&ClearedShaderCache, callback));
132    return;
133  }
134  callback.Run();
135}
136
137void ClearShaderCacheOnIOThread(const base::FilePath& path,
138                                const base::Time begin,
139                                const base::Time end,
140                                const base::Closure& callback) {
141  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
142  ShaderCacheFactory::GetInstance()->ClearByPath(
143      path, begin, end, base::Bind(&ClearedShaderCache, callback));
144}
145
146void OnLocalStorageUsageInfo(
147    const scoped_refptr<DOMStorageContextWrapper>& dom_storage_context,
148    const base::Time delete_begin,
149    const base::Time delete_end,
150    const base::Closure& callback,
151    const std::vector<LocalStorageUsageInfo>& infos) {
152  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
153
154  for (size_t i = 0; i < infos.size(); ++i) {
155    if (infos[i].last_modified >= delete_begin &&
156        infos[i].last_modified <= delete_end) {
157      dom_storage_context->DeleteLocalStorage(infos[i].origin);
158    }
159  }
160  callback.Run();
161}
162
163void OnSessionStorageUsageInfo(
164    const scoped_refptr<DOMStorageContextWrapper>& dom_storage_context,
165    const base::Closure& callback,
166    const std::vector<SessionStorageUsageInfo>& infos) {
167  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
168
169  for (size_t i = 0; i < infos.size(); ++i)
170    dom_storage_context->DeleteSessionStorage(infos[i]);
171
172  callback.Run();
173}
174
175void ClearLocalStorageOnUIThread(
176    const scoped_refptr<DOMStorageContextWrapper>& dom_storage_context,
177    const GURL& remove_origin,
178    const base::Time begin,
179    const base::Time end,
180    const base::Closure& callback) {
181  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
182
183  if (!remove_origin.is_empty()) {
184    dom_storage_context->DeleteLocalStorage(remove_origin);
185    callback.Run();
186    return;
187  }
188
189  dom_storage_context->GetLocalStorageUsage(
190      base::Bind(&OnLocalStorageUsageInfo,
191                 dom_storage_context, begin, end, callback));
192}
193
194void ClearSessionStorageOnUIThread(
195    const scoped_refptr<DOMStorageContextWrapper>& dom_storage_context,
196    const base::Closure& callback) {
197  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
198
199  dom_storage_context->GetSessionStorageUsage(
200      base::Bind(&OnSessionStorageUsageInfo, dom_storage_context, callback));
201}
202
203}  // namespace
204
205// Helper for deleting quota managed data from a partition.
206//
207// Most of the operations in this class are done on IO thread.
208struct StoragePartitionImpl::QuotaManagedDataDeletionHelper {
209  QuotaManagedDataDeletionHelper(const base::Closure& callback)
210      : callback(callback), task_count(0) {
211  }
212
213  void IncrementTaskCountOnIO();
214  void DecrementTaskCountOnIO();
215
216  void ClearDataOnIOThread(
217      const scoped_refptr<quota::QuotaManager>& quota_manager,
218      const base::Time begin,
219      uint32 remove_mask,
220      uint32 quota_storage_remove_mask,
221      const GURL& remove_origin);
222
223  // Accessed on IO thread.
224  const base::Closure callback;
225  // Accessed on IO thread.
226  int task_count;
227};
228
229// Helper for deleting all sorts of data from a partition, keeps track of
230// deletion status.
231//
232// StoragePartitionImpl creates an instance of this class to keep track of
233// data deletion progress. Deletion requires deleting multiple bits of data
234// (e.g. cookies, local storage, session storage etc.) and hopping between UI
235// and IO thread. An instance of this class is created in the beginning of
236// deletion process (StoragePartitionImpl::ClearDataImpl) and the instance is
237// forwarded and updated on each (sub) deletion's callback. The instance is
238// finally destroyed when deletion completes (and |callback| is invoked).
239struct StoragePartitionImpl::DataDeletionHelper {
240  DataDeletionHelper(const base::Closure& callback)
241      : callback(callback), task_count(0) {
242  }
243
244  void IncrementTaskCountOnUI();
245  void DecrementTaskCountOnUI();
246
247  void ClearDataOnUIThread(uint32 remove_mask,
248                           uint32 quota_storage_remove_mask,
249                           const GURL& remove_origin,
250                           const base::FilePath& path,
251                           net::URLRequestContextGetter* rq_context,
252                           DOMStorageContextWrapper* dom_storage_context,
253                           quota::QuotaManager* quota_manager,
254                           WebRTCIdentityStore* webrtc_identity_store,
255                           const base::Time begin,
256                           const base::Time end);
257
258  // Accessed on UI thread.
259  const base::Closure callback;
260  // Accessed on UI thread.
261  int task_count;
262};
263
264void ClearQuotaManagedDataOnIOThread(
265    const scoped_refptr<quota::QuotaManager>& quota_manager,
266    const base::Time begin,
267    uint32 remove_mask,
268    uint32 quota_storage_remove_mask,
269    const GURL& remove_origin,
270    const base::Closure& callback) {
271  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
272
273  StoragePartitionImpl::QuotaManagedDataDeletionHelper* helper =
274      new StoragePartitionImpl::QuotaManagedDataDeletionHelper(callback);
275  helper->ClearDataOnIOThread(quota_manager, begin,
276      remove_mask, quota_storage_remove_mask, remove_origin);
277}
278
279StoragePartitionImpl::StoragePartitionImpl(
280    const base::FilePath& partition_path,
281    quota::QuotaManager* quota_manager,
282    ChromeAppCacheService* appcache_service,
283    fileapi::FileSystemContext* filesystem_context,
284    webkit_database::DatabaseTracker* database_tracker,
285    DOMStorageContextWrapper* dom_storage_context,
286    IndexedDBContextImpl* indexed_db_context,
287    ServiceWorkerContext* service_worker_context,
288    WebRTCIdentityStore* webrtc_identity_store)
289    : partition_path_(partition_path),
290      quota_manager_(quota_manager),
291      appcache_service_(appcache_service),
292      filesystem_context_(filesystem_context),
293      database_tracker_(database_tracker),
294      dom_storage_context_(dom_storage_context),
295      indexed_db_context_(indexed_db_context),
296      service_worker_context_(service_worker_context),
297      webrtc_identity_store_(webrtc_identity_store) {}
298
299StoragePartitionImpl::~StoragePartitionImpl() {
300  // These message loop checks are just to avoid leaks in unittests.
301  if (GetDatabaseTracker() &&
302      BrowserThread::IsMessageLoopValid(BrowserThread::FILE)) {
303    BrowserThread::PostTask(
304        BrowserThread::FILE, FROM_HERE,
305        base::Bind(&webkit_database::DatabaseTracker::Shutdown,
306                   GetDatabaseTracker()));
307  }
308
309  if (GetFileSystemContext())
310    GetFileSystemContext()->Shutdown();
311
312  if (GetDOMStorageContext())
313    GetDOMStorageContext()->Shutdown();
314}
315
316// TODO(ajwong): Break the direct dependency on |context|. We only
317// need 3 pieces of info from it.
318StoragePartitionImpl* StoragePartitionImpl::Create(
319    BrowserContext* context,
320    bool in_memory,
321    const base::FilePath& partition_path) {
322  // Ensure that these methods are called on the UI thread, except for
323  // unittests where a UI thread might not have been created.
324  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
325         !BrowserThread::IsMessageLoopValid(BrowserThread::UI));
326
327  // All of the clients have to be created and registered with the
328  // QuotaManager prior to the QuotaManger being used. We do them
329  // all together here prior to handing out a reference to anything
330  // that utilizes the QuotaManager.
331  scoped_refptr<quota::QuotaManager> quota_manager = new quota::QuotaManager(
332      in_memory,
333      partition_path,
334      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get(),
335      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB).get(),
336      context->GetSpecialStoragePolicy());
337
338  // Each consumer is responsible for registering its QuotaClient during
339  // its construction.
340  scoped_refptr<fileapi::FileSystemContext> filesystem_context =
341      CreateFileSystemContext(context,
342                              partition_path, in_memory,
343                              quota_manager->proxy());
344
345  scoped_refptr<webkit_database::DatabaseTracker> database_tracker =
346      new webkit_database::DatabaseTracker(
347          partition_path,
348          in_memory,
349          context->GetSpecialStoragePolicy(),
350          quota_manager->proxy(),
351          BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)
352              .get());
353
354  base::FilePath path = in_memory ? base::FilePath() : partition_path;
355  scoped_refptr<DOMStorageContextWrapper> dom_storage_context =
356      new DOMStorageContextWrapper(path, context->GetSpecialStoragePolicy());
357
358  // BrowserMainLoop may not be initialized in unit tests. Tests will
359  // need to inject their own task runner into the IndexedDBContext.
360  base::SequencedTaskRunner* idb_task_runner =
361      BrowserThread::CurrentlyOn(BrowserThread::UI) &&
362              BrowserMainLoop::GetInstance()
363          ? BrowserMainLoop::GetInstance()->indexed_db_thread()
364                ->message_loop_proxy().get()
365          : NULL;
366  scoped_refptr<IndexedDBContextImpl> indexed_db_context =
367      new IndexedDBContextImpl(path,
368                               context->GetSpecialStoragePolicy(),
369                               quota_manager->proxy(),
370                               idb_task_runner);
371
372  scoped_refptr<ServiceWorkerContext> service_worker_context =
373      new ServiceWorkerContext(path, quota_manager->proxy());
374
375  scoped_refptr<ChromeAppCacheService> appcache_service =
376      new ChromeAppCacheService(quota_manager->proxy());
377
378  scoped_refptr<WebRTCIdentityStore> webrtc_identity_store(
379      new WebRTCIdentityStore(path, context->GetSpecialStoragePolicy()));
380
381  return new StoragePartitionImpl(partition_path,
382                                  quota_manager.get(),
383                                  appcache_service.get(),
384                                  filesystem_context.get(),
385                                  database_tracker.get(),
386                                  dom_storage_context.get(),
387                                  indexed_db_context.get(),
388                                  service_worker_context.get(),
389                                  webrtc_identity_store.get());
390}
391
392base::FilePath StoragePartitionImpl::GetPath() {
393  return partition_path_;
394}
395
396net::URLRequestContextGetter* StoragePartitionImpl::GetURLRequestContext() {
397  return url_request_context_.get();
398}
399
400net::URLRequestContextGetter*
401StoragePartitionImpl::GetMediaURLRequestContext() {
402  return media_url_request_context_.get();
403}
404
405quota::QuotaManager* StoragePartitionImpl::GetQuotaManager() {
406  return quota_manager_.get();
407}
408
409ChromeAppCacheService* StoragePartitionImpl::GetAppCacheService() {
410  return appcache_service_.get();
411}
412
413fileapi::FileSystemContext* StoragePartitionImpl::GetFileSystemContext() {
414  return filesystem_context_.get();
415}
416
417webkit_database::DatabaseTracker* StoragePartitionImpl::GetDatabaseTracker() {
418  return database_tracker_.get();
419}
420
421DOMStorageContextWrapper* StoragePartitionImpl::GetDOMStorageContext() {
422  return dom_storage_context_.get();
423}
424
425IndexedDBContextImpl* StoragePartitionImpl::GetIndexedDBContext() {
426  return indexed_db_context_.get();
427}
428
429ServiceWorkerContext* StoragePartitionImpl::GetServiceWorkerContext() {
430  return service_worker_context_.get();
431}
432
433void StoragePartitionImpl::ClearDataImpl(
434    uint32 remove_mask,
435    uint32 quota_storage_remove_mask,
436    const GURL& remove_origin,
437    net::URLRequestContextGetter* rq_context,
438    const base::Time begin,
439    const base::Time end,
440    const base::Closure& callback) {
441  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
442  DataDeletionHelper* helper = new DataDeletionHelper(callback);
443  // |helper| deletes itself when done in
444  // DataDeletionHelper::DecrementTaskCountOnUI().
445  helper->ClearDataOnUIThread(
446      remove_mask, quota_storage_remove_mask, remove_origin,
447      GetPath(), rq_context, dom_storage_context_, quota_manager_,
448      webrtc_identity_store_, begin, end);
449}
450
451void StoragePartitionImpl::
452    QuotaManagedDataDeletionHelper::IncrementTaskCountOnIO() {
453  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
454  ++task_count;
455}
456
457void StoragePartitionImpl::
458    QuotaManagedDataDeletionHelper::DecrementTaskCountOnIO() {
459  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
460  DCHECK_GT(task_count, 0);
461  --task_count;
462  if (task_count)
463    return;
464
465  callback.Run();
466  delete this;
467}
468
469void StoragePartitionImpl::QuotaManagedDataDeletionHelper::ClearDataOnIOThread(
470    const scoped_refptr<quota::QuotaManager>& quota_manager,
471    const base::Time begin,
472    uint32 remove_mask,
473    uint32 quota_storage_remove_mask,
474    const GURL& remove_origin) {
475  std::set<GURL> origins;
476  if (!remove_origin.is_empty())
477    origins.insert(remove_origin);
478
479  IncrementTaskCountOnIO();
480  base::Closure decrement_callback = base::Bind(
481      &QuotaManagedDataDeletionHelper::DecrementTaskCountOnIO,
482      base::Unretained(this));
483
484  if (quota_storage_remove_mask & QUOTA_MANAGED_STORAGE_MASK_PERSISTENT) {
485    IncrementTaskCountOnIO();
486    if (origins.empty()) {  // Remove for all origins.
487      // Ask the QuotaManager for all origins with temporary quota modified
488      // within the user-specified timeframe, and deal with the resulting set in
489      // ClearQuotaManagedOriginsOnIOThread().
490      quota_manager->GetOriginsModifiedSince(
491          quota::kStorageTypePersistent, begin,
492          base::Bind(&ClearQuotaManagedOriginsOnIOThread,
493                     quota_manager, remove_mask, decrement_callback));
494    } else {
495      ClearQuotaManagedOriginsOnIOThread(
496          quota_manager, remove_mask, decrement_callback,
497          origins, quota::kStorageTypePersistent);
498    }
499  }
500
501  // Do the same for temporary quota.
502  if (quota_storage_remove_mask & QUOTA_MANAGED_STORAGE_MASK_TEMPORARY) {
503    IncrementTaskCountOnIO();
504    if (origins.empty()) {  // Remove for all origins.
505      quota_manager->GetOriginsModifiedSince(
506          quota::kStorageTypeTemporary, begin,
507          base::Bind(&ClearQuotaManagedOriginsOnIOThread,
508                     quota_manager, remove_mask, decrement_callback));
509    } else {
510      ClearQuotaManagedOriginsOnIOThread(
511          quota_manager, remove_mask, decrement_callback,
512          origins, quota::kStorageTypeTemporary);
513    }
514  }
515
516  // Do the same for syncable quota.
517  if (quota_storage_remove_mask & QUOTA_MANAGED_STORAGE_MASK_SYNCABLE) {
518    IncrementTaskCountOnIO();
519    if (origins.empty()) {  // Remove for all origins.
520      quota_manager->GetOriginsModifiedSince(
521          quota::kStorageTypeSyncable, begin,
522          base::Bind(&ClearQuotaManagedOriginsOnIOThread,
523                     quota_manager, remove_mask, decrement_callback));
524    } else {
525      ClearQuotaManagedOriginsOnIOThread(
526          quota_manager, remove_mask, decrement_callback,
527          origins, quota::kStorageTypeSyncable);
528    }
529  }
530
531  DecrementTaskCountOnIO();
532}
533
534void StoragePartitionImpl::DataDeletionHelper::IncrementTaskCountOnUI() {
535  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
536  ++task_count;
537}
538
539void StoragePartitionImpl::DataDeletionHelper::DecrementTaskCountOnUI() {
540  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
541    BrowserThread::PostTask(
542        BrowserThread::UI, FROM_HERE,
543        base::Bind(&DataDeletionHelper::DecrementTaskCountOnUI,
544                   base::Unretained(this)));
545    return;
546  }
547  DCHECK_GT(task_count, 0);
548  --task_count;
549  if (!task_count) {
550    callback.Run();
551    delete this;
552  }
553}
554
555void StoragePartitionImpl::DataDeletionHelper::ClearDataOnUIThread(
556    uint32 remove_mask,
557    uint32 quota_storage_remove_mask,
558    const GURL& remove_origin,
559    const base::FilePath& path,
560    net::URLRequestContextGetter* rq_context,
561    DOMStorageContextWrapper* dom_storage_context,
562    quota::QuotaManager* quota_manager,
563    WebRTCIdentityStore* webrtc_identity_store,
564    const base::Time begin,
565    const base::Time end) {
566  DCHECK_NE(remove_mask, 0u);
567  DCHECK(!callback.is_null());
568
569  IncrementTaskCountOnUI();
570  base::Closure decrement_callback = base::Bind(
571      &DataDeletionHelper::DecrementTaskCountOnUI, base::Unretained(this));
572
573  if (remove_mask & REMOVE_DATA_MASK_COOKIES) {
574    // Handle the cookies.
575    IncrementTaskCountOnUI();
576    BrowserThread::PostTask(
577        BrowserThread::IO, FROM_HERE,
578        base::Bind(&ClearCookiesOnIOThread,
579                   make_scoped_refptr(rq_context), begin, end, remove_origin,
580                   decrement_callback));
581  }
582
583  if (remove_mask & REMOVE_DATA_MASK_INDEXEDDB ||
584      remove_mask & REMOVE_DATA_MASK_WEBSQL ||
585      remove_mask & REMOVE_DATA_MASK_APPCACHE ||
586      remove_mask & REMOVE_DATA_MASK_FILE_SYSTEMS) {
587    IncrementTaskCountOnUI();
588    BrowserThread::PostTask(
589        BrowserThread::IO, FROM_HERE,
590        base::Bind(&ClearQuotaManagedDataOnIOThread,
591                   make_scoped_refptr(quota_manager), begin,
592                   remove_mask, quota_storage_remove_mask, remove_origin,
593                   decrement_callback));
594  }
595
596  if (remove_mask & REMOVE_DATA_MASK_LOCAL_STORAGE) {
597    IncrementTaskCountOnUI();
598    ClearLocalStorageOnUIThread(
599        make_scoped_refptr(dom_storage_context),
600        remove_origin, begin, end, decrement_callback);
601
602    // ClearDataImpl cannot clear session storage data when a particular origin
603    // is specified. Therefore we ignore clearing session storage in this case.
604    // TODO(lazyboy): Fix.
605    if (remove_origin.is_empty()) {
606      IncrementTaskCountOnUI();
607      ClearSessionStorageOnUIThread(
608          make_scoped_refptr(dom_storage_context), decrement_callback);
609    }
610  }
611
612  if (remove_mask & REMOVE_DATA_MASK_SHADER_CACHE) {
613    IncrementTaskCountOnUI();
614    BrowserThread::PostTask(
615        BrowserThread::IO, FROM_HERE,
616        base::Bind(&ClearShaderCacheOnIOThread,
617                   path, begin, end, decrement_callback));
618  }
619
620  if (remove_mask & REMOVE_DATA_MASK_WEBRTC_IDENTITY) {
621    IncrementTaskCountOnUI();
622    BrowserThread::PostTask(
623        BrowserThread::IO,
624        FROM_HERE,
625        base::Bind(&WebRTCIdentityStore::DeleteBetween,
626                   webrtc_identity_store,
627                   begin,
628                   end,
629                   decrement_callback));
630  }
631
632  DecrementTaskCountOnUI();
633}
634
635
636void StoragePartitionImpl::ClearDataForOrigin(
637    uint32 remove_mask,
638    uint32 quota_storage_remove_mask,
639    const GURL& storage_origin,
640    net::URLRequestContextGetter* request_context_getter) {
641  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
642  ClearDataImpl(remove_mask, quota_storage_remove_mask, storage_origin,
643                request_context_getter, base::Time(), base::Time::Max(),
644                base::Bind(&base::DoNothing));
645}
646
647void StoragePartitionImpl::ClearDataForUnboundedRange(
648    uint32 remove_mask,
649    uint32 quota_storage_remove_mask) {
650  ClearDataImpl(remove_mask, quota_storage_remove_mask, GURL(),
651                GetURLRequestContext(), base::Time(), base::Time::Max(),
652                base::Bind(&base::DoNothing));
653}
654
655void StoragePartitionImpl::ClearDataForRange(uint32 remove_mask,
656                                             uint32 quota_storage_remove_mask,
657                                             const base::Time& begin,
658                                             const base::Time& end,
659                                             const base::Closure& callback) {
660  ClearDataImpl(remove_mask, quota_storage_remove_mask, GURL(),
661                GetURLRequestContext(), begin, end, callback);
662}
663
664WebRTCIdentityStore* StoragePartitionImpl::GetWebRTCIdentityStore() {
665  return webrtc_identity_store_.get();
666}
667
668void StoragePartitionImpl::SetURLRequestContext(
669    net::URLRequestContextGetter* url_request_context) {
670  url_request_context_ = url_request_context;
671}
672
673void StoragePartitionImpl::SetMediaURLRequestContext(
674    net::URLRequestContextGetter* media_url_request_context) {
675  media_url_request_context_ = media_url_request_context;
676}
677
678}  // namespace content
679