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/profiles/off_the_record_profile_impl.h" 6 7 #include "base/prefs/pref_registry_simple.h" 8 #include "base/prefs/pref_service.h" 9 #include "base/prefs/scoped_user_pref_update.h" 10 #include "base/run_loop.h" 11 #include "chrome/browser/prefs/browser_prefs.h" 12 #include "chrome/common/pref_names.h" 13 #include "chrome/test/base/browser_with_test_window_test.h" 14 #include "chrome/test/base/testing_browser_process.h" 15 #include "chrome/test/base/testing_io_thread_state.h" 16 #include "chrome/test/base/testing_pref_service_syncable.h" 17 #include "chrome/test/base/testing_profile.h" 18 #include "chrome/test/base/testing_profile_manager.h" 19 #include "content/public/browser/host_zoom_map.h" 20 #include "content/public/common/page_zoom.h" 21 #include "net/dns/mock_host_resolver.h" 22 23 using content::HostZoomMap; 24 25 namespace { 26 27 class TestingProfileWithHostZoomMap : public TestingProfile { 28 public: 29 TestingProfileWithHostZoomMap() { 30 zoom_subscription_ = 31 HostZoomMap::GetDefaultForBrowserContext(this) 32 ->AddZoomLevelChangedCallback( 33 base::Bind(&TestingProfileWithHostZoomMap::OnZoomLevelChanged, 34 base::Unretained(this))); 35 } 36 37 virtual ~TestingProfileWithHostZoomMap() {} 38 39 // Profile overrides: 40 virtual PrefService* GetOffTheRecordPrefs() OVERRIDE { 41 return GetPrefs(); 42 } 43 44 private: 45 void OnZoomLevelChanged(const HostZoomMap::ZoomLevelChange& change) { 46 47 if (change.mode != HostZoomMap::ZOOM_CHANGED_FOR_HOST) 48 return; 49 50 HostZoomMap* host_zoom_map = HostZoomMap::GetDefaultForBrowserContext(this); 51 52 double level = change.zoom_level; 53 DictionaryPrefUpdate update(prefs_.get(), prefs::kPerHostZoomLevels); 54 base::DictionaryValue* host_zoom_dictionary = update.Get(); 55 if (content::ZoomValuesEqual(level, host_zoom_map->GetDefaultZoomLevel())) { 56 host_zoom_dictionary->RemoveWithoutPathExpansion(change.host, NULL); 57 } else { 58 host_zoom_dictionary->SetWithoutPathExpansion( 59 change.host, new base::FundamentalValue(level)); 60 } 61 } 62 63 scoped_ptr<HostZoomMap::Subscription> zoom_subscription_; 64 65 DISALLOW_COPY_AND_ASSIGN(TestingProfileWithHostZoomMap); 66 }; 67 68 } // namespace 69 70 // We need to have a BrowserProcess in g_browser_process variable, since 71 // OffTheRecordProfileImpl ctor uses it in 72 // ProfileIOData::InitializeProfileParams. 73 class OffTheRecordProfileImplTest : public BrowserWithTestWindowTest { 74 protected: 75 OffTheRecordProfileImplTest() {} 76 77 virtual ~OffTheRecordProfileImplTest() {} 78 79 // testing::Test overrides: 80 virtual void SetUp() OVERRIDE { 81 profile_manager_.reset(new TestingProfileManager(browser_process())); 82 ASSERT_TRUE(profile_manager_->SetUp()); 83 84 testing_io_thread_state_.reset(new chrome::TestingIOThreadState()); 85 testing_io_thread_state_->io_thread_state()->globals()->host_resolver.reset( 86 new net::MockHostResolver()); 87 88 BrowserWithTestWindowTest::SetUp(); 89 } 90 91 virtual void TearDown() OVERRIDE { 92 BrowserWithTestWindowTest::TearDown(); 93 94 testing_io_thread_state_.reset(); 95 96 profile_manager_.reset(); 97 } 98 99 // BrowserWithTestWindowTest overrides: 100 virtual TestingProfile* CreateProfile() OVERRIDE { 101 return new TestingProfileWithHostZoomMap; 102 } 103 104 private: 105 TestingBrowserProcess* browser_process() { 106 return TestingBrowserProcess::GetGlobal(); 107 } 108 109 scoped_ptr<TestingProfileManager> profile_manager_; 110 scoped_ptr<chrome::TestingIOThreadState> testing_io_thread_state_; 111 112 DISALLOW_COPY_AND_ASSIGN(OffTheRecordProfileImplTest); 113 }; 114 115 // Test four things: 116 // 1. Host zoom maps of parent profile and child profile are different. 117 // 2. Child host zoom map inherites zoom level at construction. 118 // 3. Change of zoom level doesn't propagate from child to parent. 119 // 4. Change of zoom level propagate from parent to child. 120 TEST_F(OffTheRecordProfileImplTest, GetHostZoomMap) { 121 // Constants for test case. 122 const std::string host("example.com"); 123 const double zoom_level_25 = 2.5; 124 const double zoom_level_30 = 3.0; 125 const double zoom_level_40 = 4.0; 126 127 // The TestingProfile from CreateProfile above is the parent. 128 TestingProfile* parent_profile = GetProfile(); 129 ASSERT_TRUE(parent_profile); 130 ASSERT_TRUE(parent_profile->GetPrefs()); 131 ASSERT_TRUE(parent_profile->GetOffTheRecordPrefs()); 132 133 // Prepare parent host zoom map. 134 HostZoomMap* parent_zoom_map = 135 HostZoomMap::GetDefaultForBrowserContext(parent_profile); 136 ASSERT_TRUE(parent_zoom_map); 137 138 parent_zoom_map->SetZoomLevelForHost(host, zoom_level_25); 139 ASSERT_EQ(parent_zoom_map->GetZoomLevelForHostAndScheme("http", host), 140 zoom_level_25); 141 142 // TODO(yosin) We need to wait ProfileImpl::Observe done for 143 // OnZoomLevelChanged. 144 145 // Prepare an off the record profile owned by the parent profile. 146 parent_profile->SetOffTheRecordProfile( 147 scoped_ptr<Profile>(new OffTheRecordProfileImpl(parent_profile))); 148 OffTheRecordProfileImpl* child_profile = 149 static_cast<OffTheRecordProfileImpl*>( 150 parent_profile->GetOffTheRecordProfile()); 151 child_profile->InitIoData(); 152 child_profile->InitHostZoomMap(); 153 154 // Prepare child host zoom map. 155 HostZoomMap* child_zoom_map = 156 HostZoomMap::GetDefaultForBrowserContext(child_profile); 157 ASSERT_TRUE(child_zoom_map); 158 159 // Verify. 160 EXPECT_NE(parent_zoom_map, child_zoom_map); 161 162 EXPECT_EQ(parent_zoom_map->GetZoomLevelForHostAndScheme("http", host), 163 child_zoom_map->GetZoomLevelForHostAndScheme("http", host)) << 164 "Child must inherit from parent."; 165 166 child_zoom_map->SetZoomLevelForHost(host, zoom_level_30); 167 ASSERT_EQ( 168 child_zoom_map->GetZoomLevelForHostAndScheme("http", host), 169 zoom_level_30); 170 171 EXPECT_NE(parent_zoom_map->GetZoomLevelForHostAndScheme("http", host), 172 child_zoom_map->GetZoomLevelForHostAndScheme("http", host)) << 173 "Child change must not propagate to parent."; 174 175 parent_zoom_map->SetZoomLevelForHost(host, zoom_level_40); 176 ASSERT_EQ( 177 parent_zoom_map->GetZoomLevelForHostAndScheme("http", host), 178 zoom_level_40); 179 180 EXPECT_EQ(parent_zoom_map->GetZoomLevelForHostAndScheme("http", host), 181 child_zoom_map->GetZoomLevelForHostAndScheme("http", host)) << 182 "Parent change should propagate to child."; 183 base::RunLoop().RunUntilIdle(); 184 } 185