15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/test_extension_prefs.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 12b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/prefs/json_pref_store.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_value_store.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/run_loop.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sequenced_task_runner.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/prefs/pref_service_mock_factory.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/prefs/pref_service_syncable.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/common/chrome_constants.h" 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/crx_file/id_util.h" 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/pref_registry/pref_registry_syncable.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_pref_store.h" 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_pref_value_map.h" 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_prefs.h" 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/extensions_browser_client.h" 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest_constants.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/string_ordinal.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A TimeProvider which returns an incrementally later time each time 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// GetCurrentTime is called. 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class IncrementalTimeProvider : public ExtensionPrefs::TimeProvider { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IncrementalTimeProvider() : current_time_(base::Time::Now()) { 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~IncrementalTimeProvider() { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual base::Time GetCurrentTime() const OVERRIDE { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_time_ += base::TimeDelta::FromSeconds(10); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return current_time_; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(IncrementalTimeProvider); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mutable base::Time current_time_; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTestExtensionPrefs::TestExtensionPrefs( 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::SequencedTaskRunner>& task_runner) 657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : task_runner_(task_runner), extensions_disabled_(false) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) preferences_file_ = temp_dir_.path().Append(chrome::kPreferencesFilename); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions_dir_ = temp_dir_.path().AppendASCII("Extensions"); 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_TRUE(base::CreateDirectory(extensions_dir_)); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ResetPrefRegistry(); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecreateExtensionPrefs(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestExtensionPrefs::~TestExtensionPrefs() { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrefService* TestExtensionPrefs::pref_service() { 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return pref_service_.get(); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const scoped_refptr<user_prefs::PrefRegistrySyncable>& 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TestExtensionPrefs::pref_registry() { 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return pref_registry_; 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestExtensionPrefs::ResetPrefRegistry() { 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pref_registry_ = new user_prefs::PrefRegistrySyncable; 897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ExtensionPrefs::RegisterProfilePrefs(pref_registry_.get()); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestExtensionPrefs::RecreateExtensionPrefs() { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We persist and reload the PrefService's PrefStores because this process 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // deletes all empty dictionaries. The ExtensionPrefs implementation 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // needs to be able to handle this situation. 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (pref_service_) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Commit a pending write (which posts a task to task_runner_) and wait for 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it to finish. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_service_->CommitPendingWrite(); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::RunLoop run_loop; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE( 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task_runner_->PostTaskAndReply( 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&base::DoNothing), 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) run_loop.QuitClosure())); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) run_loop.Run(); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_pref_value_map_.reset(new ExtensionPrefValueMap); 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PrefServiceMockFactory factory; 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) factory.SetUserPrefsFile(preferences_file_, task_runner_.get()); 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) factory.set_extension_prefs( 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ExtensionPrefStore(extension_pref_value_map_.get(), false)); 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) pref_service_ = factory.CreateSyncable(pref_registry_.get()).Pass(); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) prefs_.reset(ExtensionPrefs::Create( 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pref_service_.get(), 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) temp_dir_.path(), 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_pref_value_map_.get(), 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionsBrowserClient::Get()->CreateAppSorting().Pass(), 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions_disabled_, 122e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch std::vector<ExtensionPrefsObserver*>(), 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Guarantee that no two extensions get the same installation time 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // stamp and we can reliably assert the installation order in the tests. 125e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch scoped_ptr<ExtensionPrefs::TimeProvider>(new IncrementalTimeProvider()))); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuscoped_refptr<Extension> TestExtensionPrefs::AddExtension( 1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& name) { 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue dictionary; 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dictionary.SetString(manifest_keys::kName, name); 1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dictionary.SetString(manifest_keys::kVersion, "0.1"); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AddExtensionWithManifest(dictionary, Manifest::INTERNAL); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuscoped_refptr<Extension> TestExtensionPrefs::AddApp(const std::string& name) { 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue dictionary; 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dictionary.SetString(manifest_keys::kName, name); 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dictionary.SetString(manifest_keys::kVersion, "0.1"); 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dictionary.SetString(manifest_keys::kApp, "true"); 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) dictionary.SetString(manifest_keys::kLaunchWebURL, "http://example.com"); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AddExtensionWithManifest(dictionary, Manifest::INTERNAL); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Extension> TestExtensionPrefs::AddExtensionWithManifest( 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::DictionaryValue& manifest, Manifest::Location location) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddExtensionWithManifestAndFlags(manifest, location, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Extension::NO_FLAGS); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<Extension> TestExtensionPrefs::AddExtensionWithManifestAndFlags( 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::DictionaryValue& manifest, 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Manifest::Location location, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int extra_flags) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name; 1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EXPECT_TRUE(manifest.GetString(manifest_keys::kName, &name)); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath path = extensions_dir_.AppendASCII(name); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string errors; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension = Extension::Create( 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path, location, manifest, extra_flags, &errors); 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRUE(extension.get()) << errors; 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!extension.get()) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_TRUE(crx_file::id_util::IdIsValid(extension->id())); 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) prefs_->OnExtensionInstalled(extension.get(), 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Extension::ENABLED, 169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch syncer::StringOrdinal::CreateInitialOrdinal(), 170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch std::string()); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustd::string TestExtensionPrefs::AddExtensionAndReturnId( 1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& name) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<Extension> extension(AddExtension(name)); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extension->id(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrefService* TestExtensionPrefs::CreateIncognitoPrefService() const { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pref_service_->CreateIncognitoPrefService( 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ExtensionPrefStore(extension_pref_value_map_.get(), true)); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestExtensionPrefs::set_extensions_disabled(bool extensions_disabled) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions_disabled_ = extensions_disabled; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 190