| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <memory> | |
| 6 #include <string> | |
| 7 #include <vector> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/command_line.h" | |
| 11 #include "base/files/file_path.h" | |
| 12 #include "base/files/file_util.h" | |
| 13 #include "base/files/scoped_temp_dir.h" | |
| 14 #include "base/macros.h" | |
| 15 #include "base/run_loop.h" | |
| 16 #include "chrome/browser/chromeos/arc/arc_auth_service.h" | |
| 17 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" | |
| 18 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" | |
| 19 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h" | |
| 20 #include "chrome/browser/chromeos/profiles/profile_helper.h" | |
| 21 #include "chrome/browser/prefs/pref_service_syncable_util.h" | |
| 22 #include "chrome/browser/profiles/profile.h" | |
| 23 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" | |
| 24 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" | |
| 25 #include "chrome/common/pref_names.h" | |
| 26 #include "chrome/test/base/testing_profile.h" | |
| 27 #include "chromeos/chromeos_switches.h" | |
| 28 #include "chromeos/dbus/dbus_thread_manager.h" | |
| 29 #include "components/arc/arc_bridge_service.h" | |
| 30 #include "components/arc/test/fake_arc_bridge_service.h" | |
| 31 #include "components/prefs/pref_service.h" | |
| 32 #include "components/signin/core/account_id/account_id.h" | |
| 33 #include "components/sync/model/fake_sync_change_processor.h" | |
| 34 #include "components/sync/model/sync_error_factory_mock.h" | |
| 35 #include "components/sync_preferences/testing_pref_service_syncable.h" | |
| 36 #include "components/user_manager/user_manager.h" | |
| 37 #include "components/user_manager/user_names.h" | |
| 38 #include "content/public/browser/browser_thread.h" | |
| 39 #include "content/public/test/test_browser_thread_bundle.h" | |
| 40 #include "google_apis/gaia/gaia_constants.h" | |
| 41 #include "google_apis/gaia/gaia_urls.h" | |
| 42 #include "net/http/http_status_code.h" | |
| 43 #include "testing/gtest/include/gtest/gtest.h" | |
| 44 | |
| 45 namespace arc { | |
| 46 | |
| 47 class ArcAuthServiceTest : public testing::Test { | |
| 48 public: | |
| 49 ArcAuthServiceTest() | |
| 50 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), | |
| 51 user_manager_enabler_(new chromeos::FakeChromeUserManager) {} | |
| 52 ~ArcAuthServiceTest() override = default; | |
| 53 | |
| 54 void SetUp() override { | |
| 55 chromeos::DBusThreadManager::Initialize(); | |
| 56 | |
| 57 base::CommandLine::ForCurrentProcess()->AppendSwitch( | |
| 58 chromeos::switches::kEnableArc); | |
| 59 ArcAuthService::DisableUIForTesting(); | |
| 60 | |
| 61 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); | |
| 62 TestingProfile::Builder profile_builder; | |
| 63 profile_builder.SetPath(temp_dir_.GetPath().AppendASCII("TestArcProfile")); | |
| 64 | |
| 65 profile_ = profile_builder.Build(); | |
| 66 StartPreferenceSyncing(); | |
| 67 | |
| 68 bridge_service_.reset(new FakeArcBridgeService()); | |
| 69 auth_service_.reset(new ArcAuthService(bridge_service_.get())); | |
| 70 | |
| 71 // Check initial conditions. | |
| 72 EXPECT_EQ(bridge_service_.get(), ArcBridgeService::Get()); | |
| 73 EXPECT_TRUE(ArcBridgeService::Get()->stopped()); | |
| 74 | |
| 75 const AccountId account_id( | |
| 76 AccountId::FromUserEmailGaiaId("user@gmail.com", "1234567890")); | |
| 77 GetFakeUserManager()->AddUser(account_id); | |
| 78 GetFakeUserManager()->LoginUser(account_id); | |
| 79 | |
| 80 chromeos::WallpaperManager::Initialize(); | |
| 81 } | |
| 82 | |
| 83 void TearDown() override { | |
| 84 chromeos::WallpaperManager::Shutdown(); | |
| 85 chromeos::DBusThreadManager::Shutdown(); | |
| 86 } | |
| 87 | |
| 88 chromeos::FakeChromeUserManager* GetFakeUserManager() const { | |
| 89 return static_cast<chromeos::FakeChromeUserManager*>( | |
| 90 user_manager::UserManager::Get()); | |
| 91 } | |
| 92 | |
| 93 protected: | |
| 94 Profile* profile() { return profile_.get(); } | |
| 95 FakeArcBridgeService* bridge_service() { return bridge_service_.get(); } | |
| 96 ArcAuthService* auth_service() { return auth_service_.get(); } | |
| 97 | |
| 98 private: | |
| 99 void StartPreferenceSyncing() const { | |
| 100 PrefServiceSyncableFromProfile(profile_.get()) | |
| 101 ->GetSyncableService(syncer::PREFERENCES) | |
| 102 ->MergeDataAndStartSyncing(syncer::PREFERENCES, syncer::SyncDataList(), | |
| 103 std::unique_ptr<syncer::SyncChangeProcessor>( | |
| 104 new syncer::FakeSyncChangeProcessor), | |
| 105 std::unique_ptr<syncer::SyncErrorFactory>( | |
| 106 new syncer::SyncErrorFactoryMock())); | |
| 107 } | |
| 108 | |
| 109 content::TestBrowserThreadBundle thread_bundle_; | |
| 110 std::unique_ptr<FakeArcBridgeService> bridge_service_; | |
| 111 std::unique_ptr<TestingProfile> profile_; | |
| 112 std::unique_ptr<ArcAuthService> auth_service_; | |
| 113 chromeos::ScopedUserManagerEnabler user_manager_enabler_; | |
| 114 base::ScopedTempDir temp_dir_; | |
| 115 | |
| 116 DISALLOW_COPY_AND_ASSIGN(ArcAuthServiceTest); | |
| 117 }; | |
| 118 | |
| 119 TEST_F(ArcAuthServiceTest, PrefChangeTriggersService) { | |
| 120 ASSERT_EQ(ArcAuthService::State::NOT_INITIALIZED, auth_service()->state()); | |
| 121 | |
| 122 PrefService* const pref = profile()->GetPrefs(); | |
| 123 ASSERT_FALSE(pref->GetBoolean(prefs::kArcEnabled)); | |
| 124 | |
| 125 auth_service()->OnPrimaryUserProfilePrepared(profile()); | |
| 126 ASSERT_EQ(ArcAuthService::State::STOPPED, auth_service()->state()); | |
| 127 | |
| 128 pref->SetBoolean(prefs::kArcEnabled, true); | |
| 129 ASSERT_EQ(ArcAuthService::State::SHOWING_TERMS_OF_SERVICE, | |
| 130 auth_service()->state()); | |
| 131 | |
| 132 pref->SetBoolean(prefs::kArcEnabled, false); | |
| 133 ASSERT_EQ(ArcAuthService::State::STOPPED, auth_service()->state()); | |
| 134 | |
| 135 // Correctly stop service. | |
| 136 auth_service()->Shutdown(); | |
| 137 } | |
| 138 | |
| 139 TEST_F(ArcAuthServiceTest, DisabledForEphemeralDataUsers) { | |
| 140 PrefService* const prefs = profile()->GetPrefs(); | |
| 141 EXPECT_FALSE(prefs->GetBoolean(prefs::kArcSignedIn)); | |
| 142 prefs->SetBoolean(prefs::kArcEnabled, true); | |
| 143 | |
| 144 chromeos::FakeChromeUserManager* const fake_user_manager = | |
| 145 GetFakeUserManager(); | |
| 146 | |
| 147 fake_user_manager->AddUser(fake_user_manager->GetGuestAccountId()); | |
| 148 fake_user_manager->SwitchActiveUser(fake_user_manager->GetGuestAccountId()); | |
| 149 auth_service()->OnPrimaryUserProfilePrepared(profile()); | |
| 150 ASSERT_EQ(ArcAuthService::State::NOT_INITIALIZED, auth_service()->state()); | |
| 151 | |
| 152 fake_user_manager->AddUser(user_manager::DemoAccountId()); | |
| 153 fake_user_manager->SwitchActiveUser(user_manager::DemoAccountId()); | |
| 154 auth_service()->Shutdown(); | |
| 155 auth_service()->OnPrimaryUserProfilePrepared(profile()); | |
| 156 ASSERT_EQ(ArcAuthService::State::NOT_INITIALIZED, auth_service()->state()); | |
| 157 | |
| 158 const AccountId public_account_id( | |
| 159 AccountId::FromUserEmail("public_user@gmail.com")); | |
| 160 fake_user_manager->AddPublicAccountUser(public_account_id); | |
| 161 fake_user_manager->SwitchActiveUser(public_account_id); | |
| 162 auth_service()->Shutdown(); | |
| 163 auth_service()->OnPrimaryUserProfilePrepared(profile()); | |
| 164 ASSERT_EQ(ArcAuthService::State::NOT_INITIALIZED, auth_service()->state()); | |
| 165 | |
| 166 const AccountId not_in_list_account_id( | |
| 167 AccountId::FromUserEmail("not_in_list_user@gmail.com")); | |
| 168 fake_user_manager->set_ephemeral_users_enabled(true); | |
| 169 fake_user_manager->AddUser(not_in_list_account_id); | |
| 170 fake_user_manager->SwitchActiveUser(not_in_list_account_id); | |
| 171 fake_user_manager->RemoveUserFromList(not_in_list_account_id); | |
| 172 auth_service()->Shutdown(); | |
| 173 auth_service()->OnPrimaryUserProfilePrepared(profile()); | |
| 174 ASSERT_EQ(ArcAuthService::State::NOT_INITIALIZED, auth_service()->state()); | |
| 175 | |
| 176 // Correctly stop service. | |
| 177 auth_service()->Shutdown(); | |
| 178 } | |
| 179 | |
| 180 TEST_F(ArcAuthServiceTest, BaseWorkflow) { | |
| 181 ASSERT_FALSE(bridge_service()->ready()); | |
| 182 ASSERT_EQ(ArcAuthService::State::NOT_INITIALIZED, auth_service()->state()); | |
| 183 | |
| 184 auth_service()->OnPrimaryUserProfilePrepared(profile()); | |
| 185 | |
| 186 // By default ARC is not enabled. | |
| 187 ASSERT_EQ(ArcAuthService::State::STOPPED, auth_service()->state()); | |
| 188 | |
| 189 profile()->GetPrefs()->SetBoolean(prefs::kArcEnabled, true); | |
| 190 | |
| 191 // Setting profile and pref initiates a code fetching process. | |
| 192 ASSERT_EQ(ArcAuthService::State::SHOWING_TERMS_OF_SERVICE, | |
| 193 auth_service()->state()); | |
| 194 | |
| 195 // TODO(hidehiko): Verify state transition from SHOWING_TERMS_OF_SERVICE -> | |
| 196 // CHECKING_ANDROID_MANAGEMENT, when we extract ArcSessionManager. | |
| 197 auth_service()->StartArc(); | |
| 198 | |
| 199 ASSERT_EQ(ArcAuthService::State::ACTIVE, auth_service()->state()); | |
| 200 ASSERT_TRUE(bridge_service()->ready()); | |
| 201 | |
| 202 auth_service()->Shutdown(); | |
| 203 ASSERT_EQ(ArcAuthService::State::NOT_INITIALIZED, auth_service()->state()); | |
| 204 ASSERT_FALSE(bridge_service()->ready()); | |
| 205 | |
| 206 // Send profile and don't provide a code. | |
| 207 auth_service()->OnPrimaryUserProfilePrepared(profile()); | |
| 208 | |
| 209 // Setting profile initiates a code fetching process. | |
| 210 ASSERT_EQ(ArcAuthService::State::SHOWING_TERMS_OF_SERVICE, | |
| 211 auth_service()->state()); | |
| 212 | |
| 213 content::BrowserThread::GetBlockingPool()->FlushForTesting(); | |
| 214 base::RunLoop().RunUntilIdle(); | |
| 215 | |
| 216 // UI is disabled in unit tests and this code is unchanged. | |
| 217 ASSERT_EQ(ArcAuthService::State::SHOWING_TERMS_OF_SERVICE, | |
| 218 auth_service()->state()); | |
| 219 | |
| 220 // Correctly stop service. | |
| 221 auth_service()->Shutdown(); | |
| 222 } | |
| 223 | |
| 224 TEST_F(ArcAuthServiceTest, CancelFetchingDisablesArc) { | |
| 225 PrefService* const pref = profile()->GetPrefs(); | |
| 226 | |
| 227 auth_service()->OnPrimaryUserProfilePrepared(profile()); | |
| 228 pref->SetBoolean(prefs::kArcEnabled, true); | |
| 229 ASSERT_EQ(ArcAuthService::State::SHOWING_TERMS_OF_SERVICE, | |
| 230 auth_service()->state()); | |
| 231 | |
| 232 auth_service()->CancelAuthCode(); | |
| 233 ASSERT_EQ(ArcAuthService::State::STOPPED, auth_service()->state()); | |
| 234 ASSERT_FALSE(pref->GetBoolean(prefs::kArcEnabled)); | |
| 235 | |
| 236 // Correctly stop service. | |
| 237 auth_service()->Shutdown(); | |
| 238 } | |
| 239 | |
| 240 TEST_F(ArcAuthServiceTest, CloseUIKeepsArcEnabled) { | |
| 241 PrefService* const pref = profile()->GetPrefs(); | |
| 242 | |
| 243 auth_service()->OnPrimaryUserProfilePrepared(profile()); | |
| 244 pref->SetBoolean(prefs::kArcEnabled, true); | |
| 245 | |
| 246 auth_service()->StartArc(); | |
| 247 | |
| 248 ASSERT_EQ(ArcAuthService::State::ACTIVE, auth_service()->state()); | |
| 249 | |
| 250 auth_service()->CancelAuthCode(); | |
| 251 ASSERT_EQ(ArcAuthService::State::ACTIVE, auth_service()->state()); | |
| 252 ASSERT_TRUE(pref->GetBoolean(prefs::kArcEnabled)); | |
| 253 | |
| 254 // Correctly stop service. | |
| 255 auth_service()->Shutdown(); | |
| 256 } | |
| 257 | |
| 258 TEST_F(ArcAuthServiceTest, EnableDisablesArc) { | |
| 259 const PrefService* pref = profile()->GetPrefs(); | |
| 260 auth_service()->OnPrimaryUserProfilePrepared(profile()); | |
| 261 | |
| 262 EXPECT_FALSE(pref->GetBoolean(prefs::kArcEnabled)); | |
| 263 auth_service()->EnableArc(); | |
| 264 EXPECT_TRUE(pref->GetBoolean(prefs::kArcEnabled)); | |
| 265 auth_service()->DisableArc(); | |
| 266 EXPECT_FALSE(pref->GetBoolean(prefs::kArcEnabled)); | |
| 267 | |
| 268 // Correctly stop service. | |
| 269 auth_service()->Shutdown(); | |
| 270 } | |
| 271 | |
| 272 TEST_F(ArcAuthServiceTest, SignInStatus) { | |
| 273 PrefService* const prefs = profile()->GetPrefs(); | |
| 274 | |
| 275 EXPECT_FALSE(prefs->GetBoolean(prefs::kArcSignedIn)); | |
| 276 prefs->SetBoolean(prefs::kArcEnabled, true); | |
| 277 | |
| 278 auth_service()->OnPrimaryUserProfilePrepared(profile()); | |
| 279 EXPECT_EQ(ArcAuthService::State::SHOWING_TERMS_OF_SERVICE, | |
| 280 auth_service()->state()); | |
| 281 auth_service()->StartArc(); | |
| 282 EXPECT_EQ(ArcAuthService::State::ACTIVE, auth_service()->state()); | |
| 283 EXPECT_TRUE(bridge_service()->ready()); | |
| 284 EXPECT_FALSE(prefs->GetBoolean(prefs::kArcSignedIn)); | |
| 285 auth_service()->OnSignInComplete(); | |
| 286 EXPECT_TRUE(prefs->GetBoolean(prefs::kArcSignedIn)); | |
| 287 EXPECT_EQ(ArcAuthService::State::ACTIVE, auth_service()->state()); | |
| 288 EXPECT_TRUE(bridge_service()->ready()); | |
| 289 | |
| 290 // Second start, no fetching code is expected. | |
| 291 auth_service()->Shutdown(); | |
| 292 EXPECT_EQ(ArcAuthService::State::NOT_INITIALIZED, auth_service()->state()); | |
| 293 EXPECT_FALSE(bridge_service()->ready()); | |
| 294 auth_service()->OnPrimaryUserProfilePrepared(profile()); | |
| 295 EXPECT_TRUE(prefs->GetBoolean(prefs::kArcSignedIn)); | |
| 296 EXPECT_EQ(ArcAuthService::State::ACTIVE, auth_service()->state()); | |
| 297 EXPECT_TRUE(bridge_service()->ready()); | |
| 298 | |
| 299 // Report failure. | |
| 300 auth_service()->OnSignInFailed( | |
| 301 mojom::ArcSignInFailureReason::GMS_NETWORK_ERROR); | |
| 302 // On error, UI to send feedback is showing. In that case, | |
| 303 // the ARC is still necessary to run on background for gathering the logs. | |
| 304 EXPECT_TRUE(prefs->GetBoolean(prefs::kArcSignedIn)); | |
| 305 EXPECT_EQ(ArcAuthService::State::ACTIVE, auth_service()->state()); | |
| 306 EXPECT_TRUE(bridge_service()->ready()); | |
| 307 | |
| 308 // Correctly stop service. | |
| 309 auth_service()->Shutdown(); | |
| 310 } | |
| 311 | |
| 312 TEST_F(ArcAuthServiceTest, DisabledForDeviceLocalAccount) { | |
| 313 PrefService* const prefs = profile()->GetPrefs(); | |
| 314 EXPECT_FALSE(prefs->GetBoolean(prefs::kArcSignedIn)); | |
| 315 prefs->SetBoolean(prefs::kArcEnabled, true); | |
| 316 auth_service()->OnPrimaryUserProfilePrepared(profile()); | |
| 317 auth_service()->StartArc(); | |
| 318 EXPECT_EQ(ArcAuthService::State::ACTIVE, auth_service()->state()); | |
| 319 | |
| 320 // Create device local account and set it as active. | |
| 321 const std::string email = "device-local-account@fake-email.com"; | |
| 322 TestingProfile::Builder profile_builder; | |
| 323 profile_builder.SetProfileName(email); | |
| 324 std::unique_ptr<TestingProfile> device_local_profile(profile_builder.Build()); | |
| 325 const AccountId account_id(AccountId::FromUserEmail(email)); | |
| 326 GetFakeUserManager()->AddPublicAccountUser(account_id); | |
| 327 | |
| 328 // Remove |profile_| to set the device local account be the primary account. | |
| 329 GetFakeUserManager()->RemoveUserFromList( | |
| 330 multi_user_util::GetAccountIdFromProfile(profile())); | |
| 331 GetFakeUserManager()->LoginUser(account_id); | |
| 332 | |
| 333 // Check that user without GAIA account can't use ARC. | |
| 334 device_local_profile->GetPrefs()->SetBoolean(prefs::kArcEnabled, true); | |
| 335 auth_service()->OnPrimaryUserProfilePrepared(device_local_profile.get()); | |
| 336 EXPECT_EQ(ArcAuthService::State::NOT_INITIALIZED, auth_service()->state()); | |
| 337 | |
| 338 // Correctly stop service. | |
| 339 auth_service()->Shutdown(); | |
| 340 } | |
| 341 | |
| 342 TEST_F(ArcAuthServiceTest, DisabledForNonPrimaryProfile) { | |
| 343 profile()->GetPrefs()->SetBoolean(prefs::kArcEnabled, true); | |
| 344 auth_service()->OnPrimaryUserProfilePrepared(profile()); | |
| 345 auth_service()->StartArc(); | |
| 346 EXPECT_EQ(ArcAuthService::State::ACTIVE, auth_service()->state()); | |
| 347 | |
| 348 // Create a second profile and set it as the active profile. | |
| 349 const std::string email = "test@example.com"; | |
| 350 TestingProfile::Builder profile_builder; | |
| 351 profile_builder.SetProfileName(email); | |
| 352 std::unique_ptr<TestingProfile> second_profile(profile_builder.Build()); | |
| 353 const AccountId account_id(AccountId::FromUserEmail(email)); | |
| 354 GetFakeUserManager()->AddUser(account_id); | |
| 355 GetFakeUserManager()->SwitchActiveUser(account_id); | |
| 356 second_profile->GetPrefs()->SetBoolean(prefs::kArcEnabled, true); | |
| 357 | |
| 358 // Check that non-primary user can't use Arc. | |
| 359 EXPECT_FALSE(chromeos::ProfileHelper::IsPrimaryProfile(second_profile.get())); | |
| 360 EXPECT_FALSE(ArcAppListPrefs::Get(second_profile.get())); | |
| 361 | |
| 362 auth_service()->Shutdown(); | |
| 363 } | |
| 364 | |
| 365 } // namespace arc | |
| OLD | NEW |