OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_han dler.h" | 5 #include "chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_han dler.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "ash/system/devicetype_utils.h" | 11 #include "ash/system/devicetype_utils.h" |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/files/file_path.h" | 13 #include "base/files/file_path.h" |
14 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
15 #include "base/metrics/user_metrics.h" | |
15 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
16 #include "base/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
17 #include "base/sys_info.h" | 18 #include "base/sys_info.h" |
18 #include "base/task_scheduler/post_task.h" | 19 #include "base/task_scheduler/post_task.h" |
20 #include "base/threading/thread_task_runner_handle.h" | |
21 #include "base/time/time.h" | |
19 #include "chrome/browser/browser_process.h" | 22 #include "chrome/browser/browser_process.h" |
20 #include "chrome/browser/chromeos/arc/arc_migration_constants.h" | 23 #include "chrome/browser/chromeos/arc/arc_migration_constants.h" |
21 #include "chrome/browser/chromeos/login/ui/login_feedback.h" | 24 #include "chrome/browser/chromeos/login/ui/login_feedback.h" |
22 #include "chrome/browser/lifetime/application_lifetime.h" | 25 #include "chrome/browser/lifetime/application_lifetime.h" |
23 #include "chrome/browser/profiles/profile.h" | 26 #include "chrome/browser/profiles/profile.h" |
24 #include "chrome/grit/generated_resources.h" | 27 #include "chrome/grit/generated_resources.h" |
25 #include "chromeos/chromeos_switches.h" | 28 #include "chromeos/chromeos_switches.h" |
26 #include "chromeos/cryptohome/async_method_caller.h" | 29 #include "chromeos/cryptohome/async_method_caller.h" |
27 #include "chromeos/cryptohome/homedir_methods.h" | 30 #include "chromeos/cryptohome/homedir_methods.h" |
28 #include "chromeos/dbus/cryptohome_client.h" | 31 #include "chromeos/dbus/cryptohome_client.h" |
(...skipping 10 matching lines...) Expand all Loading... | |
39 | 42 |
40 constexpr char kJsScreenPath[] = "login.EncryptionMigrationScreen"; | 43 constexpr char kJsScreenPath[] = "login.EncryptionMigrationScreen"; |
41 | 44 |
42 // Path to the mount point to check the available space. | 45 // Path to the mount point to check the available space. |
43 constexpr char kCheckStoragePath[] = "/home"; | 46 constexpr char kCheckStoragePath[] = "/home"; |
44 | 47 |
45 // JS API callbacks names. | 48 // JS API callbacks names. |
46 constexpr char kJsApiStartMigration[] = "startMigration"; | 49 constexpr char kJsApiStartMigration[] = "startMigration"; |
47 constexpr char kJsApiSkipMigration[] = "skipMigration"; | 50 constexpr char kJsApiSkipMigration[] = "skipMigration"; |
48 constexpr char kJsApiRequestRestart[] = "requestRestart"; | 51 constexpr char kJsApiRequestRestart[] = "requestRestart"; |
52 constexpr char kJsApiRequestRestartOnFailure[] = "requestRestartOnFailure"; | |
49 constexpr char kJsApiOpenFeedbackDialog[] = "openFeedbackDialog"; | 53 constexpr char kJsApiOpenFeedbackDialog[] = "openFeedbackDialog"; |
50 | 54 |
51 // UMA names. | 55 // UMA names. |
52 constexpr char kUmaNameFirstScreen[] = "Cryptohome.MigrationUI.FirstScreen"; | 56 constexpr char kUmaNameFirstScreen[] = "Cryptohome.MigrationUI.FirstScreen"; |
53 constexpr char kUmaNameUserChoice[] = "Cryptohome.MigrationUI.UserChoice"; | 57 constexpr char kUmaNameUserChoice[] = "Cryptohome.MigrationUI.UserChoice"; |
58 constexpr char kUmaNameMigrationResult[] = | |
59 "Cryptohome.MigrationUI.MigrationResult"; | |
60 constexpr char kUmaNameRemoveCryptohomeResult[] = | |
61 "Cryptohome.MigrationUI.RemoveCryptohomeResult"; | |
54 constexpr char kUmaNameConsumedBatteryPercent[] = | 62 constexpr char kUmaNameConsumedBatteryPercent[] = |
55 "Cryptohome.MigrationUI.ConsumedBatteryPercent"; | 63 "Cryptohome.MigrationUI.ConsumedBatteryPercent"; |
56 | 64 |
57 // This enum must match the numbering for Cryptohome.MigrationUI.FirstScreen in | 65 // This enum must match the numbering for MigrationUIFirstScreen in |
58 // histograms.xml. Do not reorder or remove items, only add new items before | 66 // histograms/enums.xml. Do not reorder or remove items, only add new items |
59 // FIRST_SCREEN_MAX. | 67 // before FIRST_SCREEN_COUNT. |
60 enum class FirstScreen { | 68 enum class FirstScreen { |
61 FIRST_SCREEN_READY = 0, | 69 FIRST_SCREEN_READY = 0, |
62 FIRST_SCREEN_RESUME = 1, | 70 FIRST_SCREEN_RESUME = 1, |
63 FIRST_SCREEN_LOW_STORAGE = 2, | 71 FIRST_SCREEN_LOW_STORAGE = 2, |
64 FIRST_SCREEN_COUNT | 72 FIRST_SCREEN_COUNT |
65 }; | 73 }; |
66 | 74 |
67 // This enum must match the numbering for Cryptohome.MigrationUI.UserChoice in | 75 // This enum must match the numbering for MigrationUIUserChoice in |
68 // histograms.xml. Do not reorder or remove items, only add new items before | 76 // histograms/enums.xml. Do not reorder or remove items, only add new items |
69 // FIRST_SCREEN_MAX. | 77 // before USER_CHOICE_COUNT. |
70 enum class UserChoice { | 78 enum class UserChoice { |
71 USER_CHOICE_UPDATE = 0, | 79 USER_CHOICE_UPDATE = 0, |
72 USER_CHOICE_SKIP = 1, | 80 USER_CHOICE_SKIP = 1, |
73 USER_CHOICE_COUNT | 81 USER_CHOICE_COUNT |
74 }; | 82 }; |
75 | 83 |
84 // This enum must match the numbering for MigrationUIMigrationResult in | |
85 // histograms/enums.xml. Do not reorder or remove items, only add new items | |
86 // before COUNT. | |
87 enum class MigrationResult { | |
fukino
2017/05/31 12:21:28
MigrationResult and RemoveCryptohomeResult have th
| |
88 SUCCESS_IN_NEW_MIGRATION = 0, | |
89 SUCCESS_IN_RESUMED_MIGRATION = 1, | |
90 FAILURE_IN_NEW_MIGRATION = 2, | |
91 FAILURE_IN_RESUMED_MIGRATION = 3, | |
92 COUNT | |
93 }; | |
94 | |
95 // This enum must match the numbering for MigrationUIRemoveCryptohomeResult in | |
96 // histograms/enums.xml. Do not reorder or remove items, only add new items | |
97 // before COUNT. | |
98 enum class RemoveCryptohomeResult { | |
99 SUCCESS_IN_NEW_MIGRATION = 0, | |
100 SUCCESS_IN_RESUMED_MIGRATION = 1, | |
101 FAILURE_IN_NEW_MIGRATION = 2, | |
102 FAILURE_IN_RESUMED_MIGRATION = 3, | |
103 COUNT | |
104 }; | |
105 | |
76 bool IsTestingUI() { | 106 bool IsTestingUI() { |
77 return base::CommandLine::ForCurrentProcess()->HasSwitch( | 107 return base::CommandLine::ForCurrentProcess()->HasSwitch( |
78 chromeos::switches::kTestEncryptionMigrationUI); | 108 chromeos::switches::kTestEncryptionMigrationUI); |
79 } | 109 } |
80 | 110 |
81 // Wrapper functions for histogram macros to avoid duplication of expanded code. | 111 // Wrapper functions for histogram macros to avoid duplication of expanded code. |
82 void RecordFirstScreen(FirstScreen first_screen) { | 112 void RecordFirstScreen(FirstScreen first_screen) { |
83 UMA_HISTOGRAM_ENUMERATION(kUmaNameFirstScreen, static_cast<int>(first_screen), | 113 UMA_HISTOGRAM_ENUMERATION(kUmaNameFirstScreen, static_cast<int>(first_screen), |
84 static_cast<int>(FirstScreen::FIRST_SCREEN_COUNT)); | 114 static_cast<int>(FirstScreen::FIRST_SCREEN_COUNT)); |
85 } | 115 } |
86 | 116 |
87 void RecordUserChoice(UserChoice user_choice) { | 117 void RecordUserChoice(UserChoice user_choice) { |
88 UMA_HISTOGRAM_ENUMERATION(kUmaNameUserChoice, static_cast<int>(user_choice), | 118 UMA_HISTOGRAM_ENUMERATION(kUmaNameUserChoice, static_cast<int>(user_choice), |
89 static_cast<int>(UserChoice::USER_CHOICE_COUNT)); | 119 static_cast<int>(UserChoice::USER_CHOICE_COUNT)); |
90 } | 120 } |
91 | 121 |
122 void RecordMigrationResult(bool success, bool is_resumed_migration) { | |
123 MigrationResult result = | |
124 success ? (is_resumed_migration | |
125 ? MigrationResult::SUCCESS_IN_RESUMED_MIGRATION | |
126 : MigrationResult::SUCCESS_IN_NEW_MIGRATION) | |
127 : (is_resumed_migration | |
128 ? MigrationResult::FAILURE_IN_RESUMED_MIGRATION | |
129 : MigrationResult::FAILURE_IN_NEW_MIGRATION); | |
130 UMA_HISTOGRAM_ENUMERATION(kUmaNameMigrationResult, static_cast<int>(result), | |
131 static_cast<int>(MigrationResult::COUNT)); | |
Ilya Sherman
2017/05/31 23:34:44
nit: static_casts shouldn't be needed anymore when
fukino
2017/06/01 09:28:38
Done.
| |
132 } | |
133 | |
134 void RecordRemoveCryptohomeResult(bool success, bool is_resumed_migration) { | |
135 RemoveCryptohomeResult result = | |
136 success ? (is_resumed_migration | |
137 ? RemoveCryptohomeResult::SUCCESS_IN_RESUMED_MIGRATION | |
138 : RemoveCryptohomeResult::SUCCESS_IN_NEW_MIGRATION) | |
139 : (is_resumed_migration | |
140 ? RemoveCryptohomeResult::FAILURE_IN_RESUMED_MIGRATION | |
141 : RemoveCryptohomeResult::FAILURE_IN_NEW_MIGRATION); | |
142 UMA_HISTOGRAM_ENUMERATION(kUmaNameRemoveCryptohomeResult, | |
143 static_cast<int>(result), | |
144 static_cast<int>(RemoveCryptohomeResult::COUNT)); | |
145 } | |
146 | |
147 void RecordShowFailureScreen() { | |
148 base::RecordAction( | |
149 base::UserMetricsAction("Cryptohome.MigrationUI.ShowFailureScreen")); | |
150 } | |
151 | |
92 } // namespace | 152 } // namespace |
93 | 153 |
94 namespace chromeos { | 154 namespace chromeos { |
95 | 155 |
96 EncryptionMigrationScreenHandler::EncryptionMigrationScreenHandler() | 156 EncryptionMigrationScreenHandler::EncryptionMigrationScreenHandler() |
97 : BaseScreenHandler(kScreenId), weak_ptr_factory_(this) { | 157 : BaseScreenHandler(kScreenId), weak_ptr_factory_(this) { |
98 set_call_js_prefix(kJsScreenPath); | 158 set_call_js_prefix(kJsScreenPath); |
99 } | 159 } |
100 | 160 |
101 EncryptionMigrationScreenHandler::~EncryptionMigrationScreenHandler() { | 161 EncryptionMigrationScreenHandler::~EncryptionMigrationScreenHandler() { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
198 } | 258 } |
199 } | 259 } |
200 | 260 |
201 void EncryptionMigrationScreenHandler::RegisterMessages() { | 261 void EncryptionMigrationScreenHandler::RegisterMessages() { |
202 AddCallback(kJsApiStartMigration, | 262 AddCallback(kJsApiStartMigration, |
203 &EncryptionMigrationScreenHandler::HandleStartMigration); | 263 &EncryptionMigrationScreenHandler::HandleStartMigration); |
204 AddCallback(kJsApiSkipMigration, | 264 AddCallback(kJsApiSkipMigration, |
205 &EncryptionMigrationScreenHandler::HandleSkipMigration); | 265 &EncryptionMigrationScreenHandler::HandleSkipMigration); |
206 AddCallback(kJsApiRequestRestart, | 266 AddCallback(kJsApiRequestRestart, |
207 &EncryptionMigrationScreenHandler::HandleRequestRestart); | 267 &EncryptionMigrationScreenHandler::HandleRequestRestart); |
268 AddCallback(kJsApiRequestRestartOnFailure, | |
269 &EncryptionMigrationScreenHandler::HandleRequestRestartOnFailure); | |
208 AddCallback(kJsApiOpenFeedbackDialog, | 270 AddCallback(kJsApiOpenFeedbackDialog, |
209 &EncryptionMigrationScreenHandler::HandleOpenFeedbackDialog); | 271 &EncryptionMigrationScreenHandler::HandleOpenFeedbackDialog); |
210 } | 272 } |
211 | 273 |
212 void EncryptionMigrationScreenHandler::PowerChanged( | 274 void EncryptionMigrationScreenHandler::PowerChanged( |
213 const power_manager::PowerSupplyProperties& proto) { | 275 const power_manager::PowerSupplyProperties& proto) { |
214 if (proto.has_battery_percent()) { | 276 if (proto.has_battery_percent()) { |
215 if (!current_battery_percent_) { | 277 if (!current_battery_percent_) { |
216 // If initial battery level is below the minimum, migration should start | 278 // If initial battery level is below the minimum, migration should start |
217 // automatically once the device is charged enough. | 279 // automatically once the device is charged enough. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
254 if (!continue_login_callback_.is_null()) { | 316 if (!continue_login_callback_.is_null()) { |
255 user_context_.SetIsForcingDircrypto(false); | 317 user_context_.SetIsForcingDircrypto(false); |
256 std::move(continue_login_callback_).Run(user_context_); | 318 std::move(continue_login_callback_).Run(user_context_); |
257 } | 319 } |
258 } | 320 } |
259 | 321 |
260 void EncryptionMigrationScreenHandler::HandleRequestRestart() { | 322 void EncryptionMigrationScreenHandler::HandleRequestRestart() { |
261 DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); | 323 DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); |
262 } | 324 } |
263 | 325 |
326 void EncryptionMigrationScreenHandler::HandleRequestRestartOnFailure() { | |
327 base::RecordAction(base::UserMetricsAction( | |
328 "Cryptohome.MigrationUI.RestartClickedOnFailure")); | |
329 DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); | |
330 } | |
331 | |
264 void EncryptionMigrationScreenHandler::HandleOpenFeedbackDialog() { | 332 void EncryptionMigrationScreenHandler::HandleOpenFeedbackDialog() { |
265 const std::string description = base::StringPrintf( | 333 const std::string description = base::StringPrintf( |
266 "Auto generated feedback for http://crbug.com/719266.\n" | 334 "Auto generated feedback for http://crbug.com/719266.\n" |
267 "(uniquifier:%s)", | 335 "(uniquifier:%s)", |
268 base::Int64ToString(base::Time::Now().ToInternalValue()).c_str()); | 336 base::Int64ToString(base::Time::Now().ToInternalValue()).c_str()); |
269 login_feedback_.reset(new LoginFeedback(Profile::FromWebUI(web_ui()))); | 337 login_feedback_.reset(new LoginFeedback(Profile::FromWebUI(web_ui()))); |
270 login_feedback_->Request(description, base::Closure()); | 338 login_feedback_->Request(description, base::Closure()); |
271 } | 339 } |
272 | 340 |
273 void EncryptionMigrationScreenHandler::UpdateUIState(UIState state) { | 341 void EncryptionMigrationScreenHandler::UpdateUIState(UIState state) { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
391 cryptohome::Identification(user_context_.GetAccountId()), | 459 cryptohome::Identification(user_context_.GetAccountId()), |
392 base::Bind(&EncryptionMigrationScreenHandler::OnRemoveCryptohome, | 460 base::Bind(&EncryptionMigrationScreenHandler::OnRemoveCryptohome, |
393 weak_ptr_factory_.GetWeakPtr())); | 461 weak_ptr_factory_.GetWeakPtr())); |
394 } | 462 } |
395 | 463 |
396 void EncryptionMigrationScreenHandler::OnRemoveCryptohome( | 464 void EncryptionMigrationScreenHandler::OnRemoveCryptohome( |
397 bool success, | 465 bool success, |
398 cryptohome::MountError return_code) { | 466 cryptohome::MountError return_code) { |
399 LOG_IF(ERROR, !success) << "Removing cryptohome failed. return code: " | 467 LOG_IF(ERROR, !success) << "Removing cryptohome failed. return code: " |
400 << return_code; | 468 << return_code; |
469 RecordRemoveCryptohomeResult(success, should_resume_); | |
401 UpdateUIState(UIState::MIGRATION_FAILED); | 470 UpdateUIState(UIState::MIGRATION_FAILED); |
402 } | 471 } |
403 | 472 |
404 cryptohome::KeyDefinition EncryptionMigrationScreenHandler::GetAuthKey() { | 473 cryptohome::KeyDefinition EncryptionMigrationScreenHandler::GetAuthKey() { |
405 // |auth_key| is created in the same manner as CryptohomeAuthenticator. | 474 // |auth_key| is created in the same manner as CryptohomeAuthenticator. |
406 const Key* key = user_context_.GetKey(); | 475 const Key* key = user_context_.GetKey(); |
407 // If the |key| is a plain text password, crash rather than attempting to | 476 // If the |key| is a plain text password, crash rather than attempting to |
408 // mount the cryptohome with a plain text password. | 477 // mount the cryptohome with a plain text password. |
409 CHECK_NE(Key::KEY_TYPE_PASSWORD_PLAIN, key->GetKeyType()); | 478 CHECK_NE(Key::KEY_TYPE_PASSWORD_PLAIN, key->GetKeyType()); |
410 // Set the authentication's key label to an empty string, which is a wildcard | 479 // Set the authentication's key label to an empty string, which is a wildcard |
(...skipping 11 matching lines...) Expand all Loading... | |
422 uint64_t total) { | 491 uint64_t total) { |
423 switch (status) { | 492 switch (status) { |
424 case cryptohome::DIRCRYPTO_MIGRATION_INITIALIZING: | 493 case cryptohome::DIRCRYPTO_MIGRATION_INITIALIZING: |
425 UpdateUIState(UIState::MIGRATING); | 494 UpdateUIState(UIState::MIGRATING); |
426 break; | 495 break; |
427 case cryptohome::DIRCRYPTO_MIGRATION_IN_PROGRESS: | 496 case cryptohome::DIRCRYPTO_MIGRATION_IN_PROGRESS: |
428 UpdateUIState(UIState::MIGRATING); | 497 UpdateUIState(UIState::MIGRATING); |
429 CallJS("setMigrationProgress", static_cast<double>(current) / total); | 498 CallJS("setMigrationProgress", static_cast<double>(current) / total); |
430 break; | 499 break; |
431 case cryptohome::DIRCRYPTO_MIGRATION_SUCCESS: | 500 case cryptohome::DIRCRYPTO_MIGRATION_SUCCESS: |
501 RecordMigrationResult(true, should_resume_); | |
432 // If the battery level decreased during migration, record the consumed | 502 // If the battery level decreased during migration, record the consumed |
433 // battery level. | 503 // battery level. |
434 if (*current_battery_percent_ < initial_battery_percent_) { | 504 if (*current_battery_percent_ < initial_battery_percent_) { |
435 UMA_HISTOGRAM_PERCENTAGE( | 505 UMA_HISTOGRAM_PERCENTAGE( |
436 kUmaNameConsumedBatteryPercent, | 506 kUmaNameConsumedBatteryPercent, |
437 static_cast<int>(std::round(initial_battery_percent_ - | 507 static_cast<int>(std::round(initial_battery_percent_ - |
438 *current_battery_percent_))); | 508 *current_battery_percent_))); |
439 } | 509 } |
440 // Restart immediately after successful migration. | 510 // Restart immediately after successful migration. |
441 DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); | 511 DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); |
442 break; | 512 break; |
443 case cryptohome::DIRCRYPTO_MIGRATION_FAILED: | 513 case cryptohome::DIRCRYPTO_MIGRATION_FAILED: |
514 RecordMigrationResult(false, should_resume_); | |
515 // Record an event that the user sees the failure screen. | |
516 // We record it after delay to make sure that the user was actually able | |
517 // to see the failure screen. There is a potential race condition where | |
518 // the user can see only flash of failure screen on shutting down. | |
519 // crbug.com/727980. | |
520 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
521 FROM_HERE, base::BindOnce(&RecordShowFailureScreen), | |
522 base::TimeDelta::FromSeconds(1)); | |
444 // Stop listening to the progress updates. | 523 // Stop listening to the progress updates. |
445 DBusThreadManager::Get() | 524 DBusThreadManager::Get() |
446 ->GetCryptohomeClient() | 525 ->GetCryptohomeClient() |
447 ->SetDircryptoMigrationProgressHandler( | 526 ->SetDircryptoMigrationProgressHandler( |
448 CryptohomeClient::DircryptoMigrationProgessHandler()); | 527 CryptohomeClient::DircryptoMigrationProgessHandler()); |
449 // Shows error screen after removing user directory is completed. | 528 // Shows error screen after removing user directory is completed. |
450 RemoveCryptohome(); | 529 RemoveCryptohome(); |
451 break; | 530 break; |
452 default: | 531 default: |
453 break; | 532 break; |
454 } | 533 } |
455 } | 534 } |
456 | 535 |
457 void EncryptionMigrationScreenHandler::OnMigrationRequested(bool success) { | 536 void EncryptionMigrationScreenHandler::OnMigrationRequested(bool success) { |
458 if (!success) { | 537 if (!success) { |
459 LOG(ERROR) << "Requesting MigrateToDircrypto failed."; | 538 LOG(ERROR) << "Requesting MigrateToDircrypto failed."; |
460 UpdateUIState(UIState::MIGRATION_FAILED); | 539 UpdateUIState(UIState::MIGRATION_FAILED); |
461 } | 540 } |
462 } | 541 } |
463 | 542 |
464 } // namespace chromeos | 543 } // namespace chromeos |
OLD | NEW |