| OLD | NEW |
| (Empty) |
| 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 "chrome/browser/extensions/api/storage/settings_frontend.h" | |
| 6 | |
| 7 #include <limits> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/bind_helpers.h" | |
| 11 #include "base/file_path.h" | |
| 12 #include "base/json/json_reader.h" | |
| 13 #include "chrome/browser/extensions/api/storage/leveldb_settings_storage_factory
.h" | |
| 14 #include "chrome/browser/extensions/api/storage/settings_backend.h" | |
| 15 #include "chrome/browser/extensions/api/storage/sync_or_local_value_store_cache.
h" | |
| 16 #include "chrome/browser/extensions/event_names.h" | |
| 17 #include "chrome/browser/extensions/event_router.h" | |
| 18 #include "chrome/browser/extensions/extension_service.h" | |
| 19 #include "chrome/browser/extensions/extension_system.h" | |
| 20 #include "chrome/browser/profiles/profile.h" | |
| 21 #include "chrome/common/extensions/api/storage.h" | |
| 22 #include "content/public/browser/browser_thread.h" | |
| 23 | |
| 24 #if defined(ENABLE_CONFIGURATION_POLICY) | |
| 25 #include "chrome/browser/extensions/api/storage/managed_value_store_cache.h" | |
| 26 #endif | |
| 27 | |
| 28 using content::BrowserThread; | |
| 29 | |
| 30 namespace extensions { | |
| 31 | |
| 32 namespace { | |
| 33 | |
| 34 // Settings change Observer which forwards changes on to the extension | |
| 35 // processes for |profile| and its incognito partner if it exists. | |
| 36 class DefaultObserver : public SettingsObserver { | |
| 37 public: | |
| 38 explicit DefaultObserver(Profile* profile) : profile_(profile) {} | |
| 39 | |
| 40 // SettingsObserver implementation. | |
| 41 virtual void OnSettingsChanged( | |
| 42 const std::string& extension_id, | |
| 43 settings_namespace::Namespace settings_namespace, | |
| 44 const std::string& change_json) OVERRIDE { | |
| 45 // TODO(gdk): This is a temporary hack while the refactoring for | |
| 46 // string-based event payloads is removed. http://crbug.com/136045 | |
| 47 scoped_ptr<ListValue> args(new ListValue()); | |
| 48 args->Append(base::JSONReader::Read(change_json)); | |
| 49 args->Append(Value::CreateStringValue(settings_namespace::ToString( | |
| 50 settings_namespace))); | |
| 51 scoped_ptr<Event> event(new Event( | |
| 52 event_names::kOnSettingsChanged, args.Pass())); | |
| 53 ExtensionSystem::Get(profile_)->event_router()-> | |
| 54 DispatchEventToExtension(extension_id, event.Pass()); | |
| 55 } | |
| 56 | |
| 57 private: | |
| 58 Profile* const profile_; | |
| 59 }; | |
| 60 | |
| 61 SettingsStorageQuotaEnforcer::Limits GetLocalLimits() { | |
| 62 SettingsStorageQuotaEnforcer::Limits limits = { | |
| 63 static_cast<size_t>(api::storage::local::QUOTA_BYTES), | |
| 64 std::numeric_limits<size_t>::max(), | |
| 65 std::numeric_limits<size_t>::max() | |
| 66 }; | |
| 67 return limits; | |
| 68 } | |
| 69 | |
| 70 SettingsStorageQuotaEnforcer::Limits GetSyncLimits() { | |
| 71 SettingsStorageQuotaEnforcer::Limits limits = { | |
| 72 static_cast<size_t>(api::storage::sync::QUOTA_BYTES), | |
| 73 static_cast<size_t>(api::storage::sync::QUOTA_BYTES_PER_ITEM), | |
| 74 static_cast<size_t>(api::storage::sync::MAX_ITEMS) | |
| 75 }; | |
| 76 return limits; | |
| 77 } | |
| 78 | |
| 79 } // namespace | |
| 80 | |
| 81 // static | |
| 82 SettingsFrontend* SettingsFrontend::Create(Profile* profile) { | |
| 83 return new SettingsFrontend(new LeveldbSettingsStorageFactory(), profile); | |
| 84 } | |
| 85 | |
| 86 // static | |
| 87 SettingsFrontend* SettingsFrontend::Create( | |
| 88 const scoped_refptr<SettingsStorageFactory>& storage_factory, | |
| 89 Profile* profile) { | |
| 90 return new SettingsFrontend(storage_factory, profile); | |
| 91 } | |
| 92 | |
| 93 SettingsFrontend::SettingsFrontend( | |
| 94 const scoped_refptr<SettingsStorageFactory>& factory, Profile* profile) | |
| 95 : local_quota_limit_(GetLocalLimits()), | |
| 96 sync_quota_limit_(GetSyncLimits()), | |
| 97 profile_(profile), | |
| 98 observers_(new SettingsObserverList()), | |
| 99 profile_observer_(new DefaultObserver(profile)) { | |
| 100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 101 DCHECK(!profile->IsOffTheRecord()); | |
| 102 | |
| 103 observers_->AddObserver(profile_observer_.get()); | |
| 104 | |
| 105 const FilePath& profile_path = profile->GetPath(); | |
| 106 caches_[settings_namespace::LOCAL] = | |
| 107 new SyncOrLocalValueStoreCache( | |
| 108 settings_namespace::LOCAL, | |
| 109 factory, | |
| 110 local_quota_limit_, | |
| 111 observers_, | |
| 112 profile_path); | |
| 113 caches_[settings_namespace::SYNC] = | |
| 114 new SyncOrLocalValueStoreCache( | |
| 115 settings_namespace::SYNC, | |
| 116 factory, | |
| 117 sync_quota_limit_, | |
| 118 observers_, | |
| 119 profile_path); | |
| 120 | |
| 121 #if defined(ENABLE_CONFIGURATION_POLICY) | |
| 122 caches_[settings_namespace::MANAGED] = | |
| 123 new ManagedValueStoreCache( | |
| 124 profile->GetPolicyService(), | |
| 125 ExtensionSystem::Get(profile)->event_router(), | |
| 126 factory, | |
| 127 observers_, | |
| 128 profile_path); | |
| 129 #endif | |
| 130 } | |
| 131 | |
| 132 SettingsFrontend::~SettingsFrontend() { | |
| 133 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 134 observers_->RemoveObserver(profile_observer_.get()); | |
| 135 for (CacheMap::iterator it = caches_.begin(); it != caches_.end(); ++it) { | |
| 136 ValueStoreCache* cache = it->second; | |
| 137 cache->ShutdownOnUI(); | |
| 138 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, cache); | |
| 139 } | |
| 140 } | |
| 141 | |
| 142 syncer::SyncableService* SettingsFrontend::GetBackendForSync( | |
| 143 syncer::ModelType type) const { | |
| 144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
| 145 CacheMap::const_iterator it = caches_.find(settings_namespace::SYNC); | |
| 146 DCHECK(it != caches_.end()); | |
| 147 const SyncOrLocalValueStoreCache* sync_cache = | |
| 148 static_cast<const SyncOrLocalValueStoreCache*>(it->second); | |
| 149 switch (type) { | |
| 150 case syncer::APP_SETTINGS: | |
| 151 return sync_cache->GetAppBackend(); | |
| 152 case syncer::EXTENSION_SETTINGS: | |
| 153 return sync_cache->GetExtensionBackend(); | |
| 154 default: | |
| 155 NOTREACHED(); | |
| 156 return NULL; | |
| 157 } | |
| 158 } | |
| 159 | |
| 160 bool SettingsFrontend::IsStorageEnabled( | |
| 161 settings_namespace::Namespace settings_namespace) const { | |
| 162 return caches_.find(settings_namespace) != caches_.end(); | |
| 163 } | |
| 164 | |
| 165 void SettingsFrontend::RunWithStorage( | |
| 166 const std::string& extension_id, | |
| 167 settings_namespace::Namespace settings_namespace, | |
| 168 const ValueStoreCache::StorageCallback& callback) { | |
| 169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 170 | |
| 171 ValueStoreCache* cache = caches_[settings_namespace]; | |
| 172 CHECK(cache); | |
| 173 | |
| 174 // The |extension| has already been referenced earlier in the stack, so it | |
| 175 // can't be gone here. | |
| 176 // TODO(kalman): change RunWithStorage() to take a | |
| 177 // scoped_refptr<const Extension> instead. | |
| 178 scoped_refptr<const Extension> extension = | |
| 179 extensions::ExtensionSystem::Get(profile_)->extension_service()-> | |
| 180 GetExtensionById(extension_id, true); | |
| 181 CHECK(extension); | |
| 182 | |
| 183 BrowserThread::PostTask( | |
| 184 BrowserThread::FILE, FROM_HERE, | |
| 185 base::Bind(&ValueStoreCache::RunWithValueStoreForExtension, | |
| 186 base::Unretained(cache), callback, extension)); | |
| 187 } | |
| 188 | |
| 189 void SettingsFrontend::DeleteStorageSoon( | |
| 190 const std::string& extension_id) { | |
| 191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 192 for (CacheMap::iterator it = caches_.begin(); it != caches_.end(); ++it) { | |
| 193 ValueStoreCache* cache = it->second; | |
| 194 BrowserThread::PostTask( | |
| 195 BrowserThread::FILE, FROM_HERE, | |
| 196 base::Bind(&ValueStoreCache::DeleteStorageSoon, | |
| 197 base::Unretained(cache), | |
| 198 extension_id)); | |
| 199 } | |
| 200 } | |
| 201 | |
| 202 scoped_refptr<SettingsObserverList> SettingsFrontend::GetObservers() { | |
| 203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 204 return observers_; | |
| 205 } | |
| 206 | |
| 207 void SettingsFrontend::DisableStorageForTesting( | |
| 208 settings_namespace::Namespace settings_namespace) { | |
| 209 CacheMap::iterator it = caches_.find(settings_namespace); | |
| 210 if (it != caches_.end()) { | |
| 211 ValueStoreCache* cache = it->second; | |
| 212 cache->ShutdownOnUI(); | |
| 213 BrowserThread::DeleteSoon(BrowserThread::FILE, FROM_HERE, cache); | |
| 214 caches_.erase(it); | |
| 215 } | |
| 216 } | |
| 217 | |
| 218 } // namespace extensions | |
| OLD | NEW |