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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 support_host->ui_page() == ArcSupportHost::UIPage::NO_PAGE || | 70 support_host->ui_page() == ArcSupportHost::UIPage::NO_PAGE || |
71 support_host->ui_page() == ArcSupportHost::UIPage::ERROR) { | 71 support_host->ui_page() == ArcSupportHost::UIPage::ERROR) { |
72 return; | 72 return; |
73 } | 73 } |
74 | 74 |
75 UpdateOptInCancelUMA(OptInCancelReason::USER_CANCEL); | 75 UpdateOptInCancelUMA(OptInCancelReason::USER_CANCEL); |
76 } | 76 } |
77 | 77 |
78 } // namespace | 78 } // namespace |
79 | 79 |
| 80 // This class is used to track statuses on OptIn flow. It is created in case ARC |
| 81 // is activated, and it needs to OptIn. Once started OptInFlowResult::STARTED is |
| 82 // recorded via UMA. If it finishes successfully OptInFlowResult::SUCCEEDED is |
| 83 // recorded. Optional OptInFlowResult::SUCCEEDED_AFTER_RETRY is recorded in this |
| 84 // case if an error occurred during OptIn flow, and user pressed Retry. In case |
| 85 // the user cancels OptIn flow before it was completed then |
| 86 // OptInFlowResult::CANCELED is recorded and if an error occurred optional |
| 87 // OptInFlowResult::CANCELED_AFTER_ERROR. If a shutdown happens during the OptIn |
| 88 // nothing is recorded, except initial OptInFlowResult::STARTED. |
| 89 // OptInFlowResult::STARTED = OptInFlowResult::SUCCEEDED + |
| 90 // OptInFlowResult::CANCELED + cases happened during the shutdown. |
| 91 class ArcSessionManager::ScopedOptInFlowTracker { |
| 92 public: |
| 93 ScopedOptInFlowTracker() { |
| 94 UpdateOptInFlowResultUMA(OptInFlowResult::STARTED); |
| 95 } |
| 96 |
| 97 ~ScopedOptInFlowTracker() { |
| 98 if (shutdown_) |
| 99 return; |
| 100 |
| 101 UpdateOptInFlowResultUMA(success_ ? OptInFlowResult::SUCCEEDED |
| 102 : OptInFlowResult::CANCELED); |
| 103 if (error_) { |
| 104 UpdateOptInFlowResultUMA(success_ |
| 105 ? OptInFlowResult::SUCCEEDED_AFTER_RETRY |
| 106 : OptInFlowResult::CANCELED_AFTER_ERROR); |
| 107 } |
| 108 } |
| 109 |
| 110 // Tracks error occurred during the OptIn flow. |
| 111 void TrackError() { |
| 112 DCHECK(!success_ && !shutdown_); |
| 113 error_ = true; |
| 114 } |
| 115 |
| 116 // Tracks that OptIn finished successfully. |
| 117 void TrackSuccess() { |
| 118 DCHECK(!success_ && !shutdown_); |
| 119 success_ = true; |
| 120 } |
| 121 |
| 122 // Tracks that OptIn was not completed before shutdown. |
| 123 void TrackShutdown() { |
| 124 DCHECK(!success_ && !shutdown_); |
| 125 shutdown_ = true; |
| 126 } |
| 127 |
| 128 private: |
| 129 bool error_ = false; |
| 130 bool success_ = false; |
| 131 bool shutdown_ = false; |
| 132 |
| 133 DISALLOW_COPY_AND_ASSIGN(ScopedOptInFlowTracker); |
| 134 }; |
| 135 |
80 ArcSessionManager::ArcSessionManager( | 136 ArcSessionManager::ArcSessionManager( |
81 std::unique_ptr<ArcSessionRunner> arc_session_runner) | 137 std::unique_ptr<ArcSessionRunner> arc_session_runner) |
82 : arc_session_runner_(std::move(arc_session_runner)), | 138 : arc_session_runner_(std::move(arc_session_runner)), |
83 attempt_user_exit_callback_(base::Bind(chrome::AttemptUserExit)), | 139 attempt_user_exit_callback_(base::Bind(chrome::AttemptUserExit)), |
84 weak_ptr_factory_(this) { | 140 weak_ptr_factory_(this) { |
85 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 141 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
86 DCHECK(!g_arc_session_manager); | 142 DCHECK(!g_arc_session_manager); |
87 g_arc_session_manager = this; | 143 g_arc_session_manager = this; |
88 arc_session_runner_->AddObserver(this); | 144 arc_session_runner_->AddObserver(this); |
89 } | 145 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 // We don't expect ProvisioningResult::SUCCESS is reported twice or reported | 260 // We don't expect ProvisioningResult::SUCCESS is reported twice or reported |
205 // after an error. | 261 // after an error. |
206 DCHECK_NE(result, ProvisioningResult::SUCCESS); | 262 DCHECK_NE(result, ProvisioningResult::SUCCESS); |
207 // TODO(khmel): Consider changing LOG to NOTREACHED once we guaranty that | 263 // TODO(khmel): Consider changing LOG to NOTREACHED once we guaranty that |
208 // no double message can happen in production. | 264 // no double message can happen in production. |
209 LOG(WARNING) << "Provisioning result was already reported. Ignoring " | 265 LOG(WARNING) << "Provisioning result was already reported. Ignoring " |
210 << "additional result " << static_cast<int>(result) << "."; | 266 << "additional result " << static_cast<int>(result) << "."; |
211 return; | 267 return; |
212 } | 268 } |
213 provisioning_reported_ = true; | 269 provisioning_reported_ = true; |
| 270 if (scoped_opt_in_tracker_ && result != ProvisioningResult::SUCCESS) |
| 271 scoped_opt_in_tracker_->TrackError(); |
214 | 272 |
215 if (result == ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR) { | 273 if (result == ProvisioningResult::CHROME_SERVER_COMMUNICATION_ERROR) { |
216 if (IsArcKioskMode()) { | 274 if (IsArcKioskMode()) { |
217 VLOG(1) << "Robot account auth code fetching error"; | 275 VLOG(1) << "Robot account auth code fetching error"; |
218 // Log out the user. All the cleanup will be done in Shutdown() method. | 276 // Log out the user. All the cleanup will be done in Shutdown() method. |
219 // The callback is not called because auth code is empty. | 277 // The callback is not called because auth code is empty. |
220 attempt_user_exit_callback_.Run(); | 278 attempt_user_exit_callback_.Run(); |
221 return; | 279 return; |
222 } | 280 } |
223 | 281 |
224 // For backwards compatibility, use NETWORK_ERROR for | 282 // For backwards compatibility, use NETWORK_ERROR for |
225 // CHROME_SERVER_COMMUNICATION_ERROR case. | 283 // CHROME_SERVER_COMMUNICATION_ERROR case. |
226 UpdateOptInCancelUMA(OptInCancelReason::NETWORK_ERROR); | 284 UpdateOptInCancelUMA(OptInCancelReason::NETWORK_ERROR); |
227 } else if (!sign_in_start_time_.is_null()) { | 285 } else if (!sign_in_start_time_.is_null()) { |
228 arc_sign_in_timer_.Stop(); | 286 arc_sign_in_timer_.Stop(); |
229 | 287 |
230 UpdateProvisioningTiming(base::Time::Now() - sign_in_start_time_, | 288 UpdateProvisioningTiming(base::Time::Now() - sign_in_start_time_, |
231 result == ProvisioningResult::SUCCESS, | 289 result == ProvisioningResult::SUCCESS, |
232 policy_util::IsAccountManaged(profile_)); | 290 policy_util::IsAccountManaged(profile_)); |
233 UpdateProvisioningResultUMA(result, | 291 UpdateProvisioningResultUMA(result, |
234 policy_util::IsAccountManaged(profile_)); | 292 policy_util::IsAccountManaged(profile_)); |
235 if (result != ProvisioningResult::SUCCESS) | 293 if (result != ProvisioningResult::SUCCESS) |
236 UpdateOptInCancelUMA(OptInCancelReason::CLOUD_PROVISION_FLOW_FAIL); | 294 UpdateOptInCancelUMA(OptInCancelReason::CLOUD_PROVISION_FLOW_FAIL); |
237 } | 295 } |
238 | 296 |
239 if (result == ProvisioningResult::SUCCESS) { | 297 if (result == ProvisioningResult::SUCCESS) { |
240 if (support_host_) | 298 if (support_host_) |
241 support_host_->Close(); | 299 support_host_->Close(); |
242 | 300 |
| 301 if (scoped_opt_in_tracker_) { |
| 302 scoped_opt_in_tracker_->TrackSuccess(); |
| 303 scoped_opt_in_tracker_.reset(); |
| 304 } |
| 305 |
243 if (profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn)) | 306 if (profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn)) |
244 return; | 307 return; |
245 | 308 |
246 profile_->GetPrefs()->SetBoolean(prefs::kArcSignedIn, true); | 309 profile_->GetPrefs()->SetBoolean(prefs::kArcSignedIn, true); |
247 | 310 |
248 // Launch Play Store app, except for the following cases: | 311 // Launch Play Store app, except for the following cases: |
249 // * When Opt-in verification is disabled (for tests); | 312 // * When Opt-in verification is disabled (for tests); |
250 // * In ARC Kiosk mode, because the only one UI in kiosk mode must be the | 313 // * In ARC Kiosk mode, because the only one UI in kiosk mode must be the |
251 // kiosk app and device is not needed for opt-in; | 314 // kiosk app and device is not needed for opt-in; |
252 // * When ARC is managed and all OptIn preferences are managed too, because | 315 // * When ARC is managed and all OptIn preferences are managed too, because |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 enable_requested_ = false; | 452 enable_requested_ = false; |
390 ShutdownSession(); | 453 ShutdownSession(); |
391 if (support_host_) { | 454 if (support_host_) { |
392 support_host_->Close(); | 455 support_host_->Close(); |
393 support_host_->RemoveObserver(this); | 456 support_host_->RemoveObserver(this); |
394 support_host_.reset(); | 457 support_host_.reset(); |
395 } | 458 } |
396 context_.reset(); | 459 context_.reset(); |
397 profile_ = nullptr; | 460 profile_ = nullptr; |
398 SetState(State::NOT_INITIALIZED); | 461 SetState(State::NOT_INITIALIZED); |
| 462 if (scoped_opt_in_tracker_) { |
| 463 scoped_opt_in_tracker_->TrackShutdown(); |
| 464 scoped_opt_in_tracker_.reset(); |
| 465 } |
399 } | 466 } |
400 | 467 |
401 void ArcSessionManager::ShutdownSession() { | 468 void ArcSessionManager::ShutdownSession() { |
402 arc_sign_in_timer_.Stop(); | 469 arc_sign_in_timer_.Stop(); |
403 playstore_launcher_.reset(); | 470 playstore_launcher_.reset(); |
404 terms_of_service_negotiator_.reset(); | 471 terms_of_service_negotiator_.reset(); |
405 android_management_checker_.reset(); | 472 android_management_checker_.reset(); |
406 arc_session_runner_->RequestStop(); | 473 arc_session_runner_->RequestStop(); |
407 // TODO(hidehiko): The ARC instance's stopping is asynchronous, so it might | 474 // TODO(hidehiko): The ARC instance's stopping is asynchronous, so it might |
408 // still be running when we return from this function. Do not set the | 475 // still be running when we return from this function. Do not set the |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 | 608 |
542 void ArcSessionManager::RequestDisable() { | 609 void ArcSessionManager::RequestDisable() { |
543 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 610 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
544 DCHECK(profile_); | 611 DCHECK(profile_); |
545 | 612 |
546 if (!enable_requested_) { | 613 if (!enable_requested_) { |
547 VLOG(1) << "ARC is already disabled. Do nothing."; | 614 VLOG(1) << "ARC is already disabled. Do nothing."; |
548 return; | 615 return; |
549 } | 616 } |
550 enable_requested_ = false; | 617 enable_requested_ = false; |
| 618 scoped_opt_in_tracker_.reset(); |
551 | 619 |
552 // Reset any pending request to re-enable ARC. | 620 // Reset any pending request to re-enable ARC. |
553 reenable_arc_ = false; | 621 reenable_arc_ = false; |
554 StopArc(); | 622 StopArc(); |
555 VLOG(1) << "ARC opt-out. Removing user data."; | 623 VLOG(1) << "ARC opt-out. Removing user data."; |
556 RequestArcDataRemoval(); | 624 RequestArcDataRemoval(); |
557 } | 625 } |
558 | 626 |
559 void ArcSessionManager::RequestArcDataRemoval() { | 627 void ArcSessionManager::RequestArcDataRemoval() { |
560 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 628 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 | 663 |
596 // TODO(hidehiko): Remove this condition, when the state machine is fixed. | 664 // TODO(hidehiko): Remove this condition, when the state machine is fixed. |
597 if (!arc_session_runner_->IsStopped()) { | 665 if (!arc_session_runner_->IsStopped()) { |
598 // If the user attempts to re-enable ARC while the ARC instance is still | 666 // If the user attempts to re-enable ARC while the ARC instance is still |
599 // running the user should not be able to continue until the ARC instance | 667 // running the user should not be able to continue until the ARC instance |
600 // has stopped. | 668 // has stopped. |
601 if (support_host_) { | 669 if (support_host_) { |
602 support_host_->ShowError( | 670 support_host_->ShowError( |
603 ArcSupportHost::Error::SIGN_IN_SERVICE_UNAVAILABLE_ERROR, false); | 671 ArcSupportHost::Error::SIGN_IN_SERVICE_UNAVAILABLE_ERROR, false); |
604 } | 672 } |
| 673 UpdateOptInCancelUMA(OptInCancelReason::SESSION_BUSY); |
605 return; | 674 return; |
606 } | 675 } |
607 | 676 |
608 // TODO(hidehiko): DCHECK if |state_| is STOPPED, when the state machine | 677 // TODO(hidehiko): DCHECK if |state_| is STOPPED, when the state machine |
609 // is fixed. | 678 // is fixed. |
610 SetState(State::NEGOTIATING_TERMS_OF_SERVICE); | 679 SetState(State::NEGOTIATING_TERMS_OF_SERVICE); |
611 | 680 |
| 681 if (!scoped_opt_in_tracker_ && |
| 682 !profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn)) { |
| 683 scoped_opt_in_tracker_ = base::MakeUnique<ScopedOptInFlowTracker>(); |
| 684 } |
| 685 |
612 if (!IsArcTermsOfServiceNegotiationNeeded()) { | 686 if (!IsArcTermsOfServiceNegotiationNeeded()) { |
613 // Moves to next state, Android management check, immediately, as if | 687 // Moves to next state, Android management check, immediately, as if |
614 // Terms of Service negotiation is done successfully. | 688 // Terms of Service negotiation is done successfully. |
615 StartAndroidManagementCheck(); | 689 StartAndroidManagementCheck(); |
616 return; | 690 return; |
617 } | 691 } |
618 | 692 |
619 if (IsOobeOptInActive()) { | 693 if (IsOobeOptInActive()) { |
620 VLOG(1) << "Use OOBE negotiator."; | 694 VLOG(1) << "Use OOBE negotiator."; |
621 terms_of_service_negotiator_ = | 695 terms_of_service_negotiator_ = |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
973 | 1047 |
974 #undef MAP_STATE | 1048 #undef MAP_STATE |
975 | 1049 |
976 // Some compilers report an error even if all values of an enum-class are | 1050 // Some compilers report an error even if all values of an enum-class are |
977 // covered exhaustively in a switch statement. | 1051 // covered exhaustively in a switch statement. |
978 NOTREACHED() << "Invalid value " << static_cast<int>(state); | 1052 NOTREACHED() << "Invalid value " << static_cast<int>(state); |
979 return os; | 1053 return os; |
980 } | 1054 } |
981 | 1055 |
982 } // namespace arc | 1056 } // namespace arc |
OLD | NEW |