OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/chromeos/arc/arc_session_manager.h" | 5 #include "chrome/browser/chromeos/arc/arc_session_manager.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "ash/common/shelf/shelf_delegate.h" | 9 #include "ash/common/shelf/shelf_delegate.h" |
10 #include "ash/common/wm_shell.h" | 10 #include "ash/common/wm_shell.h" |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
103 ArcSessionManager* ArcSessionManager::Get() { | 103 ArcSessionManager* ArcSessionManager::Get() { |
104 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 104 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
105 return g_arc_session_manager; | 105 return g_arc_session_manager; |
106 } | 106 } |
107 | 107 |
108 // static | 108 // static |
109 void ArcSessionManager::RegisterProfilePrefs( | 109 void ArcSessionManager::RegisterProfilePrefs( |
110 user_prefs::PrefRegistrySyncable* registry) { | 110 user_prefs::PrefRegistrySyncable* registry) { |
111 // TODO(dspaid): Implement a mechanism to allow this to sync on first boot | 111 // TODO(dspaid): Implement a mechanism to allow this to sync on first boot |
112 // only. | 112 // only. |
113 registry->RegisterBooleanPref(prefs::kArcDataRemoveRequested, false); | |
113 registry->RegisterBooleanPref(prefs::kArcEnabled, false); | 114 registry->RegisterBooleanPref(prefs::kArcEnabled, false); |
114 registry->RegisterBooleanPref(prefs::kArcSignedIn, false); | 115 registry->RegisterBooleanPref(prefs::kArcSignedIn, false); |
115 registry->RegisterBooleanPref(prefs::kArcTermsAccepted, false); | 116 registry->RegisterBooleanPref(prefs::kArcTermsAccepted, false); |
116 registry->RegisterBooleanPref(prefs::kArcBackupRestoreEnabled, true); | 117 registry->RegisterBooleanPref(prefs::kArcBackupRestoreEnabled, true); |
117 registry->RegisterBooleanPref(prefs::kArcLocationServiceEnabled, true); | 118 registry->RegisterBooleanPref(prefs::kArcLocationServiceEnabled, true); |
118 } | 119 } |
119 | 120 |
120 // static | 121 // static |
121 void ArcSessionManager::DisableUIForTesting() { | 122 void ArcSessionManager::DisableUIForTesting() { |
122 g_disable_ui_for_testing = true; | 123 g_disable_ui_for_testing = true; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 bool ArcSessionManager::IsArcKioskMode() { | 189 bool ArcSessionManager::IsArcKioskMode() { |
189 return user_manager::UserManager::Get()->IsLoggedInAsArcKioskApp(); | 190 return user_manager::UserManager::Get()->IsLoggedInAsArcKioskApp(); |
190 } | 191 } |
191 | 192 |
192 void ArcSessionManager::OnBridgeStopped(ArcBridgeService::StopReason reason) { | 193 void ArcSessionManager::OnBridgeStopped(ArcBridgeService::StopReason reason) { |
193 // TODO(crbug.com/625923): Use |reason| to report more detailed errors. | 194 // TODO(crbug.com/625923): Use |reason| to report more detailed errors. |
194 if (arc_sign_in_timer_.IsRunning()) { | 195 if (arc_sign_in_timer_.IsRunning()) { |
195 OnProvisioningFinished(ProvisioningResult::ARC_STOPPED); | 196 OnProvisioningFinished(ProvisioningResult::ARC_STOPPED); |
196 } | 197 } |
197 | 198 |
198 if (clear_required_) { | 199 if (profile_->GetPrefs()->GetBoolean(prefs::kArcDataRemoveRequested)) { |
199 // This should be always true, but just in case as this is looked at | 200 // This should be always true, but just in case as this is looked at |
200 // inside RemoveArcData() at first. | 201 // inside RemoveArcData() at first. |
201 DCHECK(arc_bridge_service()->stopped()); | 202 DCHECK(arc_bridge_service()->stopped()); |
202 RemoveArcData(); | 203 RemoveArcData(); |
203 } else { | 204 } else { |
204 // To support special "Stop and enable ARC" procedure for enterprise, | 205 // To support special "Stop and enable ARC" procedure for enterprise, |
205 // here call OnArcDataRemoved(true) as if the data removal is successfully | 206 // here call MaybeReenableArc() asyncronously. |
206 // done. | |
207 // TODO(hidehiko): Restructure the code. crbug.com/665316 | 207 // TODO(hidehiko): Restructure the code. crbug.com/665316 |
208 base::ThreadTaskRunnerHandle::Get()->PostTask( | 208 base::ThreadTaskRunnerHandle::Get()->PostTask( |
209 FROM_HERE, base::Bind(&ArcSessionManager::OnArcDataRemoved, | 209 FROM_HERE, base::Bind(&ArcSessionManager::MaybeReenableArc, |
210 weak_ptr_factory_.GetWeakPtr(), true)); | 210 weak_ptr_factory_.GetWeakPtr())); |
211 } | 211 } |
212 } | 212 } |
213 | 213 |
214 void ArcSessionManager::RemoveArcData() { | 214 void ArcSessionManager::RemoveArcData() { |
215 // Ignore redundant data removal request. | |
216 if (state() == State::REMOVING_DATA_DIR) | |
217 return; | |
218 | |
219 // OnArcDataRemoved resets this flag. | |
220 profile_->GetPrefs()->SetBoolean(prefs::kArcDataRemoveRequested, true); | |
221 | |
215 if (!arc_bridge_service()->stopped()) { | 222 if (!arc_bridge_service()->stopped()) { |
216 // Just set a flag. On bridge stopped, this will be re-called, | 223 // Just set a flag. On bridge stopped, this will be re-called, |
217 // then session manager should remove the data. | 224 // then session manager should remove the data. |
218 clear_required_ = true; | |
219 return; | 225 return; |
220 } | 226 } |
221 clear_required_ = false; | 227 |
228 SetState(State::REMOVING_DATA_DIR); | |
222 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->RemoveArcData( | 229 chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->RemoveArcData( |
223 cryptohome::Identification( | 230 cryptohome::Identification( |
224 multi_user_util::GetAccountIdFromProfile(profile_)), | 231 multi_user_util::GetAccountIdFromProfile(profile_)), |
225 base::Bind(&ArcSessionManager::OnArcDataRemoved, | 232 base::Bind(&ArcSessionManager::OnArcDataRemoved, |
226 weak_ptr_factory_.GetWeakPtr())); | 233 weak_ptr_factory_.GetWeakPtr())); |
227 } | 234 } |
228 | 235 |
229 void ArcSessionManager::OnArcDataRemoved(bool success) { | 236 void ArcSessionManager::OnArcDataRemoved(bool success) { |
230 LOG_IF(ERROR, !success) << "Required ARC user data wipe failed."; | 237 LOG_IF(ERROR, !success) << "Required ARC user data wipe failed."; |
231 | 238 |
239 // TODO(khmel): Browser tests may shutdown profile by itself. Update browser | |
240 // tests and remove this check. | |
241 if (state() == State::NOT_INITIALIZED) | |
242 return; | |
243 | |
244 for (auto& observer : observer_list_) | |
245 observer.OnArcDataRemoved(); | |
246 | |
247 profile_->GetPrefs()->SetBoolean(prefs::kArcDataRemoveRequested, false); | |
248 DCHECK_EQ(state(), State::REMOVING_DATA_DIR); | |
249 SetState(State::STOPPED); | |
250 | |
251 MaybeReenableArc(); | |
252 } | |
253 | |
254 void ArcSessionManager::MaybeReenableArc() { | |
232 // Here check if |reenable_arc_| is marked or not. | 255 // Here check if |reenable_arc_| is marked or not. |
233 // The only case this happens should be in the special case for enterprise | 256 // The only case this happens should be in the special case for enterprise |
234 // "on managed lost" case. In that case, OnBridgeStopped() should trigger | 257 // "on managed lost" case. In that case, OnBridgeStopped() should trigger |
235 // the RemoveArcData(), then this. | 258 // the RemoveArcData(), then this. |
236 // TODO(hidehiko): Restructure the code. | 259 if (!reenable_arc_ || !IsArcEnabled()) |
237 if (!reenable_arc_) | |
238 return; | 260 return; |
239 | 261 |
240 // Restart ARC anyway. Let the enterprise reporting instance decide whether | 262 // Restart ARC anyway. Let the enterprise reporting instance decide whether |
241 // the ARC user data wipe is still required or not. | 263 // the ARC user data wipe is still required or not. |
242 reenable_arc_ = false; | 264 reenable_arc_ = false; |
243 VLOG(1) << "Reenable ARC"; | 265 VLOG(1) << "Reenable ARC"; |
244 EnableArc(); | 266 EnableArc(); |
245 } | 267 } |
246 | 268 |
247 void ArcSessionManager::OnProvisioningFinished(ProvisioningResult result) { | 269 void ArcSessionManager::OnProvisioningFinished(ProvisioningResult result) { |
248 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 270 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
249 DCHECK_EQ(state_, State::ACTIVE); | 271 |
272 // Due asynchronous nature of stopping Arc bridge, OnProvisioningFinished may | |
hidehiko
2016/12/06 18:32:10
Nice commenting!
| |
273 // arrive after setting the |State::STOPPED| state and |State::Active| is not | |
274 // guaranty set here. prefs::kArcDataRemoveRequested is also can be active | |
275 // for now. | |
250 | 276 |
251 if (result == ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR) { | 277 if (result == ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR) { |
252 if (IsArcKioskMode()) { | 278 if (IsArcKioskMode()) { |
253 VLOG(1) << "Robot account auth code fetching error"; | 279 VLOG(1) << "Robot account auth code fetching error"; |
254 // Log out the user. All the cleanup will be done in Shutdown() method. | 280 // Log out the user. All the cleanup will be done in Shutdown() method. |
255 // The callback is not called because auth code is empty. | 281 // The callback is not called because auth code is empty. |
256 chrome::AttemptUserExit(); | 282 chrome::AttemptUserExit(); |
257 return; | 283 return; |
258 } | 284 } |
259 | 285 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
405 if (!g_disable_ui_for_testing || | 431 if (!g_disable_ui_for_testing || |
406 g_enable_check_android_management_for_testing) { | 432 g_enable_check_android_management_for_testing) { |
407 ArcAndroidManagementChecker::StartClient(); | 433 ArcAndroidManagementChecker::StartClient(); |
408 } | 434 } |
409 pref_change_registrar_.Init(profile_->GetPrefs()); | 435 pref_change_registrar_.Init(profile_->GetPrefs()); |
410 pref_change_registrar_.Add( | 436 pref_change_registrar_.Add( |
411 prefs::kArcEnabled, | 437 prefs::kArcEnabled, |
412 base::Bind(&ArcSessionManager::OnOptInPreferenceChanged, | 438 base::Bind(&ArcSessionManager::OnOptInPreferenceChanged, |
413 weak_ptr_factory_.GetWeakPtr())); | 439 weak_ptr_factory_.GetWeakPtr())); |
414 if (profile_->GetPrefs()->GetBoolean(prefs::kArcEnabled)) { | 440 if (profile_->GetPrefs()->GetBoolean(prefs::kArcEnabled)) { |
415 OnOptInPreferenceChanged(); | 441 // Don't start ARC if there is a pending request to remove the data. Restart |
442 // ARC once data removal finishes. | |
443 if (profile_->GetPrefs()->GetBoolean(prefs::kArcDataRemoveRequested)) { | |
444 reenable_arc_ = true; | |
445 RemoveArcData(); | |
446 } else { | |
447 OnOptInPreferenceChanged(); | |
448 } | |
416 } else { | 449 } else { |
417 RemoveArcData(); | 450 RemoveArcData(); |
418 PrefServiceSyncableFromProfile(profile_)->AddObserver(this); | 451 PrefServiceSyncableFromProfile(profile_)->AddObserver(this); |
419 OnIsSyncingChanged(); | 452 OnIsSyncingChanged(); |
420 } | 453 } |
421 } | 454 } |
422 | 455 |
423 void ArcSessionManager::OnIsSyncingChanged() { | 456 void ArcSessionManager::OnIsSyncingChanged() { |
424 sync_preferences::PrefServiceSyncable* const pref_service_syncable = | 457 sync_preferences::PrefServiceSyncable* const pref_service_syncable = |
425 PrefServiceSyncableFromProfile(profile_); | 458 PrefServiceSyncableFromProfile(profile_); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
485 DCHECK(profile_); | 518 DCHECK(profile_); |
486 | 519 |
487 // TODO(dspaid): Move code from OnSyncedPrefChanged into this method. | 520 // TODO(dspaid): Move code from OnSyncedPrefChanged into this method. |
488 OnSyncedPrefChanged(prefs::kArcEnabled, IsArcManaged()); | 521 OnSyncedPrefChanged(prefs::kArcEnabled, IsArcManaged()); |
489 | 522 |
490 const bool arc_enabled = IsArcEnabled(); | 523 const bool arc_enabled = IsArcEnabled(); |
491 for (auto& observer : observer_list_) | 524 for (auto& observer : observer_list_) |
492 observer.OnOptInEnabled(arc_enabled); | 525 observer.OnOptInEnabled(arc_enabled); |
493 | 526 |
494 if (!arc_enabled) { | 527 if (!arc_enabled) { |
528 // Reset any pending request to re-enable Arc. | |
529 reenable_arc_ = false; | |
495 StopArc(); | 530 StopArc(); |
496 RemoveArcData(); | 531 RemoveArcData(); |
497 return; | 532 return; |
498 } | 533 } |
499 | 534 |
500 if (state_ == State::ACTIVE) | 535 if (state_ == State::ACTIVE) |
501 return; | 536 return; |
502 | 537 |
538 if (state_ == State::REMOVING_DATA_DIR) { | |
539 // Data removal request is in progress. Set flag to re-enable Arc once it is | |
540 // finished. | |
541 reenable_arc_ = true; | |
542 return; | |
543 } | |
544 | |
503 if (support_host_) | 545 if (support_host_) |
504 support_host_->SetArcManaged(IsArcManaged()); | 546 support_host_->SetArcManaged(IsArcManaged()); |
505 | 547 |
506 // For ARC Kiosk we skip ToS because it is very likely that near the device | 548 // For ARC Kiosk we skip ToS because it is very likely that near the device |
507 // there will be no one who is eligible to accept them. | 549 // there will be no one who is eligible to accept them. |
508 // TODO(poromov): Move to more Kiosk dedicated set-up phase. | 550 // TODO(poromov): Move to more Kiosk dedicated set-up phase. |
509 if (IsArcKioskMode()) | 551 if (IsArcKioskMode()) |
510 profile_->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true); | 552 profile_->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true); |
511 | 553 |
512 // If it is marked that sign in has been successfully done, then directly | 554 // If it is marked that sign in has been successfully done, then directly |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
557 // Need user's explicit Terms Of Service agreement. | 599 // Need user's explicit Terms Of Service agreement. |
558 StartTermsOfServiceNegotiation(); | 600 StartTermsOfServiceNegotiation(); |
559 } | 601 } |
560 | 602 |
561 void ArcSessionManager::ShutdownBridge() { | 603 void ArcSessionManager::ShutdownBridge() { |
562 arc_sign_in_timer_.Stop(); | 604 arc_sign_in_timer_.Stop(); |
563 playstore_launcher_.reset(); | 605 playstore_launcher_.reset(); |
564 terms_of_service_negotiator_.reset(); | 606 terms_of_service_negotiator_.reset(); |
565 android_management_checker_.reset(); | 607 android_management_checker_.reset(); |
566 arc_bridge_service()->RequestStop(); | 608 arc_bridge_service()->RequestStop(); |
567 if (state_ != State::NOT_INITIALIZED) | 609 if (state_ != State::NOT_INITIALIZED && state_ != State::REMOVING_DATA_DIR) |
568 SetState(State::STOPPED); | 610 SetState(State::STOPPED); |
569 for (auto& observer : observer_list_) | 611 for (auto& observer : observer_list_) |
570 observer.OnShutdownBridge(); | 612 observer.OnShutdownBridge(); |
571 } | 613 } |
572 | 614 |
573 void ArcSessionManager::AddObserver(Observer* observer) { | 615 void ArcSessionManager::AddObserver(Observer* observer) { |
574 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 616 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
575 observer_list_.AddObserver(observer); | 617 observer_list_.AddObserver(observer); |
576 } | 618 } |
577 | 619 |
578 void ArcSessionManager::RemoveObserver(Observer* observer) { | 620 void ArcSessionManager::RemoveObserver(Observer* observer) { |
579 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 621 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
580 observer_list_.RemoveObserver(observer); | 622 observer_list_.RemoveObserver(observer); |
581 } | 623 } |
582 | 624 |
583 // This is the special method to support enterprise mojo API. | 625 // This is the special method to support enterprise mojo API. |
584 // TODO(hidehiko): Remove this. | 626 // TODO(hidehiko): Remove this. |
585 void ArcSessionManager::StopAndEnableArc() { | 627 void ArcSessionManager::StopAndEnableArc() { |
586 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 628 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
587 DCHECK(!arc_bridge_service()->stopped()); | 629 DCHECK(!arc_bridge_service()->stopped()); |
588 reenable_arc_ = true; | 630 reenable_arc_ = true; |
589 StopArc(); | 631 StopArc(); |
590 } | 632 } |
591 | 633 |
592 void ArcSessionManager::StartArc() { | 634 void ArcSessionManager::StartArc() { |
593 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 635 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
636 | |
637 // Arc must be started only if no pending data removal request exists. | |
638 DCHECK(!profile_->GetPrefs()->GetBoolean(prefs::kArcDataRemoveRequested)); | |
639 | |
594 arc_bridge_service()->RequestStart(); | 640 arc_bridge_service()->RequestStart(); |
595 SetState(State::ACTIVE); | 641 SetState(State::ACTIVE); |
596 } | 642 } |
597 | 643 |
598 void ArcSessionManager::OnArcSignInTimeout() { | 644 void ArcSessionManager::OnArcSignInTimeout() { |
599 LOG(ERROR) << "Timed out waiting for first sign in."; | 645 LOG(ERROR) << "Timed out waiting for first sign in."; |
600 OnProvisioningFinished(ProvisioningResult::OVERALL_SIGN_IN_TIMEOUT); | 646 OnProvisioningFinished(ProvisioningResult::OVERALL_SIGN_IN_TIMEOUT); |
601 } | 647 } |
602 | 648 |
603 void ArcSessionManager::CancelAuthCode() { | 649 void ArcSessionManager::CancelAuthCode() { |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
842 const ArcSessionManager::State& state) { | 888 const ArcSessionManager::State& state) { |
843 switch (state) { | 889 switch (state) { |
844 case ArcSessionManager::State::NOT_INITIALIZED: | 890 case ArcSessionManager::State::NOT_INITIALIZED: |
845 return os << "NOT_INITIALIZED"; | 891 return os << "NOT_INITIALIZED"; |
846 case ArcSessionManager::State::STOPPED: | 892 case ArcSessionManager::State::STOPPED: |
847 return os << "STOPPED"; | 893 return os << "STOPPED"; |
848 case ArcSessionManager::State::SHOWING_TERMS_OF_SERVICE: | 894 case ArcSessionManager::State::SHOWING_TERMS_OF_SERVICE: |
849 return os << "SHOWING_TERMS_OF_SERVICE"; | 895 return os << "SHOWING_TERMS_OF_SERVICE"; |
850 case ArcSessionManager::State::CHECKING_ANDROID_MANAGEMENT: | 896 case ArcSessionManager::State::CHECKING_ANDROID_MANAGEMENT: |
851 return os << "CHECKING_ANDROID_MANAGEMENT"; | 897 return os << "CHECKING_ANDROID_MANAGEMENT"; |
898 case ArcSessionManager::State::REMOVING_DATA_DIR: | |
899 return os << "REMOVING_DATA_DIR"; | |
852 case ArcSessionManager::State::ACTIVE: | 900 case ArcSessionManager::State::ACTIVE: |
853 return os << "ACTIVE"; | 901 return os << "ACTIVE"; |
854 } | 902 } |
855 | 903 |
856 // Some compiler reports an error even if all values of an enum-class are | 904 // Some compiler reports an error even if all values of an enum-class are |
857 // covered indivisually in a switch statement. | 905 // covered indivisually in a switch statement. |
858 NOTREACHED(); | 906 NOTREACHED(); |
859 return os; | 907 return os; |
860 } | 908 } |
861 | 909 |
862 } // namespace arc | 910 } // namespace arc |
OLD | NEW |