OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 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/power/process_power_collector.h" | |
6 | |
7 #include "apps/app_window_contents.h" | |
8 #include "apps/app_window_registry.h" | |
9 #include "chrome/browser/profiles/profile_manager.h" | |
10 #include "chrome/browser/ui/apps/chrome_app_delegate.h" | |
11 #include "chrome/browser/ui/browser_commands.h" | |
12 #include "chrome/browser/ui/tabs/tab_strip_model.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_profile_manager.h" | |
16 #include "components/power/origin_power_map.h" | |
17 #include "components/power/origin_power_map_factory.h" | |
18 #include "content/public/browser/site_instance.h" | |
19 #include "content/public/test/browser_test_utils.h" | |
20 #include "content/public/test/mock_render_process_host.h" | |
21 #include "extensions/browser/app_window/native_app_window.h" | |
22 #include "extensions/common/extension.h" | |
23 #include "testing/gtest/include/gtest/gtest.h" | |
24 #include "url/gurl.h" | |
25 | |
26 #if defined(OS_CHROMEOS) | |
27 #include "chrome/browser/chromeos/power/power_data_collector.h" | |
28 #include "chromeos/dbus/dbus_thread_manager.h" | |
29 #include "chromeos/dbus/fake_dbus_thread_manager.h" | |
30 #include "chromeos/dbus/power_manager/power_supply_properties.pb.h" | |
31 #endif | |
32 | |
33 using power::OriginPowerMap; | |
34 using power::OriginPowerMapFactory; | |
35 | |
36 class BrowserProcessPowerTest : public BrowserWithTestWindowTest { | |
37 public: | |
38 BrowserProcessPowerTest() {} | |
39 virtual ~BrowserProcessPowerTest() {} | |
40 | |
41 virtual void SetUp() OVERRIDE { | |
42 BrowserWithTestWindowTest::SetUp(); | |
43 #if defined(OS_CHROMEOS) | |
44 chromeos::DBusThreadManager::Shutdown(); | |
45 chromeos::FakeDBusThreadManager* fake_dbus_thread_manager = | |
46 new chromeos::FakeDBusThreadManager; | |
47 fake_dbus_thread_manager->SetFakeClients(); | |
Daniel Erat
2014/08/20 21:53:15
while we're waiting for steven to reply: what happ
Daniel Nishi
2014/08/21 17:53:55
Hm... I didn't know the powerd sent updates that r
| |
48 chromeos::DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager); | |
49 chromeos::PowerDataCollector::InitializeForTesting(); | |
50 | |
51 power_manager::PowerSupplyProperties prop1; | |
52 prop1.set_external_power( | |
53 power_manager::PowerSupplyProperties::DISCONNECTED); | |
54 prop1.set_battery_percent(20.00); | |
55 prop1.set_battery_discharge_rate(1); | |
56 chromeos::PowerDataCollector::Get()->PowerChanged(prop1); | |
57 #endif | |
58 | |
59 profile_manager_.reset( | |
60 new TestingProfileManager(TestingBrowserProcess::GetGlobal())); | |
61 ASSERT_TRUE(profile_manager_->SetUp()); | |
62 } | |
63 | |
64 virtual void TearDown() OVERRIDE { | |
65 #if defined(OS_CHROMEOS) | |
66 chromeos::PowerDataCollector::Shutdown(); | |
67 #endif | |
68 BrowserWithTestWindowTest::TearDown(); | |
69 } | |
70 | |
71 // Mocks out CPU usage for all processes as 5. | |
72 int ReturnCpuAs5(base::ProcessHandle handle) { return 5; } | |
Daniel Erat
2014/08/20 21:53:15
probably cleaner to pass the desired CPU usage int
Daniel Nishi
2014/08/21 17:53:55
Done. We curry now.
| |
73 | |
74 protected: | |
75 ProcessPowerCollector collector; | |
76 scoped_ptr<TestingProfileManager> profile_manager_; | |
77 | |
78 content::MockRenderProcessHost* process(Browser* browser) { | |
79 return static_cast<content::MockRenderProcessHost*>( | |
80 browser->tab_strip_model() | |
81 ->GetActiveWebContents() | |
82 ->GetRenderViewHost() | |
83 ->GetProcess()); | |
84 } | |
85 | |
86 scoped_ptr<base::ProcessHandle> MakeProcessHandle(int process_id) { | |
87 scoped_ptr<base::ProcessHandle> proc_handle(new base::ProcessHandle( | |
88 #if defined(OS_WIN) | |
89 reinterpret_cast<HANDLE>(process_id)) | |
90 #else | |
91 process_id) | |
92 #endif | |
93 ); | |
94 return proc_handle.Pass(); | |
95 } | |
96 }; | |
97 | |
98 class TestAppWindowContents : public apps::AppWindowContents { | |
99 public: | |
100 explicit TestAppWindowContents(content::WebContents* web_contents) { | |
101 web_contents_.reset(web_contents); | |
102 } | |
103 // apps:AppWindowContents | |
104 virtual void Initialize(content::BrowserContext* context, | |
105 const GURL& url) OVERRIDE{}; | |
106 virtual void LoadContents(int32 creator_process_id) OVERRIDE{}; | |
107 virtual void NativeWindowChanged( | |
108 extensions::NativeAppWindow* native_app_window) OVERRIDE{}; | |
109 virtual void NativeWindowClosed() OVERRIDE{}; | |
110 virtual void DispatchWindowShownForTests() const OVERRIDE{}; | |
111 virtual content::WebContents* GetWebContents() const OVERRIDE { | |
112 return web_contents_.get(); | |
113 } | |
114 | |
115 private: | |
116 scoped_ptr<content::WebContents> web_contents_; | |
117 }; | |
118 | |
119 TEST_F(BrowserProcessPowerTest, NoSite) { | |
120 collector.UpdatePowerConsumptionForTesting(); | |
121 EXPECT_EQ(0u, collector.metrics_map_for_testing()->size()); | |
122 } | |
123 | |
124 TEST_F(BrowserProcessPowerTest, OneSite) { | |
125 GURL url("http://www.google.com"); | |
126 AddTab(browser(), url); | |
127 collector.UpdatePowerConsumptionForTesting(); | |
128 ProcessPowerCollector::ProcessMetricsMap* metrics_map = | |
129 collector.metrics_map_for_testing(); | |
130 EXPECT_EQ(1u, metrics_map->size()); | |
131 | |
132 // Create fake process numbers. | |
133 process(browser())->SetProcessHandle(MakeProcessHandle(1).Pass()); | |
134 | |
135 OriginPowerMap* origin_power_map = | |
136 OriginPowerMapFactory::GetForBrowserContext(profile()); | |
137 EXPECT_EQ(0, origin_power_map->GetPowerForOrigin(url)); | |
138 | |
139 collector.SetGetCpuUsageCallbackForTesting(base::Bind( | |
140 &BrowserProcessPowerTest::ReturnCpuAs5, base::Unretained(this))); | |
141 EXPECT_DOUBLE_EQ(5, collector.UpdatePowerConsumptionForTesting()); | |
142 EXPECT_EQ(100, origin_power_map->GetPowerForOrigin(url)); | |
143 } | |
144 | |
145 TEST_F(BrowserProcessPowerTest, MultipleSites) { | |
146 Browser::CreateParams native_params(profile(), | |
147 chrome::HOST_DESKTOP_TYPE_NATIVE); | |
148 GURL url1("http://www.google.com"); | |
149 GURL url2("http://www.example.com"); | |
150 GURL url3("https://www.google.com"); | |
151 scoped_ptr<Browser> browser2( | |
152 chrome::CreateBrowserWithTestWindowForParams(&native_params)); | |
153 scoped_ptr<Browser> browser3( | |
154 chrome::CreateBrowserWithTestWindowForParams(&native_params)); | |
155 AddTab(browser(), url1); | |
156 AddTab(browser2.get(), url2); | |
157 AddTab(browser3.get(), url3); | |
158 | |
159 // Create fake process numbers. | |
160 process(browser())->SetProcessHandle(MakeProcessHandle(1).Pass()); | |
161 process(browser2.get())->SetProcessHandle(MakeProcessHandle(2).Pass()); | |
162 process(browser3.get())->SetProcessHandle(MakeProcessHandle(3).Pass()); | |
163 | |
164 collector.UpdatePowerConsumptionForTesting(); | |
165 ProcessPowerCollector::ProcessMetricsMap* metrics_map = | |
166 collector.metrics_map_for_testing(); | |
167 EXPECT_EQ(3u, metrics_map->size()); | |
168 | |
169 // Since all handlers are uninitialized, this should be 0. | |
170 EXPECT_DOUBLE_EQ(0, collector.UpdatePowerConsumptionForTesting()); | |
171 OriginPowerMap* origin_power_map = | |
172 OriginPowerMapFactory::GetForBrowserContext(profile()); | |
173 EXPECT_EQ(0, origin_power_map->GetPowerForOrigin(url1)); | |
174 EXPECT_EQ(0, origin_power_map->GetPowerForOrigin(url2)); | |
175 EXPECT_EQ(0, origin_power_map->GetPowerForOrigin(url3)); | |
176 | |
177 collector.SetGetCpuUsageCallbackForTesting(base::Bind( | |
178 &BrowserProcessPowerTest::ReturnCpuAs5, base::Unretained(this))); | |
179 EXPECT_DOUBLE_EQ(15, collector.UpdatePowerConsumptionForTesting()); | |
Daniel Erat
2014/08/20 21:53:14
i think i'm still missing some understanding of ho
| |
180 EXPECT_EQ(33, origin_power_map->GetPowerForOrigin(url1)); | |
Daniel Erat
2014/08/20 21:53:14
side question that i should've asked earlier: what
Daniel Nishi
2014/08/21 17:53:55
To answer this question and the above, here is a G
| |
181 EXPECT_EQ(33, origin_power_map->GetPowerForOrigin(url2)); | |
182 EXPECT_EQ(33, origin_power_map->GetPowerForOrigin(url3)); | |
183 | |
184 // Close some tabs and verify that they are removed from the metrics map. | |
185 chrome::CloseTab(browser2.get()); | |
186 chrome::CloseTab(browser3.get()); | |
187 | |
188 collector.UpdatePowerConsumptionForTesting(); | |
189 EXPECT_EQ(1u, metrics_map->size()); | |
190 } | |
191 | |
192 TEST_F(BrowserProcessPowerTest, IncognitoDoesntRecordPowerUsage) { | |
193 Browser::CreateParams native_params(profile()->GetOffTheRecordProfile(), | |
194 chrome::HOST_DESKTOP_TYPE_NATIVE); | |
195 scoped_ptr<Browser> incognito_browser( | |
196 chrome::CreateBrowserWithTestWindowForParams(&native_params)); | |
197 GURL url("http://www.google.com"); | |
198 AddTab(browser(), url); | |
199 | |
200 GURL hidden_url("http://foo.com"); | |
201 AddTab(incognito_browser.get(), hidden_url); | |
202 | |
203 // Create fake process numbers. | |
204 process(browser())->SetProcessHandle(MakeProcessHandle(1).Pass()); | |
205 process(incognito_browser.get()) | |
206 ->SetProcessHandle(MakeProcessHandle(2).Pass()); | |
207 | |
208 EXPECT_DOUBLE_EQ(0, collector.UpdatePowerConsumptionForTesting()); | |
209 ProcessPowerCollector::ProcessMetricsMap* metrics_map = | |
210 collector.metrics_map_for_testing(); | |
211 EXPECT_EQ(1u, metrics_map->size()); | |
212 | |
213 OriginPowerMap* origin_power_map = | |
214 OriginPowerMapFactory::GetForBrowserContext(profile()); | |
215 EXPECT_EQ(0, origin_power_map->GetPowerForOrigin(url)); | |
216 | |
217 collector.SetGetCpuUsageCallbackForTesting(base::Bind( | |
218 &BrowserProcessPowerTest::ReturnCpuAs5, base::Unretained(this))); | |
219 EXPECT_DOUBLE_EQ(5, collector.UpdatePowerConsumptionForTesting()); | |
220 | |
221 // Verify that the incognito data was not stored. | |
222 EXPECT_EQ(100, origin_power_map->GetPowerForOrigin(url)); | |
223 EXPECT_EQ(0, origin_power_map->GetPowerForOrigin(hidden_url)); | |
224 | |
225 chrome::CloseTab(incognito_browser.get()); | |
226 } | |
227 | |
228 TEST_F(BrowserProcessPowerTest, MultipleProfilesRecordSeparately) { | |
229 scoped_ptr<Profile> other_profile(CreateProfile()); | |
230 Browser::CreateParams native_params(other_profile.get(), | |
231 chrome::HOST_DESKTOP_TYPE_NATIVE); | |
232 scoped_ptr<Browser> other_user( | |
233 chrome::CreateBrowserWithTestWindowForParams(&native_params)); | |
234 | |
235 GURL url("http://www.google.com"); | |
236 AddTab(browser(), url); | |
237 | |
238 GURL hidden_url("http://foo.com"); | |
239 AddTab(other_user.get(), hidden_url); | |
240 | |
241 // Create fake process numbers. | |
242 process(browser())->SetProcessHandle(MakeProcessHandle(1).Pass()); | |
243 process(other_user.get())->SetProcessHandle(MakeProcessHandle(2).Pass()); | |
244 | |
245 EXPECT_DOUBLE_EQ(0, collector.UpdatePowerConsumptionForTesting()); | |
246 EXPECT_EQ(2u, collector.metrics_map_for_testing()->size()); | |
247 | |
248 collector.SetGetCpuUsageCallbackForTesting(base::Bind( | |
249 &BrowserProcessPowerTest::ReturnCpuAs5, base::Unretained(this))); | |
250 EXPECT_DOUBLE_EQ(10, collector.UpdatePowerConsumptionForTesting()); | |
251 | |
252 // profile() should have an entry for |url| but not |hidden_url|. | |
253 OriginPowerMap* origin_power_map_first = | |
254 OriginPowerMapFactory::GetForBrowserContext(profile()); | |
255 EXPECT_EQ(100, origin_power_map_first->GetPowerForOrigin(url)); | |
256 EXPECT_EQ(0, origin_power_map_first->GetPowerForOrigin(hidden_url)); | |
257 | |
258 // |other_profile| should have an entry for |hidden_url| but not |url|. | |
259 OriginPowerMap* origin_power_map_second = | |
260 OriginPowerMapFactory::GetForBrowserContext(other_profile.get()); | |
261 EXPECT_EQ(0, origin_power_map_second->GetPowerForOrigin(url)); | |
262 EXPECT_EQ(100, origin_power_map_second->GetPowerForOrigin(hidden_url)); | |
263 | |
264 // Clean up | |
265 chrome::CloseTab(other_user.get()); | |
266 } | |
267 | |
268 TEST_F(BrowserProcessPowerTest, AppsRecordPowerUsage) { | |
269 // Install an app (an extension*). | |
270 #if defined(OS_WIN) | |
271 base::FilePath extension_path(FILE_PATH_LITERAL("c:\\foo")); | |
272 #elif defined(OS_POSIX) | |
273 base::FilePath extension_path(FILE_PATH_LITERAL("/foo")); | |
274 #endif | |
275 base::DictionaryValue manifest; | |
276 manifest.SetString("name", "Fake Name"); | |
277 manifest.SetString("version", "1"); | |
278 std::string error; | |
279 char kTestAppId[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; | |
280 scoped_refptr<extensions::Extension> extension( | |
281 extensions::Extension::Create(extension_path, | |
282 extensions::Manifest::INTERNAL, | |
283 manifest, | |
284 extensions::Extension::NO_FLAGS, | |
285 kTestAppId, | |
286 &error)); | |
287 EXPECT_TRUE(extension.get()) << error; | |
288 | |
289 Profile* current_profile = | |
290 profile_manager_->CreateTestingProfile("Test user"); | |
291 GURL url("chrome-extension://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); | |
292 apps::AppWindow* window = | |
293 new apps::AppWindow(current_profile, new ChromeAppDelegate(), extension); | |
294 scoped_ptr<content::WebContents> web_contents( | |
295 content::WebContents::Create(content::WebContents::CreateParams( | |
296 current_profile, | |
297 content::SiteInstance::CreateForURL(current_profile, url)))); | |
298 window->SetAppWindowContentsForTesting(scoped_ptr<apps::AppWindowContents>( | |
299 new TestAppWindowContents(web_contents.get()))); | |
300 apps::AppWindowRegistry* app_registry = | |
301 apps::AppWindowRegistry::Get(current_profile); | |
302 app_registry->AddAppWindow(window); | |
303 | |
304 collector.UpdatePowerConsumptionForTesting(); | |
305 EXPECT_EQ(1u, collector.metrics_map_for_testing()->size()); | |
306 | |
307 app_registry->RemoveAppWindow(window); | |
308 collector.UpdatePowerConsumptionForTesting(); | |
309 EXPECT_EQ(0u, collector.metrics_map_for_testing()->size()); | |
310 } | |
OLD | NEW |