Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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_auth_service.h" | 5 #include "chrome/browser/chromeos/arc/arc_auth_service.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" |
| 11 #include "base/auto_reset.h" | 11 #include "base/auto_reset.h" |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/strings/string16.h" | 15 #include "base/strings/string16.h" |
| 16 #include "base/time/time.h" | |
| 16 #include "chrome/browser/chromeos/arc/arc_android_management_checker.h" | 17 #include "chrome/browser/chromeos/arc/arc_android_management_checker.h" |
| 17 #include "chrome/browser/chromeos/arc/arc_auth_code_fetcher.h" | 18 #include "chrome/browser/chromeos/arc/arc_auth_code_fetcher.h" |
| 18 #include "chrome/browser/chromeos/arc/arc_auth_context.h" | 19 #include "chrome/browser/chromeos/arc/arc_auth_context.h" |
| 19 #include "chrome/browser/chromeos/arc/arc_auth_notification.h" | 20 #include "chrome/browser/chromeos/arc/arc_auth_notification.h" |
| 20 #include "chrome/browser/chromeos/arc/arc_optin_uma.h" | 21 #include "chrome/browser/chromeos/arc/arc_optin_uma.h" |
| 21 #include "chrome/browser/chromeos/arc/arc_support_host.h" | 22 #include "chrome/browser/chromeos/arc/arc_support_host.h" |
| 22 #include "chrome/browser/chromeos/profiles/profile_helper.h" | 23 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
| 23 #include "chrome/browser/extensions/extension_util.h" | 24 #include "chrome/browser/extensions/extension_util.h" |
| 24 #include "chrome/browser/policy/profile_policy_connector.h" | 25 #include "chrome/browser/policy/profile_policy_connector.h" |
| 25 #include "chrome/browser/policy/profile_policy_connector_factory.h" | 26 #include "chrome/browser/policy/profile_policy_connector_factory.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 58 // Skip creating UI in unit tests | 59 // Skip creating UI in unit tests |
| 59 bool g_disable_ui_for_testing = false; | 60 bool g_disable_ui_for_testing = false; |
| 60 | 61 |
| 61 // Use specified ash::ShelfDelegate for unit tests. | 62 // Use specified ash::ShelfDelegate for unit tests. |
| 62 ash::ShelfDelegate* g_shelf_delegate_for_testing = nullptr; | 63 ash::ShelfDelegate* g_shelf_delegate_for_testing = nullptr; |
| 63 | 64 |
| 64 // The Android management check is disabled by default, it's used only for | 65 // The Android management check is disabled by default, it's used only for |
| 65 // testing. | 66 // testing. |
| 66 bool g_enable_check_android_management_for_testing = false; | 67 bool g_enable_check_android_management_for_testing = false; |
| 67 | 68 |
| 69 // Maximum amount of time we'll wait for ARC to finish booting up. Once this | |
| 70 // timeout expires, keep ARC running in case the user wants to file feedback, | |
| 71 // but present the UI to try again. | |
| 72 constexpr base::TimeDelta kArcSignInTimeout = base::TimeDelta::FromMinutes(5); | |
| 73 | |
| 68 const char kStateNotInitialized[] = "NOT_INITIALIZED"; | 74 const char kStateNotInitialized[] = "NOT_INITIALIZED"; |
| 69 const char kStateStopped[] = "STOPPED"; | 75 const char kStateStopped[] = "STOPPED"; |
| 70 const char kStateFetchingCode[] = "FETCHING_CODE"; | 76 const char kStateFetchingCode[] = "FETCHING_CODE"; |
| 71 const char kStateActive[] = "ACTIVE"; | 77 const char kStateActive[] = "ACTIVE"; |
| 72 | 78 |
| 73 bool IsAccountManaged(Profile* profile) { | 79 bool IsAccountManaged(Profile* profile) { |
| 74 return policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile) | 80 return policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile) |
| 75 ->IsManaged(); | 81 ->IsManaged(); |
| 76 } | 82 } |
| 77 | 83 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 return true; | 228 return true; |
| 223 } | 229 } |
| 224 | 230 |
| 225 void ArcAuthService::OnInstanceReady() { | 231 void ArcAuthService::OnInstanceReady() { |
| 226 arc_bridge_service()->auth()->instance()->Init( | 232 arc_bridge_service()->auth()->instance()->Init( |
| 227 binding_.CreateInterfacePtrAndBind()); | 233 binding_.CreateInterfacePtrAndBind()); |
| 228 } | 234 } |
| 229 | 235 |
| 230 void ArcAuthService::OnBridgeStopped(ArcBridgeService::StopReason reason) { | 236 void ArcAuthService::OnBridgeStopped(ArcBridgeService::StopReason reason) { |
| 231 // TODO(crbug.com/625923): Use |reason| to report more detailed errors. | 237 // TODO(crbug.com/625923): Use |reason| to report more detailed errors. |
| 232 if (waiting_for_reply_) { | 238 if (arc_sign_in_timer_.IsRunning()) { |
| 239 arc_sign_in_timer_.Stop(); | |
|
hidehiko
2016/09/09 02:31:48
nit/optional: this looks redundant, because this i
Luis Héctor Chávez
2016/09/09 03:16:59
Done. I also deleted the comment below now that I'
| |
| 233 // Using SERVICE_UNAVAILABLE instead of UNKNOWN_ERROR, since the latter | 240 // Using SERVICE_UNAVAILABLE instead of UNKNOWN_ERROR, since the latter |
| 234 // causes this code to not try to stop ARC, so it would retry without the | 241 // causes this code to not try to stop ARC, so it would retry without the |
| 235 // user noticing. | 242 // user noticing. |
| 236 OnSignInFailedInternal(ProvisioningResult::ARC_STOPPED); | 243 OnSignInFailedInternal(ProvisioningResult::ARC_STOPPED); |
| 237 } | 244 } |
| 238 | 245 |
| 239 if (clear_required_) { | 246 if (clear_required_) { |
| 240 // This should be always true, but just in case as this is looked at | 247 // This should be always true, but just in case as this is looked at |
| 241 // inside RemoveArcData() at first. | 248 // inside RemoveArcData() at first. |
| 242 DCHECK(arc_bridge_service()->stopped()); | 249 DCHECK(arc_bridge_service()->stopped()); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 310 initial_opt_in_ = false; | 317 initial_opt_in_ = false; |
| 311 auth_callback_ = callback; | 318 auth_callback_ = callback; |
| 312 StartUI(); | 319 StartUI(); |
| 313 } | 320 } |
| 314 | 321 |
| 315 void ArcAuthService::OnSignInComplete() { | 322 void ArcAuthService::OnSignInComplete() { |
| 316 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 323 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 317 DCHECK_EQ(state_, State::ACTIVE); | 324 DCHECK_EQ(state_, State::ACTIVE); |
| 318 DCHECK(!sign_in_time_.is_null()); | 325 DCHECK(!sign_in_time_.is_null()); |
| 319 | 326 |
| 320 waiting_for_reply_ = false; | 327 arc_sign_in_timer_.Stop(); |
| 321 | 328 |
| 322 if (!IsOptInVerificationDisabled() && | 329 if (!IsOptInVerificationDisabled() && |
| 323 !profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn)) { | 330 !profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn)) { |
| 324 playstore_launcher_.reset( | 331 playstore_launcher_.reset( |
| 325 new ArcAppLauncher(profile_, kPlayStoreAppId, true)); | 332 new ArcAppLauncher(profile_, kPlayStoreAppId, true)); |
| 326 } | 333 } |
| 327 | 334 |
| 328 profile_->GetPrefs()->SetBoolean(prefs::kArcSignedIn, true); | 335 profile_->GetPrefs()->SetBoolean(prefs::kArcSignedIn, true); |
| 329 CloseUI(); | 336 CloseUI(); |
| 330 UpdateProvisioningTiming(base::Time::Now() - sign_in_time_, true, | 337 UpdateProvisioningTiming(base::Time::Now() - sign_in_time_, true, |
| 331 IsAccountManaged(profile_)); | 338 IsAccountManaged(profile_)); |
| 332 UpdateProvisioningResultUMA(ProvisioningResult::SUCCESS); | 339 UpdateProvisioningResultUMA(ProvisioningResult::SUCCESS); |
| 333 | 340 |
| 334 FOR_EACH_OBSERVER(Observer, observer_list_, OnInitialStart()); | 341 FOR_EACH_OBSERVER(Observer, observer_list_, OnInitialStart()); |
| 335 } | 342 } |
| 336 | 343 |
| 337 void ArcAuthService::OnSignInFailed(arc::mojom::ArcSignInFailureReason reason) { | 344 void ArcAuthService::OnSignInFailed(arc::mojom::ArcSignInFailureReason reason) { |
| 338 OnSignInFailedInternal( | 345 OnSignInFailedInternal( |
| 339 ConvertArcSignInFailureReasonToProvisioningResult(reason)); | 346 ConvertArcSignInFailureReasonToProvisioningResult(reason)); |
| 340 } | 347 } |
| 341 | 348 |
| 342 void ArcAuthService::OnSignInFailedInternal(ProvisioningResult result) { | 349 void ArcAuthService::OnSignInFailedInternal(ProvisioningResult result) { |
| 343 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 350 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 344 DCHECK_EQ(state_, State::ACTIVE); | 351 DCHECK_EQ(state_, State::ACTIVE); |
| 345 DCHECK(!sign_in_time_.is_null()); | 352 DCHECK(!sign_in_time_.is_null()); |
| 346 | 353 |
| 347 waiting_for_reply_ = false; | 354 arc_sign_in_timer_.Stop(); |
| 348 | 355 |
| 349 UpdateProvisioningTiming(base::Time::Now() - sign_in_time_, false, | 356 UpdateProvisioningTiming(base::Time::Now() - sign_in_time_, false, |
| 350 IsAccountManaged(profile_)); | 357 IsAccountManaged(profile_)); |
| 351 UpdateOptInCancelUMA(OptInCancelReason::CLOUD_PROVISION_FLOW_FAIL); | 358 UpdateOptInCancelUMA(OptInCancelReason::CLOUD_PROVISION_FLOW_FAIL); |
| 352 UpdateProvisioningResultUMA(result); | 359 UpdateProvisioningResultUMA(result); |
| 353 | 360 |
| 354 int error_message_id; | 361 int error_message_id; |
| 355 switch (result) { | 362 switch (result) { |
| 356 case ProvisioningResult::GMS_NETWORK_ERROR: | 363 case ProvisioningResult::GMS_NETWORK_ERROR: |
| 357 error_message_id = IDS_ARC_SIGN_IN_NETWORK_ERROR; | 364 error_message_id = IDS_ARC_SIGN_IN_NETWORK_ERROR; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 384 if (profile_->GetPrefs()->HasPrefPath(prefs::kArcSignedIn)) | 391 if (profile_->GetPrefs()->HasPrefPath(prefs::kArcSignedIn)) |
| 385 profile_->GetPrefs()->SetBoolean(prefs::kArcSignedIn, false); | 392 profile_->GetPrefs()->SetBoolean(prefs::kArcSignedIn, false); |
| 386 ShutdownBridgeAndShowUI(UIPage::ERROR, | 393 ShutdownBridgeAndShowUI(UIPage::ERROR, |
| 387 l10n_util::GetStringUTF16(error_message_id)); | 394 l10n_util::GetStringUTF16(error_message_id)); |
| 388 return; | 395 return; |
| 389 } | 396 } |
| 390 | 397 |
| 391 if (result == ProvisioningResult::CLOUD_PROVISION_FLOW_FAILED || | 398 if (result == ProvisioningResult::CLOUD_PROVISION_FLOW_FAILED || |
| 392 result == ProvisioningResult::CLOUD_PROVISION_FLOW_TIMEOUT || | 399 result == ProvisioningResult::CLOUD_PROVISION_FLOW_TIMEOUT || |
| 393 result == ProvisioningResult::CLOUD_PROVISION_FLOW_INTERNAL_ERROR || | 400 result == ProvisioningResult::CLOUD_PROVISION_FLOW_INTERNAL_ERROR || |
| 394 result == ProvisioningResult::UNKNOWN_ERROR) | 401 // OVERALL_SIGN_IN_TIMEOUT might be an indication that ARC believes it is |
| 402 // fully setup, but Chrome does not. | |
| 403 result == ProvisioningResult::OVERALL_SIGN_IN_TIMEOUT || | |
| 404 // Just to be safe, remove data if we don't know the cause. | |
| 405 result == ProvisioningResult::UNKNOWN_ERROR) { | |
| 395 RemoveArcData(); | 406 RemoveArcData(); |
| 407 } | |
| 396 | 408 |
| 397 // We'll delay shutting down the bridge in this case to allow people to send | 409 // We'll delay shutting down the bridge in this case to allow people to send |
| 398 // feedback. | 410 // feedback. |
| 399 ShowUI(UIPage::ERROR_WITH_FEEDBACK, | 411 ShowUI(UIPage::ERROR_WITH_FEEDBACK, |
| 400 l10n_util::GetStringUTF16(error_message_id)); | 412 l10n_util::GetStringUTF16(error_message_id)); |
| 401 } | 413 } |
| 402 | 414 |
| 403 void ArcAuthService::GetIsAccountManaged( | 415 void ArcAuthService::GetIsAccountManaged( |
| 404 const GetIsAccountManagedCallback& callback) { | 416 const GetIsAccountManagedCallback& callback) { |
| 405 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 417 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 589 CheckAndroidManagement(true); | 601 CheckAndroidManagement(true); |
| 590 } else { | 602 } else { |
| 591 StartArc(); | 603 StartArc(); |
| 592 } | 604 } |
| 593 } | 605 } |
| 594 | 606 |
| 595 UpdateEnabledStateUMA(true); | 607 UpdateEnabledStateUMA(true); |
| 596 } | 608 } |
| 597 | 609 |
| 598 void ArcAuthService::ShutdownBridge() { | 610 void ArcAuthService::ShutdownBridge() { |
| 611 arc_sign_in_timer_.Stop(); | |
| 599 playstore_launcher_.reset(); | 612 playstore_launcher_.reset(); |
| 600 auth_callback_.Reset(); | 613 auth_callback_.Reset(); |
| 601 android_management_checker_.reset(); | 614 android_management_checker_.reset(); |
| 602 auth_code_fetcher_.reset(); | 615 auth_code_fetcher_.reset(); |
| 603 arc_bridge_service()->Shutdown(); | 616 arc_bridge_service()->Shutdown(); |
| 604 if (state_ != State::NOT_INITIALIZED) | 617 if (state_ != State::NOT_INITIALIZED) |
| 605 SetState(State::STOPPED); | 618 SetState(State::STOPPED); |
| 606 FOR_EACH_OBSERVER(Observer, observer_list_, OnShutdownBridge()); | 619 FOR_EACH_OBSERVER(Observer, observer_list_, OnShutdownBridge()); |
| 607 } | 620 } |
| 608 | 621 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 668 return; | 681 return; |
| 669 } | 682 } |
| 670 | 683 |
| 671 State state = state_; | 684 State state = state_; |
| 672 if (state != State::FETCHING_CODE) { | 685 if (state != State::FETCHING_CODE) { |
| 673 ShutdownBridgeAndCloseUI(); | 686 ShutdownBridgeAndCloseUI(); |
| 674 return; | 687 return; |
| 675 } | 688 } |
| 676 | 689 |
| 677 sign_in_time_ = base::Time::Now(); | 690 sign_in_time_ = base::Time::Now(); |
| 691 VLOG(1) << "Starting ARC for first sign in."; | |
| 678 | 692 |
| 679 SetUIPage(UIPage::START_PROGRESS, base::string16()); | 693 SetUIPage(UIPage::START_PROGRESS, base::string16()); |
| 680 ShutdownBridge(); | 694 ShutdownBridge(); |
| 681 auth_code_ = auth_code; | 695 auth_code_ = auth_code; |
| 682 waiting_for_reply_ = true; | 696 arc_sign_in_timer_.Start(FROM_HERE, kArcSignInTimeout, |
| 697 base::Bind(&ArcAuthService::OnArcSignInTimeout, | |
| 698 weak_ptr_factory_.GetWeakPtr())); | |
| 683 StartArc(); | 699 StartArc(); |
| 684 } | 700 } |
| 685 | 701 |
| 702 void ArcAuthService::OnArcSignInTimeout() { | |
| 703 VLOG(1) << "Timed out waiting for first sign in."; | |
| 704 OnSignInFailedInternal(ProvisioningResult::OVERALL_SIGN_IN_TIMEOUT); | |
| 705 } | |
| 706 | |
| 686 void ArcAuthService::StartLso() { | 707 void ArcAuthService::StartLso() { |
| 687 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 708 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 688 | 709 |
| 689 // Update UMA only if error (with or without feedback) is currently shown. | 710 // Update UMA only if error (with or without feedback) is currently shown. |
| 690 if (ui_page_ == UIPage::ERROR) { | 711 if (ui_page_ == UIPage::ERROR) { |
| 691 UpdateOptInActionUMA(OptInActionType::RETRY); | 712 UpdateOptInActionUMA(OptInActionType::RETRY); |
| 692 } else if (ui_page_ == UIPage::ERROR_WITH_FEEDBACK) { | 713 } else if (ui_page_ == UIPage::ERROR_WITH_FEEDBACK) { |
| 693 UpdateOptInActionUMA(OptInActionType::RETRY); | 714 UpdateOptInActionUMA(OptInActionType::RETRY); |
| 694 ShutdownBridge(); | 715 ShutdownBridge(); |
| 695 } | 716 } |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 890 return os << kStateFetchingCode; | 911 return os << kStateFetchingCode; |
| 891 case ArcAuthService::State::ACTIVE: | 912 case ArcAuthService::State::ACTIVE: |
| 892 return os << kStateActive; | 913 return os << kStateActive; |
| 893 default: | 914 default: |
| 894 NOTREACHED(); | 915 NOTREACHED(); |
| 895 return os; | 916 return os; |
| 896 } | 917 } |
| 897 } | 918 } |
| 898 | 919 |
| 899 } // namespace arc | 920 } // namespace arc |
| OLD | NEW |