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/test_extension_prefs.h" 6 7 #include "base/bind.h" 8 #include "base/bind_helpers.h" 9 #include "base/file_util.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop_proxy.h" 13 #include "base/prefs/json_pref_store.h" 14 #include "base/prefs/pref_value_store.h" 15 #include "base/run_loop.h" 16 #include "base/sequenced_task_runner.h" 17 #include "base/synchronization/waitable_event.h" 18 #include "base/values.h" 19 #include "chrome/browser/extensions/extension_pref_store.h" 20 #include "chrome/browser/extensions/extension_pref_value_map.h" 21 #include "chrome/browser/extensions/extension_prefs.h" 22 #include "chrome/browser/prefs/pref_service_mock_factory.h" 23 #include "chrome/browser/prefs/pref_service_syncable.h" 24 #include "components/user_prefs/pref_registry_syncable.h" 25 #include "content/public/browser/browser_thread.h" 26 #include "extensions/browser/extensions_browser_client.h" 27 #include "extensions/common/extension.h" 28 #include "extensions/common/manifest_constants.h" 29 #include "sync/api/string_ordinal.h" 30 #include "testing/gtest/include/gtest/gtest.h" 31 32 using content::BrowserThread; 33 34 namespace extensions { 35 36 namespace { 37 38 // A TimeProvider which returns an incrementally later time each time 39 // GetCurrentTime is called. 40 class IncrementalTimeProvider : public ExtensionPrefs::TimeProvider { 41 public: 42 IncrementalTimeProvider() : current_time_(base::Time::Now()) { 43 } 44 45 virtual ~IncrementalTimeProvider() { 46 } 47 48 virtual base::Time GetCurrentTime() const OVERRIDE { 49 current_time_ += base::TimeDelta::FromSeconds(10); 50 return current_time_; 51 } 52 53 private: 54 DISALLOW_COPY_AND_ASSIGN(IncrementalTimeProvider); 55 56 mutable base::Time current_time_; 57 }; 58 59 } // namespace 60 61 TestExtensionPrefs::TestExtensionPrefs(base::SequencedTaskRunner* task_runner) 62 : task_runner_(task_runner), extensions_disabled_(false) { 63 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); 64 preferences_file_ = temp_dir_.path().AppendASCII("Preferences"); 65 extensions_dir_ = temp_dir_.path().AppendASCII("Extensions"); 66 EXPECT_TRUE(base::CreateDirectory(extensions_dir_)); 67 68 ResetPrefRegistry(); 69 RecreateExtensionPrefs(); 70 } 71 72 TestExtensionPrefs::~TestExtensionPrefs() { 73 } 74 75 PrefService* TestExtensionPrefs::pref_service() { 76 return pref_service_.get(); 77 } 78 79 const scoped_refptr<user_prefs::PrefRegistrySyncable>& 80 TestExtensionPrefs::pref_registry() { 81 return pref_registry_; 82 } 83 84 void TestExtensionPrefs::ResetPrefRegistry() { 85 pref_registry_ = new user_prefs::PrefRegistrySyncable; 86 ExtensionPrefs::RegisterProfilePrefs(pref_registry_.get()); 87 } 88 89 void TestExtensionPrefs::RecreateExtensionPrefs() { 90 // We persist and reload the PrefService's PrefStores because this process 91 // deletes all empty dictionaries. The ExtensionPrefs implementation 92 // needs to be able to handle this situation. 93 if (pref_service_) { 94 // Commit a pending write (which posts a task to task_runner_) and wait for 95 // it to finish. 96 pref_service_->CommitPendingWrite(); 97 base::RunLoop run_loop; 98 ASSERT_TRUE( 99 task_runner_->PostTaskAndReply( 100 FROM_HERE, 101 base::Bind(&base::DoNothing), 102 run_loop.QuitClosure())); 103 run_loop.Run(); 104 } 105 106 extension_pref_value_map_.reset(new ExtensionPrefValueMap); 107 PrefServiceMockFactory factory; 108 factory.SetUserPrefsFile(preferences_file_, task_runner_.get()); 109 factory.set_extension_prefs( 110 new ExtensionPrefStore(extension_pref_value_map_.get(), false)); 111 pref_service_ = factory.CreateSyncable(pref_registry_.get()).Pass(); 112 113 prefs_.reset(ExtensionPrefs::Create( 114 pref_service_.get(), 115 temp_dir_.path(), 116 extension_pref_value_map_.get(), 117 ExtensionsBrowserClient::Get()->CreateAppSorting().Pass(), 118 extensions_disabled_, 119 // Guarantee that no two extensions get the same installation time 120 // stamp and we can reliably assert the installation order in the tests. 121 scoped_ptr<ExtensionPrefs::TimeProvider>( 122 new IncrementalTimeProvider()))); 123 } 124 125 scoped_refptr<Extension> TestExtensionPrefs::AddExtension(std::string name) { 126 DictionaryValue dictionary; 127 dictionary.SetString(manifest_keys::kName, name); 128 dictionary.SetString(manifest_keys::kVersion, "0.1"); 129 return AddExtensionWithManifest(dictionary, Manifest::INTERNAL); 130 } 131 132 scoped_refptr<Extension> TestExtensionPrefs::AddApp(std::string name) { 133 DictionaryValue dictionary; 134 dictionary.SetString(manifest_keys::kName, name); 135 dictionary.SetString(manifest_keys::kVersion, "0.1"); 136 dictionary.SetString(manifest_keys::kApp, "true"); 137 dictionary.SetString(manifest_keys::kLaunchWebURL, "http://example.com"); 138 return AddExtensionWithManifest(dictionary, Manifest::INTERNAL); 139 140 } 141 142 scoped_refptr<Extension> TestExtensionPrefs::AddExtensionWithManifest( 143 const DictionaryValue& manifest, Manifest::Location location) { 144 return AddExtensionWithManifestAndFlags(manifest, location, 145 Extension::NO_FLAGS); 146 } 147 148 scoped_refptr<Extension> TestExtensionPrefs::AddExtensionWithManifestAndFlags( 149 const DictionaryValue& manifest, 150 Manifest::Location location, 151 int extra_flags) { 152 std::string name; 153 EXPECT_TRUE(manifest.GetString(manifest_keys::kName, &name)); 154 base::FilePath path = extensions_dir_.AppendASCII(name); 155 std::string errors; 156 scoped_refptr<Extension> extension = Extension::Create( 157 path, location, manifest, extra_flags, &errors); 158 EXPECT_TRUE(extension.get()) << errors; 159 if (!extension.get()) 160 return NULL; 161 162 EXPECT_TRUE(Extension::IdIsValid(extension->id())); 163 prefs_->OnExtensionInstalled(extension.get(), 164 Extension::ENABLED, 165 false, 166 syncer::StringOrdinal::CreateInitialOrdinal()); 167 return extension; 168 } 169 170 std::string TestExtensionPrefs::AddExtensionAndReturnId(std::string name) { 171 scoped_refptr<Extension> extension(AddExtension(name)); 172 return extension->id(); 173 } 174 175 PrefService* TestExtensionPrefs::CreateIncognitoPrefService() const { 176 return pref_service_->CreateIncognitoPrefService( 177 new ExtensionPrefStore(extension_pref_value_map_.get(), true)); 178 } 179 180 void TestExtensionPrefs::set_extensions_disabled(bool extensions_disabled) { 181 extensions_disabled_ = extensions_disabled; 182 } 183 184 } // namespace extensions 185