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

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

Issue 2818433002: Wait for the battery level before starting encryption migration. (Closed)
Patch Set: Created 3 years, 8 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 <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/command_line.h"
10 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
11 #include "base/sys_info.h" 12 #include "base/sys_info.h"
12 #include "base/task_scheduler/post_task.h" 13 #include "base/task_scheduler/post_task.h"
13 #include "chrome/browser/lifetime/application_lifetime.h" 14 #include "chrome/browser/lifetime/application_lifetime.h"
15 #include "chromeos/chromeos_switches.h"
14 #include "chromeos/cryptohome/homedir_methods.h" 16 #include "chromeos/cryptohome/homedir_methods.h"
15 #include "chromeos/dbus/cryptohome_client.h" 17 #include "chromeos/dbus/cryptohome_client.h"
16 #include "chromeos/dbus/dbus_thread_manager.h" 18 #include "chromeos/dbus/dbus_thread_manager.h"
19 #include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
20 #include "chromeos/dbus/power_manager_client.h"
17 21
18 namespace { 22 namespace {
19 23
20 constexpr char kJsScreenPath[] = "login.EncryptionMigrationScreen"; 24 constexpr char kJsScreenPath[] = "login.EncryptionMigrationScreen";
21 25
22 // Path to the mount point to check the available space. 26 // Path to the mount point to check the available space.
23 constexpr char kCheckStoragePath[] = "/home"; 27 constexpr char kCheckStoragePath[] = "/home";
24 28
25 // The minimum size of available space to start the migration. 29 // The minimum size of available space to start the migration.
26 constexpr int64_t kMinimumAvailableStorage = 10LL * 1024 * 1024; // 10MB 30 constexpr int64_t kMinimumAvailableStorage = 10LL * 1024 * 1024; // 10MB
27 31
32 // The minimum battery level to start the migration.
33 constexpr double kMinimumBatteryPercent = 30;
34
28 // JS API callbacks names. 35 // JS API callbacks names.
29 constexpr char kJsApiStartMigration[] = "startMigration"; 36 constexpr char kJsApiStartMigration[] = "startMigration";
30 constexpr char kJsApiSkipMigration[] = "skipMigration"; 37 constexpr char kJsApiSkipMigration[] = "skipMigration";
31 constexpr char kJsApiRequestRestart[] = "requestRestart"; 38 constexpr char kJsApiRequestRestart[] = "requestRestart";
32 39
40 bool IsTestingUI() {
41 return base::CommandLine::ForCurrentProcess()->HasSwitch(
42 chromeos::switches::kTestEncryptionMigrationUI);
43 }
44
33 } // namespace 45 } // namespace
34 46
35 namespace chromeos { 47 namespace chromeos {
36 48
37 EncryptionMigrationScreenHandler::EncryptionMigrationScreenHandler() 49 EncryptionMigrationScreenHandler::EncryptionMigrationScreenHandler()
38 : BaseScreenHandler(kScreenId), weak_ptr_factory_(this) { 50 : BaseScreenHandler(kScreenId), weak_ptr_factory_(this) {
39 set_call_js_prefix(kJsScreenPath); 51 set_call_js_prefix(kJsScreenPath);
52 DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this);
40 } 53 }
41 54
42 EncryptionMigrationScreenHandler::~EncryptionMigrationScreenHandler() { 55 EncryptionMigrationScreenHandler::~EncryptionMigrationScreenHandler() {
56 DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this);
43 if (delegate_) 57 if (delegate_)
44 delegate_->OnViewDestroyed(this); 58 delegate_->OnViewDestroyed(this);
45 } 59 }
46 60
47 void EncryptionMigrationScreenHandler::Show() { 61 void EncryptionMigrationScreenHandler::Show() {
48 if (!page_is_ready() || !delegate_) { 62 if (!page_is_ready() || !delegate_) {
49 show_on_init_ = true; 63 show_on_init_ = true;
50 return; 64 return;
51 } 65 }
52 ShowScreen(kScreenId); 66 ShowScreen(kScreenId);
53 } 67 }
54 68
55 void EncryptionMigrationScreenHandler::Hide() { 69 void EncryptionMigrationScreenHandler::Hide() {
56 show_on_init_ = false; 70 show_on_init_ = false;
57 } 71 }
58 72
59 void EncryptionMigrationScreenHandler::SetDelegate(Delegate* delegate) { 73 void EncryptionMigrationScreenHandler::SetDelegate(Delegate* delegate) {
60 delegate_ = delegate; 74 delegate_ = delegate;
61 if (page_is_ready()) 75 if (page_is_ready())
62 Initialize(); 76 Initialize();
63 } 77 }
64 78
65 void EncryptionMigrationScreenHandler::SetUserContext( 79 void EncryptionMigrationScreenHandler::SetUserContext(
66 const UserContext& user_context) { 80 const UserContext& user_context) {
67 user_context_ = user_context; 81 user_context_ = user_context;
68 } 82 }
69 83
70 void EncryptionMigrationScreenHandler::SetShouldResume(bool should_resume) { 84 void EncryptionMigrationScreenHandler::SetShouldResume(bool should_resume) {
71 should_resume_ = should_resume; 85 should_resume_ = should_resume;
86 CallJS("setIsResuming", should_resume_);
72 } 87 }
73 88
74 void EncryptionMigrationScreenHandler::SetContinueLoginCallback( 89 void EncryptionMigrationScreenHandler::SetContinueLoginCallback(
75 ContinueLoginCallback callback) { 90 ContinueLoginCallback callback) {
76 continue_login_callback_ = std::move(callback); 91 continue_login_callback_ = std::move(callback);
77 } 92 }
78 93
79 void EncryptionMigrationScreenHandler::SetupInitialView() { 94 void EncryptionMigrationScreenHandler::SetupInitialView() {
80 CheckAvailableStorage(); 95 CheckAvailableStorage();
81 } 96 }
(...skipping 13 matching lines...) Expand all
95 110
96 void EncryptionMigrationScreenHandler::RegisterMessages() { 111 void EncryptionMigrationScreenHandler::RegisterMessages() {
97 AddCallback(kJsApiStartMigration, 112 AddCallback(kJsApiStartMigration,
98 &EncryptionMigrationScreenHandler::HandleStartMigration); 113 &EncryptionMigrationScreenHandler::HandleStartMigration);
99 AddCallback(kJsApiSkipMigration, 114 AddCallback(kJsApiSkipMigration,
100 &EncryptionMigrationScreenHandler::HandleSkipMigration); 115 &EncryptionMigrationScreenHandler::HandleSkipMigration);
101 AddCallback(kJsApiRequestRestart, 116 AddCallback(kJsApiRequestRestart,
102 &EncryptionMigrationScreenHandler::HandleRequestRestart); 117 &EncryptionMigrationScreenHandler::HandleRequestRestart);
103 } 118 }
104 119
120 void EncryptionMigrationScreenHandler::PowerChanged(
121 const power_manager::PowerSupplyProperties& proto) {
122 current_battery_percent_ = proto.battery_percent();
123 CallJS("setBatteryPercent", current_battery_percent_,
124 current_battery_percent_ >= kMinimumBatteryPercent);
125
126 // If the migration was already requested and the bettery level is enough now,
127 // The migration should start immediately.
128 if (current_battery_percent_ >= kMinimumBatteryPercent &&
129 should_migrate_on_enough_battery_) {
130 should_migrate_on_enough_battery_ = false;
131 StartMigration();
132 }
133 }
134
105 void EncryptionMigrationScreenHandler::HandleStartMigration() { 135 void EncryptionMigrationScreenHandler::HandleStartMigration() {
106 StartMigration(); 136 CallJS("setIsMigrationAccepted", true);
137 WaitBatteryAndMigrate();
107 } 138 }
108 139
109 void EncryptionMigrationScreenHandler::HandleSkipMigration() { 140 void EncryptionMigrationScreenHandler::HandleSkipMigration() {
110 // If the user skips migration, we mount the cryptohome without performing the 141 // If the user skips migration, we mount the cryptohome without performing the
111 // migration by reusing UserContext and LoginPerformer which were used in the 142 // migration by reusing UserContext and LoginPerformer which were used in the
112 // previous attempt and dropping |is_forcing_dircrypto| flag in UserContext. 143 // previous attempt and dropping |is_forcing_dircrypto| flag in UserContext.
113 // In this case, the user can not launch ARC apps in the session, and will be 144 // In this case, the user can not launch ARC apps in the session, and will be
114 // asked to do the migration again in the next log-in attempt. 145 // asked to do the migration again in the next log-in attempt.
115 if (!continue_login_callback_.is_null()) { 146 if (!continue_login_callback_.is_null()) {
116 user_context_.SetIsForcingDircrypto(false); 147 user_context_.SetIsForcingDircrypto(false);
117 std::move(continue_login_callback_).Run(user_context_); 148 std::move(continue_login_callback_).Run(user_context_);
118 } 149 }
119 } 150 }
120 151
121 void EncryptionMigrationScreenHandler::HandleRequestRestart() { 152 void EncryptionMigrationScreenHandler::HandleRequestRestart() {
122 // TODO(fukino): If the migration finished successfully, we don't need to 153 // TODO(fukino): If the migration finished successfully, we don't need to
123 // restart the device. Let's sign in to the desktop using the already-provided 154 // restart the device. Let's sign in to the desktop using the already-provided
124 // user credential. 155 // user credential.
125 chrome::AttemptRestart(); 156 chrome::AttemptRestart();
126 } 157 }
127 158
128 void EncryptionMigrationScreenHandler::UpdateUIState(UIState state) { 159 void EncryptionMigrationScreenHandler::UpdateUIState(UIState state) {
129 if (state == current_ui_state_) 160 if (state == current_ui_state_)
130 return; 161 return;
131 162
132 current_ui_state_ = state; 163 current_ui_state_ = state;
133 CallJS("setUIState", static_cast<int>(state)); 164 CallJS("setUIState", static_cast<int>(state));
165
166 // When this handler is about to show the READY screen, we should get the
167 // latest battery status and show it on the screen.
168 if (state == UIState::READY)
169 DBusThreadManager::Get()->GetPowerManagerClient()->RequestStatusUpdate();
134 } 170 }
135 171
136 void EncryptionMigrationScreenHandler::CheckAvailableStorage() { 172 void EncryptionMigrationScreenHandler::CheckAvailableStorage() {
137 base::PostTaskWithTraitsAndReplyWithResult( 173 base::PostTaskWithTraitsAndReplyWithResult(
138 FROM_HERE, 174 FROM_HERE,
139 base::TaskTraits().MayBlock().WithPriority( 175 base::TaskTraits().MayBlock().WithPriority(
140 base::TaskPriority::USER_VISIBLE), 176 base::TaskPriority::USER_VISIBLE),
141 base::Bind(&base::SysInfo::AmountOfFreeDiskSpace, 177 base::Bind(&base::SysInfo::AmountOfFreeDiskSpace,
142 base::FilePath(kCheckStoragePath)), 178 base::FilePath(kCheckStoragePath)),
143 base::Bind(&EncryptionMigrationScreenHandler::OnGetAvailableStorage, 179 base::Bind(&EncryptionMigrationScreenHandler::OnGetAvailableStorage,
144 weak_ptr_factory_.GetWeakPtr())); 180 weak_ptr_factory_.GetWeakPtr()));
145 } 181 }
146 182
147 void EncryptionMigrationScreenHandler::OnGetAvailableStorage(int64_t size) { 183 void EncryptionMigrationScreenHandler::OnGetAvailableStorage(int64_t size) {
148 if (size < kMinimumAvailableStorage) { 184 if (size >= kMinimumAvailableStorage || IsTestingUI()) {
149 UpdateUIState(NOT_ENOUGH_STORAGE); 185 if (should_resume_) {
150 CallJS("setIsResuming", should_resume_); 186 WaitBatteryAndMigrate();
187 } else {
188 UpdateUIState(UIState::READY);
189 }
151 } else { 190 } else {
152 if (should_resume_) { 191 UpdateUIState(UIState::NOT_ENOUGH_STORAGE);
153 // TODO(fukino): Check the battery level.
154 StartMigration();
155 } else {
156 UpdateUIState(READY);
157 }
158 } 192 }
159 } 193 }
160 194
195 void EncryptionMigrationScreenHandler::WaitBatteryAndMigrate() {
196 if (current_battery_percent_ >= kMinimumBatteryPercent) {
197 StartMigration();
198 return;
199 }
200 UpdateUIState(UIState::READY);
201
202 should_migrate_on_enough_battery_ = true;
203 DBusThreadManager::Get()->GetPowerManagerClient()->RequestStatusUpdate();
204 }
205
161 void EncryptionMigrationScreenHandler::StartMigration() { 206 void EncryptionMigrationScreenHandler::StartMigration() {
207 UpdateUIState(UIState::MIGRATING);
208
162 DBusThreadManager::Get() 209 DBusThreadManager::Get()
163 ->GetCryptohomeClient() 210 ->GetCryptohomeClient()
164 ->SetDircryptoMigrationProgressHandler( 211 ->SetDircryptoMigrationProgressHandler(
165 base::Bind(&EncryptionMigrationScreenHandler::OnMigrationProgress, 212 base::Bind(&EncryptionMigrationScreenHandler::OnMigrationProgress,
166 weak_ptr_factory_.GetWeakPtr())); 213 weak_ptr_factory_.GetWeakPtr()));
167 214
168 // |auth_key| is created in the same manner as CryptohomeAuthenticator. 215 // |auth_key| is created in the same manner as CryptohomeAuthenticator.
169 const Key* key = user_context_.GetKey(); 216 const Key* key = user_context_.GetKey();
170 // If the |key| is a plain text password, crash rather than attempting to 217 // If the |key| is a plain text password, crash rather than attempting to
171 // mount the cryptohome with a plain text password. 218 // mount the cryptohome with a plain text password.
172 CHECK_NE(Key::KEY_TYPE_PASSWORD_PLAIN, key->GetKeyType()); 219 CHECK_NE(Key::KEY_TYPE_PASSWORD_PLAIN, key->GetKeyType());
173 // Set the authentication's key label to an empty string, which is a wildcard 220 // Set the authentication's key label to an empty string, which is a wildcard
174 // allowing any key to match. This is necessary because cryptohomes created by 221 // allowing any key to match. This is necessary because cryptohomes created by
175 // Chrome OS M38 and older will have a legacy key with no label while those 222 // Chrome OS M38 and older will have a legacy key with no label while those
176 // created by Chrome OS M39 and newer will have a key with the label 223 // created by Chrome OS M39 and newer will have a key with the label
177 // kCryptohomeGAIAKeyLabel. 224 // kCryptohomeGAIAKeyLabel.
178 const cryptohome::KeyDefinition auth_key(key->GetSecret(), std::string(), 225 const cryptohome::KeyDefinition auth_key(key->GetSecret(), std::string(),
179 cryptohome::PRIV_DEFAULT); 226 cryptohome::PRIV_DEFAULT);
180 cryptohome::HomedirMethods::GetInstance()->MigrateToDircrypto( 227 cryptohome::HomedirMethods::GetInstance()->MigrateToDircrypto(
181 cryptohome::Identification(user_context_.GetAccountId()), 228 cryptohome::Identification(user_context_.GetAccountId()),
182 cryptohome::Authorization(auth_key), 229 cryptohome::Authorization(auth_key),
183 base::Bind(&EncryptionMigrationScreenHandler::OnMigrationRequested, 230 base::Bind(&EncryptionMigrationScreenHandler::OnMigrationRequested,
184 weak_ptr_factory_.GetWeakPtr())); 231 weak_ptr_factory_.GetWeakPtr()));
185 UpdateUIState(UIState::MIGRATING);
186 } 232 }
187 233
188 void EncryptionMigrationScreenHandler::OnMigrationProgress( 234 void EncryptionMigrationScreenHandler::OnMigrationProgress(
189 cryptohome::DircryptoMigrationStatus status, 235 cryptohome::DircryptoMigrationStatus status,
190 uint64_t current, 236 uint64_t current,
191 uint64_t total) { 237 uint64_t total) {
192 switch (status) { 238 switch (status) {
193 case cryptohome::DIRCRYPTO_MIGRATION_INITIALIZING: 239 case cryptohome::DIRCRYPTO_MIGRATION_INITIALIZING:
194 UpdateUIState(UIState::MIGRATING); 240 UpdateUIState(UIState::MIGRATING);
195 break; 241 break;
(...skipping 20 matching lines...) Expand all
216 void EncryptionMigrationScreenHandler::OnMigrationRequested(bool success) { 262 void EncryptionMigrationScreenHandler::OnMigrationRequested(bool success) {
217 // This function is called when MigrateToDircrypto is correctly requested. 263 // This function is called when MigrateToDircrypto is correctly requested.
218 // It does not mean that the migration is completed. We should know the 264 // It does not mean that the migration is completed. We should know the
219 // completion by DircryptoMigrationProgressHandler. success == false means a 265 // completion by DircryptoMigrationProgressHandler. success == false means a
220 // failure in DBus communication. 266 // failure in DBus communication.
221 // TODO(fukino): Handle this case. Should we retry or restart? 267 // TODO(fukino): Handle this case. Should we retry or restart?
222 DCHECK(success); 268 DCHECK(success);
223 } 269 }
224 270
225 } // namespace chromeos 271 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698