| 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 <string> |
| 7 #include <utility> | 8 #include <utility> |
| 8 | 9 |
| 9 #include "ash/shelf/shelf_delegate.h" | 10 #include "ash/shelf/shelf_delegate.h" |
| 10 #include "ash/shell.h" | 11 #include "ash/shell.h" |
| 11 #include "base/auto_reset.h" | 12 #include "base/auto_reset.h" |
| 12 #include "base/bind.h" | 13 #include "base/bind.h" |
| 13 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 14 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
| 15 #include "base/logging.h" | 16 #include "base/logging.h" |
| 16 #include "base/strings/string16.h" | 17 #include "base/strings/string16.h" |
| 18 #include "base/strings/stringprintf.h" |
| 17 #include "base/threading/thread_checker.h" | 19 #include "base/threading/thread_checker.h" |
| 18 #include "chrome/browser/chromeos/arc/arc_android_management_checker.h" | 20 #include "chrome/browser/chromeos/arc/arc_android_management_checker.h" |
| 19 #include "chrome/browser/chromeos/arc/arc_auth_context.h" | |
| 20 #include "chrome/browser/chromeos/arc/arc_auth_notification.h" | 21 #include "chrome/browser/chromeos/arc/arc_auth_notification.h" |
| 21 #include "chrome/browser/chromeos/arc/arc_optin_uma.h" | 22 #include "chrome/browser/chromeos/arc/arc_optin_uma.h" |
| 22 #include "chrome/browser/chromeos/arc/arc_support_host.h" | 23 #include "chrome/browser/chromeos/arc/arc_support_host.h" |
| 23 #include "chrome/browser/chromeos/profiles/profile_helper.h" | 24 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
| 24 #include "chrome/browser/extensions/extension_util.h" | 25 #include "chrome/browser/extensions/extension_util.h" |
| 25 #include "chrome/browser/policy/profile_policy_connector.h" | 26 #include "chrome/browser/policy/profile_policy_connector.h" |
| 26 #include "chrome/browser/policy/profile_policy_connector_factory.h" | 27 #include "chrome/browser/policy/profile_policy_connector_factory.h" |
| 27 #include "chrome/browser/prefs/pref_service_syncable_util.h" | 28 #include "chrome/browser/prefs/pref_service_syncable_util.h" |
| 28 #include "chrome/browser/profiles/profile.h" | 29 #include "chrome/browser/profiles/profile.h" |
| 30 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" |
| 31 #include "chrome/browser/signin/signin_manager_factory.h" |
| 29 #include "chrome/browser/ui/app_list/arc/arc_app_launcher.h" | 32 #include "chrome/browser/ui/app_list/arc/arc_app_launcher.h" |
| 30 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" | 33 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" |
| 31 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" | 34 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" |
| 32 #include "chrome/browser/ui/extensions/app_launch_params.h" | 35 #include "chrome/browser/ui/extensions/app_launch_params.h" |
| 33 #include "chrome/browser/ui/extensions/application_launch.h" | 36 #include "chrome/browser/ui/extensions/application_launch.h" |
| 34 #include "chrome/common/pref_names.h" | 37 #include "chrome/common/pref_names.h" |
| 35 #include "chrome/grit/generated_resources.h" | 38 #include "chrome/grit/generated_resources.h" |
| 36 #include "chromeos/chromeos_switches.h" | 39 #include "chromeos/chromeos_switches.h" |
| 37 #include "chromeos/cryptohome/cryptohome_parameters.h" | 40 #include "chromeos/cryptohome/cryptohome_parameters.h" |
| 38 #include "chromeos/dbus/dbus_thread_manager.h" | 41 #include "chromeos/dbus/dbus_thread_manager.h" |
| 39 #include "chromeos/dbus/session_manager_client.h" | 42 #include "chromeos/dbus/session_manager_client.h" |
| 40 #include "components/arc/arc_bridge_service.h" | 43 #include "components/arc/arc_bridge_service.h" |
| 41 #include "components/policy/core/browser/browser_policy_connector.h" | 44 #include "components/policy/core/browser/browser_policy_connector.h" |
| 42 #include "components/pref_registry/pref_registry_syncable.h" | 45 #include "components/pref_registry/pref_registry_syncable.h" |
| 43 #include "components/prefs/pref_service.h" | 46 #include "components/prefs/pref_service.h" |
| 47 #include "components/signin/core/browser/profile_oauth2_token_service.h" |
| 48 #include "components/signin/core/browser/signin_manager_base.h" |
| 44 #include "components/syncable_prefs/pref_service_syncable.h" | 49 #include "components/syncable_prefs/pref_service_syncable.h" |
| 45 #include "components/user_manager/user.h" | 50 #include "components/user_manager/user.h" |
| 51 #include "content/public/browser/storage_partition.h" |
| 52 #include "content/public/common/url_constants.h" |
| 46 #include "extensions/browser/app_window/app_window_registry.h" | 53 #include "extensions/browser/app_window/app_window_registry.h" |
| 47 #include "extensions/browser/extension_prefs.h" | 54 #include "extensions/browser/extension_prefs.h" |
| 48 #include "extensions/browser/extension_registry.h" | 55 #include "extensions/browser/extension_registry.h" |
| 56 #include "google_apis/gaia/gaia_constants.h" |
| 49 #include "ui/base/l10n/l10n_util.h" | 57 #include "ui/base/l10n/l10n_util.h" |
| 50 | 58 |
| 51 namespace arc { | 59 namespace arc { |
| 52 | 60 |
| 53 namespace { | 61 namespace { |
| 54 | 62 |
| 55 // Weak pointer. This class is owned by ArcServiceManager. | 63 // Weak pointer. This class is owned by ArcServiceManager. |
| 56 ArcAuthService* arc_auth_service = nullptr; | 64 ArcAuthService* arc_auth_service = nullptr; |
| 57 | 65 |
| 58 base::LazyInstance<base::ThreadChecker> thread_checker = | 66 base::LazyInstance<base::ThreadChecker> thread_checker = |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 | 334 |
| 327 // TODO(khmel): Move this to IsAllowedForProfile. | 335 // TODO(khmel): Move this to IsAllowedForProfile. |
| 328 if (IsArcDisabledForEnterprise() && IsAccountManaged(profile)) { | 336 if (IsArcDisabledForEnterprise() && IsAccountManaged(profile)) { |
| 329 VLOG(2) << "Enterprise users are not supported in ARC."; | 337 VLOG(2) << "Enterprise users are not supported in ARC."; |
| 330 return; | 338 return; |
| 331 } | 339 } |
| 332 | 340 |
| 333 PrefServiceSyncableFromProfile(profile_)->AddSyncedPrefObserver( | 341 PrefServiceSyncableFromProfile(profile_)->AddSyncedPrefObserver( |
| 334 prefs::kArcEnabled, this); | 342 prefs::kArcEnabled, this); |
| 335 | 343 |
| 336 context_.reset(new ArcAuthContext(this, profile_)); | 344 // Reuse storage used in ARC OptIn platform app. |
| 345 const std::string site_url = base::StringPrintf( |
| 346 "%s://%s/persist?%s", content::kGuestScheme, ArcSupportHost::kHostAppId, |
| 347 ArcSupportHost::kStorageId); |
| 348 storage_partition_ = content::BrowserContext::GetStoragePartitionForSite( |
| 349 profile_, GURL(site_url)); |
| 350 CHECK(storage_partition_); |
| 351 |
| 352 // Get token service and account ID to fetch auth tokens. |
| 353 token_service_ = ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); |
| 354 const SigninManagerBase* const signin_manager = |
| 355 SigninManagerFactory::GetForProfile(profile_); |
| 356 CHECK(token_service_ && signin_manager); |
| 357 account_id_ = signin_manager->GetAuthenticatedAccountId(); |
| 337 | 358 |
| 338 // In case UI is disabled we assume that ARC is opted-in. | 359 // In case UI is disabled we assume that ARC is opted-in. |
| 339 if (!IsOptInVerificationDisabled()) { | 360 if (!IsOptInVerificationDisabled()) { |
| 340 if (!disable_ui_for_testing || enable_check_android_management_for_testing) | 361 if (!disable_ui_for_testing || enable_check_android_management_for_testing) |
| 341 ArcAndroidManagementChecker::StartClient(); | 362 ArcAndroidManagementChecker::StartClient(); |
| 342 pref_change_registrar_.Init(profile_->GetPrefs()); | 363 pref_change_registrar_.Init(profile_->GetPrefs()); |
| 343 pref_change_registrar_.Add( | 364 pref_change_registrar_.Add( |
| 344 prefs::kArcEnabled, | 365 prefs::kArcEnabled, |
| 345 base::Bind(&ArcAuthService::OnOptInPreferenceChanged, | 366 base::Bind(&ArcAuthService::OnOptInPreferenceChanged, |
| 346 weak_ptr_factory_.GetWeakPtr())); | 367 weak_ptr_factory_.GetWeakPtr())); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 376 | 397 |
| 377 void ArcAuthService::Shutdown() { | 398 void ArcAuthService::Shutdown() { |
| 378 ShutdownBridgeAndCloseUI(); | 399 ShutdownBridgeAndCloseUI(); |
| 379 if (profile_) { | 400 if (profile_) { |
| 380 syncable_prefs::PrefServiceSyncable* pref_service_syncable = | 401 syncable_prefs::PrefServiceSyncable* pref_service_syncable = |
| 381 PrefServiceSyncableFromProfile(profile_); | 402 PrefServiceSyncableFromProfile(profile_); |
| 382 pref_service_syncable->RemoveObserver(this); | 403 pref_service_syncable->RemoveObserver(this); |
| 383 pref_service_syncable->RemoveSyncedPrefObserver(prefs::kArcEnabled, this); | 404 pref_service_syncable->RemoveSyncedPrefObserver(prefs::kArcEnabled, this); |
| 384 } | 405 } |
| 385 pref_change_registrar_.RemoveAll(); | 406 pref_change_registrar_.RemoveAll(); |
| 386 context_.reset(); | |
| 387 profile_ = nullptr; | 407 profile_ = nullptr; |
| 408 token_service_ = nullptr; |
| 409 account_id_.clear(); |
| 388 SetState(State::NOT_INITIALIZED); | 410 SetState(State::NOT_INITIALIZED); |
| 389 } | 411 } |
| 390 | 412 |
| 391 void ArcAuthService::ShowUI(UIPage page, const base::string16& status) { | 413 void ArcAuthService::ShowUI(UIPage page, const base::string16& status) { |
| 392 if (disable_ui_for_testing || IsOptInVerificationDisabled()) | 414 if (disable_ui_for_testing || IsOptInVerificationDisabled()) |
| 393 return; | 415 return; |
| 394 | 416 |
| 395 SetUIPage(page, status); | 417 SetUIPage(page, status); |
| 396 const extensions::AppWindowRegistry* const app_window_registry = | 418 const extensions::AppWindowRegistry* const app_window_registry = |
| 397 extensions::AppWindowRegistry::Get(profile_); | 419 extensions::AppWindowRegistry::Get(profile_); |
| 398 DCHECK(app_window_registry); | 420 DCHECK(app_window_registry); |
| 399 if (app_window_registry->GetCurrentAppWindowForApp( | 421 if (app_window_registry->GetCurrentAppWindowForApp( |
| 400 ArcSupportHost::kHostAppId)) { | 422 ArcSupportHost::kHostAppId)) { |
| 401 return; | 423 return; |
| 402 } | 424 } |
| 403 | 425 |
| 404 const extensions::Extension* extension = | 426 const extensions::Extension* extension = |
| 405 extensions::ExtensionRegistry::Get(profile_)->GetInstalledExtension( | 427 extensions::ExtensionRegistry::Get(profile_)->GetInstalledExtension( |
| 406 ArcSupportHost::kHostAppId); | 428 ArcSupportHost::kHostAppId); |
| 407 CHECK(extension && extensions::util::IsAppLaunchable( | 429 CHECK(extension && extensions::util::IsAppLaunchable( |
| 408 ArcSupportHost::kHostAppId, profile_)); | 430 ArcSupportHost::kHostAppId, profile_)); |
| 409 | 431 |
| 410 OpenApplication(CreateAppLaunchParamsUserContainer( | 432 OpenApplication(CreateAppLaunchParamsUserContainer( |
| 411 profile_, extension, NEW_WINDOW, extensions::SOURCE_CHROME_INTERNAL)); | 433 profile_, extension, NEW_WINDOW, extensions::SOURCE_CHROME_INTERNAL)); |
| 412 } | 434 } |
| 413 | 435 |
| 414 void ArcAuthService::OnContextReady() { | 436 void ArcAuthService::OnMergeSessionSuccess(const std::string& data) { |
| 415 DCHECK(thread_checker.Get().CalledOnValidThread()); | 437 DCHECK(thread_checker.Get().CalledOnValidThread()); |
| 416 | 438 |
| 417 DCHECK(!initial_opt_in_); | 439 DCHECK(!initial_opt_in_); |
| 440 context_prepared_ = true; |
| 418 CheckAndroidManagement(false); | 441 CheckAndroidManagement(false); |
| 419 } | 442 } |
| 420 | 443 |
| 444 void ArcAuthService::OnMergeSessionFailure( |
| 445 const GoogleServiceAuthError& error) { |
| 446 DCHECK(thread_checker.Get().CalledOnValidThread()); |
| 447 VLOG(2) << "Failed to merge gaia session " << error.ToString() << "."; |
| 448 OnPrepareContextFailed(); |
| 449 } |
| 450 |
| 451 void ArcAuthService::OnUbertokenSuccess(const std::string& token) { |
| 452 DCHECK(thread_checker.Get().CalledOnValidThread()); |
| 453 merger_fetcher_.reset( |
| 454 new GaiaAuthFetcher(this, GaiaConstants::kChromeOSSource, |
| 455 storage_partition_->GetURLRequestContext())); |
| 456 merger_fetcher_->StartMergeSession(token, std::string()); |
| 457 } |
| 458 |
| 459 void ArcAuthService::OnUbertokenFailure(const GoogleServiceAuthError& error) { |
| 460 DCHECK(thread_checker.Get().CalledOnValidThread()); |
| 461 VLOG(2) << "Failed to get ubertoken " << error.ToString() << "."; |
| 462 OnPrepareContextFailed(); |
| 463 } |
| 464 |
| 421 void ArcAuthService::OnSyncedPrefChanged(const std::string& path, | 465 void ArcAuthService::OnSyncedPrefChanged(const std::string& path, |
| 422 bool from_sync) { | 466 bool from_sync) { |
| 423 DCHECK(thread_checker.Get().CalledOnValidThread()); | 467 DCHECK(thread_checker.Get().CalledOnValidThread()); |
| 424 | 468 |
| 425 // Update UMA only for local changes | 469 // Update UMA only for local changes |
| 426 if (!from_sync) { | 470 if (!from_sync) { |
| 427 const bool arc_enabled = | 471 const bool arc_enabled = |
| 428 profile_->GetPrefs()->GetBoolean(prefs::kArcEnabled); | 472 profile_->GetPrefs()->GetBoolean(prefs::kArcEnabled); |
| 429 UpdateOptInActionUMA(arc_enabled ? OptInActionType::OPTED_IN | 473 UpdateOptInActionUMA(arc_enabled ? OptInActionType::OPTED_IN |
| 430 : OptInActionType::OPTED_OUT); | 474 : OptInActionType::OPTED_OUT); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 StartArc(); | 515 StartArc(); |
| 472 } | 516 } |
| 473 } | 517 } |
| 474 | 518 |
| 475 UpdateEnabledStateUMA(true); | 519 UpdateEnabledStateUMA(true); |
| 476 } | 520 } |
| 477 | 521 |
| 478 void ArcAuthService::ShutdownBridge() { | 522 void ArcAuthService::ShutdownBridge() { |
| 479 playstore_launcher_.reset(); | 523 playstore_launcher_.reset(); |
| 480 auth_callback_.Reset(); | 524 auth_callback_.Reset(); |
| 525 ubertoken_fetcher_.reset(); |
| 526 merger_fetcher_.reset(); |
| 481 android_management_checker_.reset(); | 527 android_management_checker_.reset(); |
| 482 arc_bridge_service()->Shutdown(); | 528 arc_bridge_service()->Shutdown(); |
| 483 if (state_ != State::NOT_INITIALIZED) | 529 if (state_ != State::NOT_INITIALIZED) |
| 484 SetState(State::STOPPED); | 530 SetState(State::STOPPED); |
| 485 FOR_EACH_OBSERVER(Observer, observer_list_, OnShutdownBridge()); | 531 FOR_EACH_OBSERVER(Observer, observer_list_, OnShutdownBridge()); |
| 486 } | 532 } |
| 487 | 533 |
| 488 void ArcAuthService::ShutdownBridgeAndCloseUI() { | 534 void ArcAuthService::ShutdownBridgeAndCloseUI() { |
| 489 ShutdownBridge(); | 535 ShutdownBridge(); |
| 490 CloseUI(); | 536 CloseUI(); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 603 DCHECK(profile_); | 649 DCHECK(profile_); |
| 604 profile_->GetPrefs()->SetBoolean(prefs::kArcEnabled, true); | 650 profile_->GetPrefs()->SetBoolean(prefs::kArcEnabled, true); |
| 605 } | 651 } |
| 606 | 652 |
| 607 void ArcAuthService::DisableArc() { | 653 void ArcAuthService::DisableArc() { |
| 608 DCHECK(thread_checker.Get().CalledOnValidThread()); | 654 DCHECK(thread_checker.Get().CalledOnValidThread()); |
| 609 DCHECK(profile_); | 655 DCHECK(profile_); |
| 610 profile_->GetPrefs()->SetBoolean(prefs::kArcEnabled, false); | 656 profile_->GetPrefs()->SetBoolean(prefs::kArcEnabled, false); |
| 611 } | 657 } |
| 612 | 658 |
| 659 void ArcAuthService::PrepareContext() { |
| 660 DCHECK(thread_checker.Get().CalledOnValidThread()); |
| 661 |
| 662 ubertoken_fetcher_.reset( |
| 663 new UbertokenFetcher(token_service_, this, GaiaConstants::kChromeOSSource, |
| 664 storage_partition_->GetURLRequestContext())); |
| 665 ubertoken_fetcher_->StartFetchingToken(account_id_); |
| 666 } |
| 667 |
| 613 void ArcAuthService::StartUI() { | 668 void ArcAuthService::StartUI() { |
| 614 DCHECK(thread_checker.Get().CalledOnValidThread()); | 669 DCHECK(thread_checker.Get().CalledOnValidThread()); |
| 615 | 670 |
| 616 SetState(State::FETCHING_CODE); | 671 SetState(State::FETCHING_CODE); |
| 617 | 672 |
| 618 if (initial_opt_in_) { | 673 if (initial_opt_in_) { |
| 619 initial_opt_in_ = false; | 674 initial_opt_in_ = false; |
| 620 if (IsArcManaged()) | 675 ShowUI(UIPage::START, base::string16()); |
| 621 context_->PrepareContext(); | 676 } else if (context_prepared_) { |
| 622 else | 677 CheckAndroidManagement(false); |
| 623 ShowUI(UIPage::START, base::string16()); | |
| 624 } else { | 678 } else { |
| 625 context_->PrepareContext(); | 679 PrepareContext(); |
| 626 } | 680 } |
| 627 } | 681 } |
| 628 | 682 |
| 629 void ArcAuthService::OnPrepareContextFailed() { | 683 void ArcAuthService::OnPrepareContextFailed() { |
| 630 DCHECK_EQ(state_, State::FETCHING_CODE); | 684 DCHECK_EQ(state_, State::FETCHING_CODE); |
| 631 | 685 |
| 632 ShutdownBridgeAndShowUI( | 686 ShutdownBridgeAndShowUI( |
| 633 UIPage::ERROR, | 687 UIPage::ERROR, |
| 634 l10n_util::GetStringUTF16(IDS_ARC_SERVER_COMMUNICATION_ERROR)); | 688 l10n_util::GetStringUTF16(IDS_ARC_SERVER_COMMUNICATION_ERROR)); |
| 635 UpdateOptInCancelUMA(OptInCancelReason::NETWORK_ERROR); | 689 UpdateOptInCancelUMA(OptInCancelReason::NETWORK_ERROR); |
| 636 } | 690 } |
| 637 | 691 |
| 638 void ArcAuthService::CheckAndroidManagement(bool background_mode) { | 692 void ArcAuthService::CheckAndroidManagement(bool backround_mode) { |
| 639 // Do not send requests for Chrome OS managed users. | 693 // Do not send requests for Chrome OS managed users. |
| 640 if (IsAccountManaged(profile_)) { | 694 if (IsAccountManaged(profile_)) { |
| 641 StartArcIfSignedIn(); | 695 StartArcIfSignedIn(); |
| 642 return; | 696 return; |
| 643 } | 697 } |
| 644 | 698 |
| 645 // Do not send requests for well-known consumer domains. | 699 // Do not send requests for well-known consumer domains. |
| 646 if (policy::BrowserPolicyConnector::IsNonEnterpriseUser( | 700 if (policy::BrowserPolicyConnector::IsNonEnterpriseUser( |
| 647 profile_->GetProfileUserName())) { | 701 profile_->GetProfileUserName())) { |
| 648 StartArcIfSignedIn(); | 702 StartArcIfSignedIn(); |
| 649 return; | 703 return; |
| 650 } | 704 } |
| 651 | 705 |
| 652 android_management_checker_.reset( | 706 android_management_checker_.reset(new ArcAndroidManagementChecker( |
| 653 new ArcAndroidManagementChecker(this, context_->token_service(), | 707 this, token_service_, account_id_, backround_mode)); |
| 654 context_->account_id(), background_mode)); | 708 if (backround_mode) |
| 655 if (background_mode) | |
| 656 StartArcIfSignedIn(); | 709 StartArcIfSignedIn(); |
| 657 } | 710 } |
| 658 | 711 |
| 659 void ArcAuthService::OnAndroidManagementChecked( | 712 void ArcAuthService::OnAndroidManagementChecked( |
| 660 policy::AndroidManagementClient::Result result) { | 713 policy::AndroidManagementClient::Result result) { |
| 661 switch (result) { | 714 switch (result) { |
| 662 case policy::AndroidManagementClient::Result::RESULT_UNMANAGED: | 715 case policy::AndroidManagementClient::Result::RESULT_UNMANAGED: |
| 663 StartArcIfSignedIn(); | 716 StartArcIfSignedIn(); |
| 664 break; | 717 break; |
| 665 case policy::AndroidManagementClient::Result::RESULT_MANAGED: | 718 case policy::AndroidManagementClient::Result::RESULT_MANAGED: |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 return os << kStateFetchingCode; | 757 return os << kStateFetchingCode; |
| 705 case ArcAuthService::State::ACTIVE: | 758 case ArcAuthService::State::ACTIVE: |
| 706 return os << kStateActive; | 759 return os << kStateActive; |
| 707 default: | 760 default: |
| 708 NOTREACHED(); | 761 NOTREACHED(); |
| 709 return os; | 762 return os; |
| 710 } | 763 } |
| 711 } | 764 } |
| 712 | 765 |
| 713 } // namespace arc | 766 } // namespace arc |
| OLD | NEW |