Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / chrome / browser / chromeos / login / enable_debugging_browsertest.cc
blobfc9e5710209de61029776f39e8e21458830edd1f
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.
5 #include <string>
7 #include "base/command_line.h"
8 #include "base/json/json_file_value_serializer.h"
9 #include "base/path_service.h"
10 #include "base/prefs/pref_service.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/chromeos/login/login_manager_test.h"
13 #include "chrome/browser/chromeos/login/startup_utils.h"
14 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
15 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
16 #include "chrome/browser/chromeos/login/ui/oobe_display.h"
17 #include "chrome/browser/chromeos/login/ui/webui_login_view.h"
18 #include "chrome/common/chrome_constants.h"
19 #include "chrome/common/chrome_paths.h"
20 #include "chrome/common/chrome_switches.h"
21 #include "chrome/common/pref_names.h"
22 #include "chromeos/chromeos_switches.h"
23 #include "chromeos/dbus/dbus_thread_manager.h"
24 #include "chromeos/dbus/fake_debug_daemon_client.h"
25 #include "chromeos/dbus/fake_power_manager_client.h"
26 #include "chromeos/dbus/fake_update_engine_client.h"
27 #include "content/public/test/browser_test_utils.h"
28 #include "content/public/test/test_utils.h"
29 #include "third_party/cros_system_api/dbus/service_constants.h"
31 namespace chromeos {
33 class TestDebugDaemonClient : public FakeDebugDaemonClient {
34 public:
35 TestDebugDaemonClient()
36 : got_reply_(false),
37 num_query_debugging_features_(0),
38 num_enable_debugging_features_(0),
39 num_remove_protection_(0) {
42 ~TestDebugDaemonClient() override {
45 // FakeDebugDaemonClient overrides:
46 void SetDebuggingFeaturesStatus(int featues_mask) override {
47 ResetWait();
48 FakeDebugDaemonClient::SetDebuggingFeaturesStatus(featues_mask);
51 void EnableDebuggingFeatures(
52 const std::string& password,
53 const EnableDebuggingCallback& callback) override {
54 FakeDebugDaemonClient::EnableDebuggingFeatures(
55 password,
56 base::Bind(&TestDebugDaemonClient::OnEnableDebuggingFeatures,
57 base::Unretained(this),
58 callback));
61 void RemoveRootfsVerification(
62 const DebugDaemonClient::EnableDebuggingCallback& callback) override {
63 FakeDebugDaemonClient::RemoveRootfsVerification(
64 base::Bind(&TestDebugDaemonClient::OnRemoveRootfsVerification,
65 base::Unretained(this),
66 callback));
69 void QueryDebuggingFeatures(
70 const DebugDaemonClient::QueryDevFeaturesCallback& callback) override {
71 LOG(WARNING) << "QueryDebuggingFeatures";
72 FakeDebugDaemonClient::QueryDebuggingFeatures(
73 base::Bind(&TestDebugDaemonClient::OnQueryDebuggingFeatures,
74 base::Unretained(this),
75 callback));
78 void OnRemoveRootfsVerification(
79 const DebugDaemonClient::EnableDebuggingCallback& original_callback,
80 bool succeeded) {
81 LOG(WARNING) << "OnRemoveRootfsVerification: succeeded = " << succeeded;
82 base::MessageLoop::current()->PostTask(
83 FROM_HERE,
84 base::Bind(original_callback, succeeded));
85 if (runner_.get())
86 runner_->Quit();
87 else
88 got_reply_ = true;
90 num_remove_protection_++;
93 void OnQueryDebuggingFeatures(
94 const DebugDaemonClient::QueryDevFeaturesCallback& original_callback,
95 bool succeeded,
96 int feature_mask) {
97 LOG(WARNING) << "OnQueryDebuggingFeatures: succeeded = " << succeeded
98 << ", feature_mask = " << feature_mask;
99 base::MessageLoop::current()->PostTask(
100 FROM_HERE,
101 base::Bind(original_callback, succeeded, feature_mask));
102 if (runner_.get())
103 runner_->Quit();
104 else
105 got_reply_ = true;
107 num_query_debugging_features_++;
110 void OnEnableDebuggingFeatures(
111 const DebugDaemonClient::EnableDebuggingCallback& original_callback,
112 bool succeeded) {
113 LOG(WARNING) << "OnEnableDebuggingFeatures: succeeded = " << succeeded
114 << ", feature_mask = ";
115 base::MessageLoop::current()->PostTask(
116 FROM_HERE,
117 base::Bind(original_callback, succeeded));
118 if (runner_.get())
119 runner_->Quit();
120 else
121 got_reply_ = true;
123 num_enable_debugging_features_++;
126 void ResetWait() {
127 got_reply_ = false;
128 num_query_debugging_features_ = 0;
129 num_enable_debugging_features_ = 0;
130 num_remove_protection_ = 0;
133 int num_query_debugging_features() const {
134 return num_query_debugging_features_;
137 int num_enable_debugging_features() const {
138 return num_enable_debugging_features_;
141 int num_remove_protection() const {
142 return num_remove_protection_;
145 void WaitUntilCalled() {
146 if (got_reply_)
147 return;
149 runner_ = new content::MessageLoopRunner;
150 runner_->Run();
153 private:
154 scoped_refptr<content::MessageLoopRunner> runner_;
155 bool got_reply_;
156 int num_query_debugging_features_;
157 int num_enable_debugging_features_;
158 int num_remove_protection_;
161 class EnableDebuggingTest : public LoginManagerTest {
162 public:
163 EnableDebuggingTest() : LoginManagerTest(false),
164 debug_daemon_client_(NULL),
165 power_manager_client_(NULL) {
167 ~EnableDebuggingTest() override {}
169 void SetUpCommandLine(base::CommandLine* command_line) override {
170 LoginManagerTest::SetUpCommandLine(command_line);
171 command_line->AppendSwitch(chromeos::switches::kSystemDevMode);
172 // Disable HID detection because it takes precedence and could block
173 // enable-debugging UI.
174 command_line->AppendSwitch(chromeos::switches::kDisableHIDDetectionOnOOBE);
177 // LoginManagerTest overrides:
178 void SetUpInProcessBrowserTestFixture() override {
179 scoped_ptr<DBusThreadManagerSetter> dbus_setter =
180 chromeos::DBusThreadManager::GetSetterForTesting();
181 power_manager_client_ = new FakePowerManagerClient;
182 dbus_setter->SetPowerManagerClient(
183 scoped_ptr<PowerManagerClient>(power_manager_client_));
184 debug_daemon_client_ = new TestDebugDaemonClient;
185 dbus_setter->SetDebugDaemonClient(
186 scoped_ptr<DebugDaemonClient>(debug_daemon_client_));
188 LoginManagerTest::SetUpInProcessBrowserTestFixture();
191 bool JSExecuted(const std::string& script) {
192 return content::ExecuteScript(web_contents(), script);
195 void WaitUntilJSIsReady() {
196 LoginDisplayHostImpl* host = static_cast<LoginDisplayHostImpl*>(
197 LoginDisplayHostImpl::default_host());
198 if (!host)
199 return;
200 chromeos::OobeUI* oobe_ui = host->GetOobeUI();
201 if (!oobe_ui)
202 return;
203 base::RunLoop run_loop;
204 const bool oobe_ui_ready = oobe_ui->IsJSReady(run_loop.QuitClosure());
205 if (!oobe_ui_ready)
206 run_loop.Run();
209 void InvokeEnableDebuggingScreen() {
210 ASSERT_TRUE(JSExecuted("cr.ui.Oobe.handleAccelerator('debugging');"));
211 OobeScreenWaiter(OobeDisplay::SCREEN_OOBE_ENABLE_DEBUGGING).Wait();
214 void CloseEnableDebuggingScreen() {
215 ASSERT_TRUE(JSExecuted("$('debugging-cancel-button').click();"));
218 void ClickRemoveProtectionButton() {
219 ASSERT_TRUE(JSExecuted("$('debugging-remove-protection-button').click();"));
222 void ClickEnableButton() {
223 ASSERT_TRUE(JSExecuted("$('debugging-enable-button').click();"));
226 void ClickOKButton() {
227 ASSERT_TRUE(JSExecuted("$('debugging-ok-button').click();"));
230 void ShowRemoveProtectionScreen() {
231 debug_daemon_client_->SetDebuggingFeaturesStatus(
232 DebugDaemonClient::DEV_FEATURE_NONE);
233 WaitUntilJSIsReady();
234 JSExpect("!!document.querySelector('#debugging.hidden')");
235 InvokeEnableDebuggingScreen();
236 JSExpect("!document.querySelector('#debugging.hidden')");
237 debug_daemon_client_->WaitUntilCalled();
238 base::MessageLoop::current()->RunUntilIdle();
239 VerifyRemoveProtectionScreen();
242 void VerifyRemoveProtectionScreen() {
243 JSExpect("!!document.querySelector('#debugging.remove-protection-view')");
244 JSExpect("!document.querySelector('#debugging.setup-view')");
245 JSExpect("!document.querySelector('#debugging.done-view')");
246 JSExpect("!document.querySelector('#debugging.wait-view')");
249 void ShowSetupScreen() {
250 debug_daemon_client_->SetDebuggingFeaturesStatus(
251 debugd::DevFeatureFlag::DEV_FEATURE_ROOTFS_VERIFICATION_REMOVED);
252 WaitUntilJSIsReady();
253 JSExpect("!!document.querySelector('#debugging.hidden')");
254 InvokeEnableDebuggingScreen();
255 JSExpect("!document.querySelector('#debugging.hidden')");
256 debug_daemon_client_->WaitUntilCalled();
257 base::MessageLoop::current()->RunUntilIdle();
258 JSExpect("!document.querySelector('#debugging.remove-protection-view')");
259 JSExpect("!!document.querySelector('#debugging.setup-view')");
260 JSExpect("!document.querySelector('#debugging.done-view')");
261 JSExpect("!document.querySelector('#debugging.wait-view')");
264 TestDebugDaemonClient* debug_daemon_client_;
265 FakePowerManagerClient* power_manager_client_;
268 // Show remove protection screen, click on [Cancel] button.
269 IN_PROC_BROWSER_TEST_F(EnableDebuggingTest, ShowAndCancelRemoveProtection) {
270 ShowRemoveProtectionScreen();
271 CloseEnableDebuggingScreen();
272 JSExpect("!!document.querySelector('#debugging.hidden')");
274 EXPECT_EQ(debug_daemon_client_->num_query_debugging_features(), 1);
275 EXPECT_EQ(debug_daemon_client_->num_enable_debugging_features(), 0);
276 EXPECT_EQ(debug_daemon_client_->num_remove_protection(), 0);
279 // Show remove protection, click on [Remove protection] button and wait for
280 // reboot.
281 IN_PROC_BROWSER_TEST_F(EnableDebuggingTest, ShowAndRemoveProtection) {
282 ShowRemoveProtectionScreen();
283 debug_daemon_client_->ResetWait();
284 ClickRemoveProtectionButton();
285 debug_daemon_client_->WaitUntilCalled();
286 JSExpect("!!document.querySelector('#debugging.wait-view')");
287 // Check if we have rebooted after enabling.
288 base::MessageLoop::current()->RunUntilIdle();
289 EXPECT_EQ(debug_daemon_client_->num_remove_protection(), 1);
290 EXPECT_EQ(debug_daemon_client_->num_enable_debugging_features(), 0);
291 EXPECT_EQ(power_manager_client_->num_request_restart_calls(), 1);
295 // Show setup screen. Click on [Enable] button. Wait until done screen is shown.
296 IN_PROC_BROWSER_TEST_F(EnableDebuggingTest, ShowSetup) {
297 ShowSetupScreen();
298 debug_daemon_client_->ResetWait();
299 ClickEnableButton();
300 debug_daemon_client_->WaitUntilCalled();
301 base::MessageLoop::current()->RunUntilIdle();
302 JSExpect("!!document.querySelector('#debugging.done-view')");
303 EXPECT_EQ(debug_daemon_client_->num_enable_debugging_features(), 1);
304 EXPECT_EQ(debug_daemon_client_->num_remove_protection(), 0);
307 // Test images come with some features enabled but still has rootfs protection.
308 // Invoking debug screen should show remove protection screen.
309 IN_PROC_BROWSER_TEST_F(EnableDebuggingTest, ShowOnTestImages) {
310 debug_daemon_client_->SetDebuggingFeaturesStatus(
311 debugd::DevFeatureFlag::DEV_FEATURE_SSH_SERVER_CONFIGURED |
312 debugd::DevFeatureFlag::DEV_FEATURE_SYSTEM_ROOT_PASSWORD_SET);
313 WaitUntilJSIsReady();
314 JSExpect("!!document.querySelector('#debugging.hidden')");
315 InvokeEnableDebuggingScreen();
316 JSExpect("!document.querySelector('#debugging.hidden')");
317 debug_daemon_client_->WaitUntilCalled();
318 base::MessageLoop::current()->RunUntilIdle();
319 VerifyRemoveProtectionScreen();
321 EXPECT_EQ(debug_daemon_client_->num_query_debugging_features(), 1);
322 EXPECT_EQ(debug_daemon_client_->num_enable_debugging_features(), 0);
323 EXPECT_EQ(debug_daemon_client_->num_remove_protection(), 0);
326 IN_PROC_BROWSER_TEST_F(EnableDebuggingTest, WaitForDebugDaemon) {
327 // Stat with service not ready.
328 debug_daemon_client_->SetServiceIsAvailable(false);
329 debug_daemon_client_->SetDebuggingFeaturesStatus(
330 DebugDaemonClient::DEV_FEATURE_NONE);
331 WaitUntilJSIsReady();
333 // Invoking UI and it should land on wait-view.
334 JSExpect("!!document.querySelector('#debugging.hidden')");
335 InvokeEnableDebuggingScreen();
336 JSExpect("!document.querySelector('#debugging.hidden')");
337 JSExpect("!!document.querySelector('#debugging.wait-view')");
339 // Mark service ready and it should proceed to remove protection view.
340 debug_daemon_client_->SetServiceIsAvailable(true);
341 debug_daemon_client_->WaitUntilCalled();
342 base::MessageLoop::current()->RunUntilIdle();
343 VerifyRemoveProtectionScreen();
346 class EnableDebuggingNonDevTest : public EnableDebuggingTest {
347 public:
348 EnableDebuggingNonDevTest() {
351 void SetUpCommandLine(base::CommandLine* command_line) override {
352 // Skip EnableDebuggingTest::SetUpCommandLine().
353 LoginManagerTest::SetUpCommandLine(command_line);
356 // LoginManagerTest overrides:
357 void SetUpInProcessBrowserTestFixture() override {
358 scoped_ptr<DBusThreadManagerSetter> dbus_setter =
359 chromeos::DBusThreadManager::GetSetterForTesting();
360 dbus_setter->SetDebugDaemonClient(
361 scoped_ptr<DebugDaemonClient>(new FakeDebugDaemonClient));
362 LoginManagerTest::SetUpInProcessBrowserTestFixture();
366 // Try to show enable debugging dialog, we should see error screen here.
367 IN_PROC_BROWSER_TEST_F(EnableDebuggingNonDevTest, NoShowInNonDevMode) {
368 JSExpect("!!document.querySelector('#debugging.hidden')");
369 InvokeEnableDebuggingScreen();
370 JSExpect("!document.querySelector('#debugging.hidden')");
371 base::MessageLoop::current()->RunUntilIdle();
372 JSExpect("!!document.querySelector('#debugging.error-view')");
373 JSExpect("!document.querySelector('#debugging.remove-protection-view')");
374 JSExpect("!document.querySelector('#debugging.setup-view')");
375 JSExpect("!document.querySelector('#debugging.done-view')");
376 JSExpect("!document.querySelector('#debugging.wait-view')");
379 class EnableDebuggingRequestedTest : public EnableDebuggingTest {
380 public:
381 EnableDebuggingRequestedTest() {
384 // EnableDebuggingTest overrides:
385 bool SetUpUserDataDirectory() override {
386 base::DictionaryValue local_state_dict;
387 local_state_dict.SetBoolean(prefs::kDebuggingFeaturesRequested, true);
389 base::FilePath user_data_dir;
390 CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
391 base::FilePath local_state_path =
392 user_data_dir.Append(chrome::kLocalStateFilename);
393 CHECK(
394 JSONFileValueSerializer(local_state_path).Serialize(local_state_dict));
396 return EnableDebuggingTest::SetUpUserDataDirectory();
398 void SetUpInProcessBrowserTestFixture() override {
399 EnableDebuggingTest::SetUpInProcessBrowserTestFixture();
401 debug_daemon_client_->SetDebuggingFeaturesStatus(
402 debugd::DevFeatureFlag::DEV_FEATURE_ROOTFS_VERIFICATION_REMOVED);
406 // Setup screen is automatically shown when the feature is requested.
407 IN_PROC_BROWSER_TEST_F(EnableDebuggingRequestedTest, AutoShowSetup) {
408 OobeScreenWaiter(OobeDisplay::SCREEN_OOBE_ENABLE_DEBUGGING).Wait();
411 // Canceling auto shown setup screen should close it.
412 IN_PROC_BROWSER_TEST_F(EnableDebuggingRequestedTest, CancelAutoShowSetup) {
413 OobeScreenWaiter(OobeDisplay::SCREEN_OOBE_ENABLE_DEBUGGING).Wait();
414 CloseEnableDebuggingScreen();
415 JSExpect("!!document.querySelector('#debugging.hidden')");
418 } // namespace chromeos