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