| 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" |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.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/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 16 #include "base/strings/string16.h" | 16 #include "base/strings/string16.h" |
| 17 #include "base/threading/thread_task_runner_handle.h" | 17 #include "base/threading/thread_task_runner_handle.h" |
| 18 #include "base/time/time.h" | 18 #include "base/time/time.h" |
| 19 #include "chrome/browser/chromeos/arc/arc_auth_context.h" | 19 #include "chrome/browser/chromeos/arc/arc_auth_context.h" |
| 20 #include "chrome/browser/chromeos/arc/arc_auth_notification.h" | 20 #include "chrome/browser/chromeos/arc/arc_auth_notification.h" |
| 21 #include "chrome/browser/chromeos/arc/arc_optin_uma.h" | 21 #include "chrome/browser/chromeos/arc/arc_optin_uma.h" |
| 22 #include "chrome/browser/chromeos/arc/arc_support_host.h" | 22 #include "chrome/browser/chromeos/arc/arc_support_host.h" |
| 23 #include "chrome/browser/chromeos/arc/arc_util.h" |
| 23 #include "chrome/browser/chromeos/arc/optin/arc_terms_of_service_negotiator.h" | 24 #include "chrome/browser/chromeos/arc/optin/arc_terms_of_service_negotiator.h" |
| 24 #include "chrome/browser/chromeos/arc/policy/arc_android_management_checker.h" | 25 #include "chrome/browser/chromeos/arc/policy/arc_android_management_checker.h" |
| 25 #include "chrome/browser/chromeos/arc/policy/arc_policy_util.h" | 26 #include "chrome/browser/chromeos/arc/policy/arc_policy_util.h" |
| 26 #include "chrome/browser/chromeos/login/user_flow.h" | |
| 27 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h" | |
| 28 #include "chrome/browser/chromeos/profiles/profile_helper.h" | |
| 29 #include "chrome/browser/lifetime/application_lifetime.h" | 27 #include "chrome/browser/lifetime/application_lifetime.h" |
| 30 #include "chrome/browser/policy/profile_policy_connector.h" | 28 #include "chrome/browser/policy/profile_policy_connector.h" |
| 31 #include "chrome/browser/policy/profile_policy_connector_factory.h" | 29 #include "chrome/browser/policy/profile_policy_connector_factory.h" |
| 32 #include "chrome/browser/prefs/pref_service_syncable_util.h" | 30 #include "chrome/browser/prefs/pref_service_syncable_util.h" |
| 33 #include "chrome/browser/profiles/profile.h" | 31 #include "chrome/browser/profiles/profile.h" |
| 34 #include "chrome/browser/ui/app_list/arc/arc_app_launcher.h" | 32 #include "chrome/browser/ui/app_list/arc/arc_app_launcher.h" |
| 35 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" | 33 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" |
| 36 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" | 34 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" |
| 37 #include "chrome/browser/ui/browser_commands.h" | 35 #include "chrome/browser/ui/browser_commands.h" |
| 38 #include "chrome/common/pref_names.h" | 36 #include "chrome/common/pref_names.h" |
| 39 #include "chrome/grit/generated_resources.h" | 37 #include "chrome/grit/generated_resources.h" |
| 40 #include "chromeos/chromeos_switches.h" | 38 #include "chromeos/chromeos_switches.h" |
| 41 #include "chromeos/cryptohome/cryptohome_parameters.h" | 39 #include "chromeos/cryptohome/cryptohome_parameters.h" |
| 42 #include "chromeos/dbus/dbus_thread_manager.h" | 40 #include "chromeos/dbus/dbus_thread_manager.h" |
| 43 #include "chromeos/dbus/session_manager_client.h" | 41 #include "chromeos/dbus/session_manager_client.h" |
| 44 #include "components/arc/arc_bridge_service.h" | 42 #include "components/arc/arc_bridge_service.h" |
| 45 #include "components/arc/arc_session_runner.h" | 43 #include "components/arc/arc_session_runner.h" |
| 46 #include "components/arc/arc_util.h" | 44 #include "components/arc/arc_util.h" |
| 47 #include "components/pref_registry/pref_registry_syncable.h" | 45 #include "components/pref_registry/pref_registry_syncable.h" |
| 48 #include "components/prefs/pref_service.h" | 46 #include "components/prefs/pref_service.h" |
| 49 #include "components/sync_preferences/pref_service_syncable.h" | 47 #include "components/sync_preferences/pref_service_syncable.h" |
| 50 #include "components/user_manager/user.h" | |
| 51 #include "content/public/browser/browser_thread.h" | 48 #include "content/public/browser/browser_thread.h" |
| 52 #include "extensions/browser/extension_prefs.h" | 49 #include "extensions/browser/extension_prefs.h" |
| 53 | 50 |
| 54 namespace arc { | 51 namespace arc { |
| 55 | 52 |
| 56 namespace { | 53 namespace { |
| 57 | 54 |
| 58 // Weak pointer. This class is owned by ArcServiceManager. | 55 // Weak pointer. This class is owned by ArcServiceManager. |
| 59 ArcSessionManager* g_arc_session_manager = nullptr; | 56 ArcSessionManager* g_arc_session_manager = nullptr; |
| 60 | 57 |
| 61 // Skip creating UI in unit tests | 58 // Skip creating UI in unit tests |
| 62 bool g_disable_ui_for_testing = false; | 59 bool g_disable_ui_for_testing = false; |
| 63 | 60 |
| 64 // Use specified ash::ShelfDelegate for unit tests. | 61 // Use specified ash::ShelfDelegate for unit tests. |
| 65 ash::ShelfDelegate* g_shelf_delegate_for_testing = nullptr; | 62 ash::ShelfDelegate* g_shelf_delegate_for_testing = nullptr; |
| 66 | 63 |
| 67 // The Android management check is disabled by default, it's used only for | 64 // The Android management check is disabled by default, it's used only for |
| 68 // testing. | 65 // testing. |
| 69 bool g_enable_check_android_management_for_testing = false; | 66 bool g_enable_check_android_management_for_testing = false; |
| 70 | 67 |
| 71 // Let IsAllowedForProfile() return "false" for any profile. | |
| 72 bool g_disallow_for_testing = false; | |
| 73 | |
| 74 // Maximum amount of time we'll wait for ARC to finish booting up. Once this | 68 // Maximum amount of time we'll wait for ARC to finish booting up. Once this |
| 75 // timeout expires, keep ARC running in case the user wants to file feedback, | 69 // timeout expires, keep ARC running in case the user wants to file feedback, |
| 76 // but present the UI to try again. | 70 // but present the UI to try again. |
| 77 constexpr base::TimeDelta kArcSignInTimeout = base::TimeDelta::FromMinutes(5); | 71 constexpr base::TimeDelta kArcSignInTimeout = base::TimeDelta::FromMinutes(5); |
| 78 | 72 |
| 79 ash::ShelfDelegate* GetShelfDelegate() { | 73 ash::ShelfDelegate* GetShelfDelegate() { |
| 80 if (g_shelf_delegate_for_testing) | 74 if (g_shelf_delegate_for_testing) |
| 81 return g_shelf_delegate_for_testing; | 75 return g_shelf_delegate_for_testing; |
| 82 if (ash::WmShell::HasInstance()) { | 76 if (ash::WmShell::HasInstance()) { |
| 83 DCHECK(ash::WmShell::Get()->shelf_delegate()); | 77 DCHECK(ash::WmShell::Get()->shelf_delegate()); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 g_disable_ui_for_testing = true; | 127 g_disable_ui_for_testing = true; |
| 134 } | 128 } |
| 135 | 129 |
| 136 // static | 130 // static |
| 137 void ArcSessionManager::SetShelfDelegateForTesting( | 131 void ArcSessionManager::SetShelfDelegateForTesting( |
| 138 ash::ShelfDelegate* shelf_delegate) { | 132 ash::ShelfDelegate* shelf_delegate) { |
| 139 g_shelf_delegate_for_testing = shelf_delegate; | 133 g_shelf_delegate_for_testing = shelf_delegate; |
| 140 } | 134 } |
| 141 | 135 |
| 142 // static | 136 // static |
| 143 bool ArcSessionManager::IsOptInVerificationDisabled() { | |
| 144 return base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 145 chromeos::switches::kDisableArcOptInVerification); | |
| 146 } | |
| 147 | |
| 148 // static | |
| 149 void ArcSessionManager::EnableCheckAndroidManagementForTesting() { | 137 void ArcSessionManager::EnableCheckAndroidManagementForTesting() { |
| 150 g_enable_check_android_management_for_testing = true; | 138 g_enable_check_android_management_for_testing = true; |
| 151 } | 139 } |
| 152 | 140 |
| 153 // static | |
| 154 bool ArcSessionManager::IsAllowedForProfile(const Profile* profile) { | |
| 155 if (g_disallow_for_testing) { | |
| 156 VLOG(1) << "ARC is disallowed for testing."; | |
| 157 return false; | |
| 158 } | |
| 159 | |
| 160 if (!IsArcAvailable()) { | |
| 161 VLOG(1) << "ARC is not available."; | |
| 162 return false; | |
| 163 } | |
| 164 | |
| 165 if (!profile) { | |
| 166 VLOG(1) << "ARC is not supported for systems without profile."; | |
| 167 return false; | |
| 168 } | |
| 169 | |
| 170 if (!chromeos::ProfileHelper::IsPrimaryProfile(profile)) { | |
| 171 VLOG(1) << "Non-primary users are not supported in ARC."; | |
| 172 return false; | |
| 173 } | |
| 174 | |
| 175 // IsPrimaryProfile can return true for an incognito profile corresponding | |
| 176 // to the primary profile, but ARC does not support it. | |
| 177 if (profile->IsOffTheRecord()) { | |
| 178 VLOG(1) << "Incognito profile is not supported in ARC."; | |
| 179 return false; | |
| 180 } | |
| 181 | |
| 182 if (profile->IsLegacySupervised()) { | |
| 183 VLOG(1) << "Supervised users are not supported in ARC."; | |
| 184 return false; | |
| 185 } | |
| 186 | |
| 187 user_manager::User const* const user = | |
| 188 chromeos::ProfileHelper::Get()->GetUserByProfile(profile); | |
| 189 if ((!user || !user->HasGaiaAccount()) && !IsArcKioskMode()) { | |
| 190 VLOG(1) << "Users without GAIA accounts are not supported in ARC."; | |
| 191 return false; | |
| 192 } | |
| 193 | |
| 194 chromeos::UserFlow* user_flow = | |
| 195 chromeos::ChromeUserManager::Get()->GetUserFlow(user->GetAccountId()); | |
| 196 if (!user_flow || !user_flow->CanStartArc()) { | |
| 197 VLOG(1) << "ARC is not allowed in the current user flow."; | |
| 198 return false; | |
| 199 } | |
| 200 | |
| 201 if (user_manager::UserManager::Get() | |
| 202 ->IsCurrentUserCryptohomeDataEphemeral()) { | |
| 203 VLOG(2) << "Users with ephemeral data are not supported in ARC."; | |
| 204 return false; | |
| 205 } | |
| 206 | |
| 207 return true; | |
| 208 } | |
| 209 | |
| 210 // static | |
| 211 void ArcSessionManager::DisallowForTesting() { | |
| 212 g_disallow_for_testing = true; | |
| 213 } | |
| 214 | |
| 215 // static | |
| 216 bool ArcSessionManager::IsArcKioskMode() { | |
| 217 return user_manager::UserManager::Get()->IsLoggedInAsArcKioskApp(); | |
| 218 } | |
| 219 | |
| 220 void ArcSessionManager::OnSessionReady() { | 141 void ArcSessionManager::OnSessionReady() { |
| 221 for (auto& observer : arc_session_observer_list_) | 142 for (auto& observer : arc_session_observer_list_) |
| 222 observer.OnSessionReady(); | 143 observer.OnSessionReady(); |
| 223 } | 144 } |
| 224 | 145 |
| 225 void ArcSessionManager::OnSessionStopped(StopReason reason) { | 146 void ArcSessionManager::OnSessionStopped(StopReason reason) { |
| 226 // TODO(crbug.com/625923): Use |reason| to report more detailed errors. | 147 // TODO(crbug.com/625923): Use |reason| to report more detailed errors. |
| 227 if (arc_sign_in_timer_.IsRunning()) | 148 if (arc_sign_in_timer_.IsRunning()) |
| 228 OnProvisioningFinished(ProvisioningResult::ARC_STOPPED); | 149 OnProvisioningFinished(ProvisioningResult::ARC_STOPPED); |
| 229 | 150 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 if (result == ProvisioningResult::SUCCESS) { | 279 if (result == ProvisioningResult::SUCCESS) { |
| 359 if (support_host_) | 280 if (support_host_) |
| 360 support_host_->Close(); | 281 support_host_->Close(); |
| 361 | 282 |
| 362 if (profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn)) | 283 if (profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn)) |
| 363 return; | 284 return; |
| 364 | 285 |
| 365 profile_->GetPrefs()->SetBoolean(prefs::kArcSignedIn, true); | 286 profile_->GetPrefs()->SetBoolean(prefs::kArcSignedIn, true); |
| 366 // Don't show Play Store app for ARC Kiosk because the only one UI in kiosk | 287 // Don't show Play Store app for ARC Kiosk because the only one UI in kiosk |
| 367 // mode must be the kiosk app and device is not needed for opt-in. | 288 // mode must be the kiosk app and device is not needed for opt-in. |
| 368 if (!IsOptInVerificationDisabled() && !IsArcKioskMode()) { | 289 if (!IsArcOptInVerificationDisabled() && !IsArcKioskMode()) { |
| 369 playstore_launcher_.reset( | 290 playstore_launcher_.reset( |
| 370 new ArcAppLauncher(profile_, kPlayStoreAppId, true)); | 291 new ArcAppLauncher(profile_, kPlayStoreAppId, true)); |
| 371 } | 292 } |
| 372 | 293 |
| 373 for (auto& observer : observer_list_) | 294 for (auto& observer : observer_list_) |
| 374 observer.OnArcInitialStart(); | 295 observer.OnArcInitialStart(); |
| 375 return; | 296 return; |
| 376 } | 297 } |
| 377 | 298 |
| 378 ArcSupportHost::Error error; | 299 ArcSupportHost::Error error; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 363 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 443 return profile_ != nullptr; | 364 return profile_ != nullptr; |
| 444 } | 365 } |
| 445 | 366 |
| 446 void ArcSessionManager::OnPrimaryUserProfilePrepared(Profile* profile) { | 367 void ArcSessionManager::OnPrimaryUserProfilePrepared(Profile* profile) { |
| 447 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 368 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 448 DCHECK(profile && profile != profile_); | 369 DCHECK(profile && profile != profile_); |
| 449 | 370 |
| 450 Shutdown(); | 371 Shutdown(); |
| 451 | 372 |
| 452 if (!IsAllowedForProfile(profile)) | 373 if (!IsArcAllowedForProfile(profile)) |
| 453 return; | 374 return; |
| 454 | 375 |
| 455 // TODO(khmel): Move this to IsAllowedForProfile. | 376 // TODO(khmel): Move this to IsArcAllowedForProfile. |
| 456 if (policy_util::IsArcDisabledForEnterprise() && | 377 if (policy_util::IsArcDisabledForEnterprise() && |
| 457 policy_util::IsAccountManaged(profile)) { | 378 policy_util::IsAccountManaged(profile)) { |
| 458 VLOG(2) << "Enterprise users are not supported in ARC."; | 379 VLOG(2) << "Enterprise users are not supported in ARC."; |
| 459 return; | 380 return; |
| 460 } | 381 } |
| 461 | 382 |
| 462 profile_ = profile; | 383 profile_ = profile; |
| 463 | 384 |
| 464 // Create the support host at initialization. Note that, practically, | 385 // Create the support host at initialization. Note that, practically, |
| 465 // ARC support Chrome app is rarely used (only opt-in and re-auth flow). | 386 // ARC support Chrome app is rarely used (only opt-in and re-auth flow). |
| 466 // So, it may be better to initialize it lazily. | 387 // So, it may be better to initialize it lazily. |
| 467 // TODO(hidehiko): Revisit to think about lazy initialization. | 388 // TODO(hidehiko): Revisit to think about lazy initialization. |
| 468 // | 389 // |
| 469 // Don't show UI for ARC Kiosk because the only one UI in kiosk mode must | 390 // Don't show UI for ARC Kiosk because the only one UI in kiosk mode must |
| 470 // be the kiosk app. In case of error the UI will be useless as well, because | 391 // be the kiosk app. In case of error the UI will be useless as well, because |
| 471 // in typical use case there will be no one nearby the kiosk device, who can | 392 // in typical use case there will be no one nearby the kiosk device, who can |
| 472 // do some action to solve the problem be means of UI. | 393 // do some action to solve the problem be means of UI. |
| 473 if (!g_disable_ui_for_testing && !IsOptInVerificationDisabled() && | 394 if (!g_disable_ui_for_testing && !IsArcOptInVerificationDisabled() && |
| 474 !IsArcKioskMode()) { | 395 !IsArcKioskMode()) { |
| 475 DCHECK(!support_host_); | 396 DCHECK(!support_host_); |
| 476 support_host_ = base::MakeUnique<ArcSupportHost>(profile_); | 397 support_host_ = base::MakeUnique<ArcSupportHost>(profile_); |
| 477 support_host_->AddObserver(this); | 398 support_host_->AddObserver(this); |
| 478 } | 399 } |
| 479 | 400 |
| 480 DCHECK_EQ(State::NOT_INITIALIZED, state_); | 401 DCHECK_EQ(State::NOT_INITIALIZED, state_); |
| 481 SetState(State::STOPPED); | 402 SetState(State::STOPPED); |
| 482 | 403 |
| 483 PrefServiceSyncableFromProfile(profile_)->AddSyncedPrefObserver( | 404 PrefServiceSyncableFromProfile(profile_)->AddSyncedPrefObserver( |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 // TODO(poromov): Move to more Kiosk dedicated set-up phase. | 546 // TODO(poromov): Move to more Kiosk dedicated set-up phase. |
| 626 if (IsArcKioskMode()) | 547 if (IsArcKioskMode()) |
| 627 profile_->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true); | 548 profile_->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, true); |
| 628 | 549 |
| 629 // If it is marked that sign in has been successfully done, then directly | 550 // If it is marked that sign in has been successfully done, then directly |
| 630 // start ARC. | 551 // start ARC. |
| 631 // For testing, and for Kisok mode, we also skip ToS negotiation procedure. | 552 // For testing, and for Kisok mode, we also skip ToS negotiation procedure. |
| 632 // For backward compatibility, this check needs to be prior to the | 553 // For backward compatibility, this check needs to be prior to the |
| 633 // kArcTermsAccepted check below. | 554 // kArcTermsAccepted check below. |
| 634 if (profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn) || | 555 if (profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn) || |
| 635 IsOptInVerificationDisabled() || IsArcKioskMode()) { | 556 IsArcOptInVerificationDisabled() || IsArcKioskMode()) { |
| 636 StartArc(); | 557 StartArc(); |
| 637 | 558 |
| 638 // Skip Android management check for testing. | 559 // Skip Android management check for testing. |
| 639 // We also skip if Android management check for Kiosk mode, | 560 // We also skip if Android management check for Kiosk mode, |
| 640 // because there are no managed human users for Kiosk exist. | 561 // because there are no managed human users for Kiosk exist. |
| 641 if (IsOptInVerificationDisabled() || IsArcKioskMode() || | 562 if (IsArcOptInVerificationDisabled() || IsArcKioskMode() || |
| 642 (g_disable_ui_for_testing && | 563 (g_disable_ui_for_testing && |
| 643 !g_enable_check_android_management_for_testing)) { | 564 !g_enable_check_android_management_for_testing)) { |
| 644 return; | 565 return; |
| 645 } | 566 } |
| 646 | 567 |
| 647 // Check Android management in parallel. | 568 // Check Android management in parallel. |
| 648 // Note: Because the callback may be called in synchronous way (i.e. called | 569 // Note: Because the callback may be called in synchronous way (i.e. called |
| 649 // on the same stack), StartCheck() needs to be called *after* StartArc(). | 570 // on the same stack), StartCheck() needs to be called *after* StartArc(). |
| 650 // Otherwise, DisableArc() which may be called in | 571 // Otherwise, DisableArc() which may be called in |
| 651 // OnBackgroundAndroidManagementChecked() could be ignored. | 572 // OnBackgroundAndroidManagementChecked() could be ignored. |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1020 return os << "ACTIVE"; | 941 return os << "ACTIVE"; |
| 1021 } | 942 } |
| 1022 | 943 |
| 1023 // Some compiler reports an error even if all values of an enum-class are | 944 // Some compiler reports an error even if all values of an enum-class are |
| 1024 // covered indivisually in a switch statement. | 945 // covered indivisually in a switch statement. |
| 1025 NOTREACHED(); | 946 NOTREACHED(); |
| 1026 return os; | 947 return os; |
| 1027 } | 948 } |
| 1028 | 949 |
| 1029 } // namespace arc | 950 } // namespace arc |
| OLD | NEW |