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