Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc

Issue 2910423002: cros: Add UMA metrics in migration UI to get more information from migration failures. (Closed)
Patch Set: Add Cryptohome.MigrationUI.ShowFailureScreen. Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698