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