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