1// Copyright 2014 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 "chrome/browser/extensions/api/storage/sync_value_store_cache.h"
6
7#include "base/bind.h"
8#include "base/callback.h"
9#include "base/files/file_path.h"
10#include "base/sequenced_task_runner.h"
11#include "chrome/browser/extensions/api/storage/sync_storage_backend.h"
12#include "chrome/browser/sync/glue/sync_start_util.h"
13#include "content/public/browser/browser_thread.h"
14#include "extensions/browser/api/storage/settings_storage_quota_enforcer.h"
15#include "extensions/browser/api/storage/storage_frontend.h"
16#include "extensions/common/api/storage.h"
17#include "extensions/common/constants.h"
18#include "extensions/common/extension.h"
19
20using content::BrowserThread;
21
22namespace extensions {
23
24namespace {
25
26// Returns the quota limit for sync storage, taken from the schema in
27// extensions/common/api/storage.json.
28SettingsStorageQuotaEnforcer::Limits GetSyncQuotaLimits() {
29  SettingsStorageQuotaEnforcer::Limits limits = {
30    static_cast<size_t>(core_api::storage::sync::QUOTA_BYTES),
31    static_cast<size_t>(core_api::storage::sync::QUOTA_BYTES_PER_ITEM),
32    static_cast<size_t>(core_api::storage::sync::MAX_ITEMS)
33  };
34  return limits;
35}
36
37}  // namespace
38
39SyncValueStoreCache::SyncValueStoreCache(
40    const scoped_refptr<SettingsStorageFactory>& factory,
41    const scoped_refptr<SettingsObserverList>& observers,
42    const base::FilePath& profile_path)
43    : initialized_(false) {
44  DCHECK_CURRENTLY_ON(BrowserThread::UI);
45
46  // This post is safe since the destructor can only be invoked from the
47  // same message loop, and any potential post of a deletion task must come
48  // after the constructor returns.
49  BrowserThread::PostTask(
50      BrowserThread::FILE, FROM_HERE,
51      base::Bind(&SyncValueStoreCache::InitOnFileThread,
52                 base::Unretained(this),
53                 factory, observers, profile_path));
54}
55
56SyncValueStoreCache::~SyncValueStoreCache() {
57  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
58}
59
60syncer::SyncableService* SyncValueStoreCache::GetSyncableService(
61    syncer::ModelType type) const {
62  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
63  DCHECK(initialized_);
64
65  switch (type) {
66    case syncer::APP_SETTINGS:
67      return app_backend_.get();
68    case syncer::EXTENSION_SETTINGS:
69      return extension_backend_.get();
70    default:
71      NOTREACHED();
72      return NULL;
73  }
74}
75
76void SyncValueStoreCache::RunWithValueStoreForExtension(
77    const StorageCallback& callback,
78    scoped_refptr<const Extension> extension) {
79  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
80  DCHECK(initialized_);
81  SyncStorageBackend* backend =
82      extension->is_app() ? app_backend_.get() : extension_backend_.get();
83  callback.Run(backend->GetStorage(extension->id()));
84}
85
86void SyncValueStoreCache::DeleteStorageSoon(const std::string& extension_id) {
87  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
88  app_backend_->DeleteStorage(extension_id);
89  extension_backend_->DeleteStorage(extension_id);
90}
91
92void SyncValueStoreCache::InitOnFileThread(
93    const scoped_refptr<SettingsStorageFactory>& factory,
94    const scoped_refptr<SettingsObserverList>& observers,
95    const base::FilePath& profile_path) {
96  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
97  DCHECK(!initialized_);
98  app_backend_.reset(new SyncStorageBackend(
99      factory,
100      profile_path.AppendASCII(kSyncAppSettingsDirectoryName),
101      GetSyncQuotaLimits(),
102      observers,
103      syncer::APP_SETTINGS,
104      sync_start_util::GetFlareForSyncableService(profile_path)));
105  extension_backend_.reset(new SyncStorageBackend(
106      factory,
107      profile_path.AppendASCII(kSyncExtensionSettingsDirectoryName),
108      GetSyncQuotaLimits(),
109      observers,
110      syncer::EXTENSION_SETTINGS,
111      sync_start_util::GetFlareForSyncableService(profile_path)));
112  initialized_ = true;
113}
114
115}  // namespace extensions
116