1 // Copyright 2018 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
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/run_loop.h"
10 #include "base/test/task_environment.h"
11 #include "chromeos/components/multidevice/remote_device_test_util.h"
12 #include "chromeos/services/device_sync/public/cpp/fake_device_sync_client.h"
13 #include "chromeos/services/device_sync/public/cpp/fake_gcm_device_info_provider.h"
14 #include "chromeos/services/multidevice_setup/fake_account_status_change_delegate.h"
15 #include "chromeos/services/multidevice_setup/fake_feature_state_observer.h"
16 #include "chromeos/services/multidevice_setup/fake_host_status_observer.h"
17 #include "chromeos/services/multidevice_setup/multidevice_setup_impl.h"
18 #include "chromeos/services/multidevice_setup/multidevice_setup_service.h"
19 #include "chromeos/services/multidevice_setup/public/cpp/fake_android_sms_app_helper_delegate.h"
20 #include "chromeos/services/multidevice_setup/public/cpp/fake_android_sms_pairing_state_tracker.h"
21 #include "chromeos/services/multidevice_setup/public/cpp/fake_auth_token_validator.h"
22 #include "chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup.h"
23 #include "chromeos/services/multidevice_setup/public/cpp/oobe_completion_tracker.h"
24 #include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h"
25 #include "components/sync_preferences/testing_pref_service_syncable.h"
26 #include "mojo/public/cpp/bindings/remote.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28
29 namespace chromeos {
30
31 namespace multidevice_setup {
32
33 namespace {
34
35 const size_t kNumTestDevices = 3;
36
37 class FakeMultiDeviceSetupFactory : public MultiDeviceSetupImpl::Factory {
38 public:
FakeMultiDeviceSetupFactory(sync_preferences::TestingPrefServiceSyncable * expected_testing_pref_service,device_sync::FakeDeviceSyncClient * expected_device_sync_client,FakeAuthTokenValidator * expected_auth_token_validator,OobeCompletionTracker * expected_oobe_completion_tracker,FakeAndroidSmsAppHelperDelegate * expected_android_sms_app_helper_delegate,FakeAndroidSmsPairingStateTracker * expected_android_sms_pairing_state_tracker,const device_sync::FakeGcmDeviceInfoProvider * expected_gcm_device_info_provider)39 FakeMultiDeviceSetupFactory(
40 sync_preferences::TestingPrefServiceSyncable*
41 expected_testing_pref_service,
42 device_sync::FakeDeviceSyncClient* expected_device_sync_client,
43 FakeAuthTokenValidator* expected_auth_token_validator,
44 OobeCompletionTracker* expected_oobe_completion_tracker,
45 FakeAndroidSmsAppHelperDelegate* expected_android_sms_app_helper_delegate,
46 FakeAndroidSmsPairingStateTracker*
47 expected_android_sms_pairing_state_tracker,
48 const device_sync::FakeGcmDeviceInfoProvider*
49 expected_gcm_device_info_provider)
50 : expected_testing_pref_service_(expected_testing_pref_service),
51 expected_device_sync_client_(expected_device_sync_client),
52 expected_auth_token_validator_(expected_auth_token_validator),
53 expected_oobe_completion_tracker_(expected_oobe_completion_tracker),
54 expected_android_sms_app_helper_delegate_(
55 expected_android_sms_app_helper_delegate),
56 expected_android_sms_pairing_state_tracker_(
57 expected_android_sms_pairing_state_tracker),
58 expected_gcm_device_info_provider_(expected_gcm_device_info_provider) {}
59
60 ~FakeMultiDeviceSetupFactory() override = default;
61
instance()62 FakeMultiDeviceSetup* instance() { return instance_; }
63
64 private:
CreateInstance(PrefService * pref_service,device_sync::DeviceSyncClient * device_sync_client,AuthTokenValidator * auth_token_validator,OobeCompletionTracker * oobe_completion_tracker,AndroidSmsAppHelperDelegate * android_sms_app_helper_delegate,AndroidSmsPairingStateTracker * android_sms_pairing_state_tracker,const device_sync::GcmDeviceInfoProvider * gcm_device_info_provider)65 std::unique_ptr<MultiDeviceSetupBase> CreateInstance(
66 PrefService* pref_service,
67 device_sync::DeviceSyncClient* device_sync_client,
68 AuthTokenValidator* auth_token_validator,
69 OobeCompletionTracker* oobe_completion_tracker,
70 AndroidSmsAppHelperDelegate* android_sms_app_helper_delegate,
71 AndroidSmsPairingStateTracker* android_sms_pairing_state_tracker,
72 const device_sync::GcmDeviceInfoProvider* gcm_device_info_provider)
73 override {
74 EXPECT_FALSE(instance_);
75 EXPECT_EQ(expected_testing_pref_service_, pref_service);
76 EXPECT_EQ(expected_device_sync_client_, device_sync_client);
77 EXPECT_EQ(expected_auth_token_validator_, auth_token_validator);
78 EXPECT_EQ(expected_oobe_completion_tracker_, oobe_completion_tracker);
79 EXPECT_EQ(expected_android_sms_app_helper_delegate_,
80 android_sms_app_helper_delegate);
81 EXPECT_EQ(expected_android_sms_pairing_state_tracker_,
82 android_sms_pairing_state_tracker);
83 EXPECT_EQ(expected_gcm_device_info_provider_, gcm_device_info_provider);
84
85 auto instance = std::make_unique<FakeMultiDeviceSetup>();
86 instance_ = instance.get();
87 return instance;
88 }
89
90 sync_preferences::TestingPrefServiceSyncable* expected_testing_pref_service_;
91 device_sync::FakeDeviceSyncClient* expected_device_sync_client_;
92 FakeAuthTokenValidator* expected_auth_token_validator_;
93 OobeCompletionTracker* expected_oobe_completion_tracker_;
94 FakeAndroidSmsAppHelperDelegate* expected_android_sms_app_helper_delegate_;
95 FakeAndroidSmsPairingStateTracker*
96 expected_android_sms_pairing_state_tracker_;
97 const device_sync::FakeGcmDeviceInfoProvider*
98 expected_gcm_device_info_provider_;
99
100 FakeMultiDeviceSetup* instance_ = nullptr;
101
102 DISALLOW_COPY_AND_ASSIGN(FakeMultiDeviceSetupFactory);
103 };
104
105 } // namespace
106
107 class MultiDeviceSetupServiceTest : public testing::Test {
108 protected:
MultiDeviceSetupServiceTest()109 MultiDeviceSetupServiceTest()
110 : test_devices_(
111 multidevice::CreateRemoteDeviceRefListForTest(kNumTestDevices)) {}
112 ~MultiDeviceSetupServiceTest() override = default;
113
114 // testing::Test:
SetUp()115 void SetUp() override {
116 test_pref_service_ =
117 std::make_unique<sync_preferences::TestingPrefServiceSyncable>();
118 fake_device_sync_client_ =
119 std::make_unique<device_sync::FakeDeviceSyncClient>();
120 fake_auth_token_validator_ = std::make_unique<FakeAuthTokenValidator>();
121 fake_oobe_completion_tracker_ = std::make_unique<OobeCompletionTracker>();
122 fake_android_sms_app_helper_delegate_ =
123 std::make_unique<FakeAndroidSmsAppHelperDelegate>();
124 fake_android_sms_pairing_state_tracker_ =
125 std::make_unique<FakeAndroidSmsPairingStateTracker>();
126 fake_gcm_device_info_provider_ =
127 std::make_unique<device_sync::FakeGcmDeviceInfoProvider>(
128 cryptauth::GcmDeviceInfo());
129
130 fake_multidevice_setup_factory_ =
131 std::make_unique<FakeMultiDeviceSetupFactory>(
132 test_pref_service_.get(), fake_device_sync_client_.get(),
133 fake_auth_token_validator_.get(),
134 fake_oobe_completion_tracker_.get(),
135 fake_android_sms_app_helper_delegate_.get(),
136 fake_android_sms_pairing_state_tracker_.get(),
137 fake_gcm_device_info_provider_.get());
138 MultiDeviceSetupImpl::Factory::SetFactoryForTesting(
139 fake_multidevice_setup_factory_.get());
140
141 service_ = std::make_unique<MultiDeviceSetupService>(
142 test_pref_service_.get(), fake_device_sync_client_.get(),
143 fake_auth_token_validator_.get(), fake_oobe_completion_tracker_.get(),
144 fake_android_sms_app_helper_delegate_.get(),
145 fake_android_sms_pairing_state_tracker_.get(),
146 fake_gcm_device_info_provider_.get());
147
148 service_->BindMultiDeviceSetup(
149 multidevice_setup_remote_.BindNewPipeAndPassReceiver());
150 service_->BindPrivilegedHostDeviceSetter(
151 privileged_host_device_setter_remote_.BindNewPipeAndPassReceiver());
152 }
153
TearDown()154 void TearDown() override {
155 MultiDeviceSetupImpl::Factory::SetFactoryForTesting(nullptr);
156 }
157
CallTriggerEventForDebuggingBeforeInitializationComplete(mojom::EventTypeForDebugging type)158 void CallTriggerEventForDebuggingBeforeInitializationComplete(
159 mojom::EventTypeForDebugging type) {
160 EXPECT_FALSE(last_debug_event_success_);
161
162 base::RunLoop run_loop;
163 multidevice_setup_remote_->TriggerEventForDebugging(
164 type,
165 base::BindOnce(&MultiDeviceSetupServiceTest::OnDebugEventTriggered,
166 base::Unretained(this), run_loop.QuitClosure()));
167 run_loop.Run();
168
169 // Always expected to fail before initialization completes.
170 EXPECT_FALSE(*last_debug_event_success_);
171 last_debug_event_success_.reset();
172 }
173
FinishInitialization()174 void FinishInitialization() {
175 EXPECT_FALSE(fake_multidevice_setup());
176 fake_device_sync_client_->set_local_device_metadata(test_devices_[0]);
177 fake_device_sync_client_->NotifyReady();
178 EXPECT_TRUE(fake_multidevice_setup());
179 }
180
fake_multidevice_setup()181 FakeMultiDeviceSetup* fake_multidevice_setup() {
182 return fake_multidevice_setup_factory_->instance();
183 }
184
multidevice_setup_remote()185 mojo::Remote<mojom::MultiDeviceSetup>& multidevice_setup_remote() {
186 return multidevice_setup_remote_;
187 }
188
189 mojo::Remote<mojom::PrivilegedHostDeviceSetter>&
privileged_host_device_setter_remote()190 privileged_host_device_setter_remote() {
191 return privileged_host_device_setter_remote_;
192 }
193
194 private:
OnDebugEventTriggered(base::OnceClosure quit_closure,bool success)195 void OnDebugEventTriggered(base::OnceClosure quit_closure, bool success) {
196 last_debug_event_success_ = success;
197 std::move(quit_closure).Run();
198 }
199
200 base::test::TaskEnvironment task_environment_;
201 const multidevice::RemoteDeviceRefList test_devices_;
202
203 std::unique_ptr<sync_preferences::TestingPrefServiceSyncable>
204 test_pref_service_;
205 std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_;
206 std::unique_ptr<FakeAuthTokenValidator> fake_auth_token_validator_;
207 std::unique_ptr<OobeCompletionTracker> fake_oobe_completion_tracker_;
208 std::unique_ptr<FakeAndroidSmsAppHelperDelegate>
209 fake_android_sms_app_helper_delegate_;
210 std::unique_ptr<FakeAndroidSmsPairingStateTracker>
211 fake_android_sms_pairing_state_tracker_;
212 std::unique_ptr<device_sync::FakeGcmDeviceInfoProvider>
213 fake_gcm_device_info_provider_;
214
215 std::unique_ptr<FakeMultiDeviceSetupFactory> fake_multidevice_setup_factory_;
216
217 std::unique_ptr<MultiDeviceSetupService> service_;
218 base::Optional<bool> last_debug_event_success_;
219
220 mojo::Remote<mojom::MultiDeviceSetup> multidevice_setup_remote_;
221 mojo::Remote<mojom::PrivilegedHostDeviceSetter>
222 privileged_host_device_setter_remote_;
223
224 DISALLOW_COPY_AND_ASSIGN(MultiDeviceSetupServiceTest);
225 };
226
TEST_F(MultiDeviceSetupServiceTest,TriggerEventForDebuggingBeforeInitialization)227 TEST_F(MultiDeviceSetupServiceTest,
228 TriggerEventForDebuggingBeforeInitialization) {
229 CallTriggerEventForDebuggingBeforeInitializationComplete(
230 mojom::EventTypeForDebugging::kNewUserPotentialHostExists);
231 CallTriggerEventForDebuggingBeforeInitializationComplete(
232 mojom::EventTypeForDebugging::kExistingUserConnectedHostSwitched);
233 CallTriggerEventForDebuggingBeforeInitializationComplete(
234 mojom::EventTypeForDebugging::kExistingUserNewChromebookAdded);
235 }
236
TEST_F(MultiDeviceSetupServiceTest,CallFunctionsBeforeInitialization)237 TEST_F(MultiDeviceSetupServiceTest, CallFunctionsBeforeInitialization) {
238 // SetAccountStatusChangeDelegate().
239 auto fake_account_status_change_delegate =
240 std::make_unique<FakeAccountStatusChangeDelegate>();
241 multidevice_setup_remote()->SetAccountStatusChangeDelegate(
242 fake_account_status_change_delegate->GenerateRemote());
243 multidevice_setup_remote().FlushForTesting();
244
245 // AddHostStatusObserver().
246 auto fake_host_status_observer = std::make_unique<FakeHostStatusObserver>();
247 multidevice_setup_remote()->AddHostStatusObserver(
248 fake_host_status_observer->GenerateRemote());
249 multidevice_setup_remote().FlushForTesting();
250
251 // AddFeatureStateObserver().
252 auto fake_feature_state_observer =
253 std::make_unique<FakeFeatureStateObserver>();
254 multidevice_setup_remote()->AddFeatureStateObserver(
255 fake_feature_state_observer->GenerateRemote());
256 multidevice_setup_remote().FlushForTesting();
257
258 // GetEligibleHostDevices().
259 multidevice_setup_remote()->GetEligibleHostDevices(base::DoNothing());
260 multidevice_setup_remote().FlushForTesting();
261
262 // GetHostStatus().
263 multidevice_setup_remote()->GetHostStatus(base::DoNothing());
264 multidevice_setup_remote().FlushForTesting();
265
266 // SetFeatureEnabledState().
267 multidevice_setup_remote()->SetFeatureEnabledState(
268 mojom::Feature::kBetterTogetherSuite, true /* enabled */, "authToken",
269 base::DoNothing());
270 multidevice_setup_remote().FlushForTesting();
271
272 // GetFeatureStates().
273 multidevice_setup_remote()->GetFeatureStates(base::DoNothing());
274 multidevice_setup_remote().FlushForTesting();
275
276 // RetrySetHostNow().
277 multidevice_setup_remote()->RetrySetHostNow(base::DoNothing());
278 multidevice_setup_remote().FlushForTesting();
279
280 // None of these requests should have been processed yet, since initialization
281 // was not complete.
282 EXPECT_FALSE(fake_multidevice_setup());
283
284 // Finish initialization; all of the pending calls should have been forwarded.
285 FinishInitialization();
286 EXPECT_TRUE(fake_multidevice_setup()->delegate());
287 EXPECT_TRUE(fake_multidevice_setup()->HasAtLeastOneHostStatusObserver());
288 EXPECT_TRUE(fake_multidevice_setup()->HasAtLeastOneFeatureStateObserver());
289 EXPECT_EQ(1u, fake_multidevice_setup()->get_eligible_hosts_args().size());
290 EXPECT_EQ(1u, fake_multidevice_setup()->get_host_args().size());
291 EXPECT_EQ(1u, fake_multidevice_setup()->set_feature_enabled_args().size());
292 EXPECT_EQ(1u, fake_multidevice_setup()->get_feature_states_args().size());
293 EXPECT_EQ(1u, fake_multidevice_setup()->retry_set_host_now_args().size());
294 }
295
TEST_F(MultiDeviceSetupServiceTest,SetThenRemoveBeforeInitialization)296 TEST_F(MultiDeviceSetupServiceTest, SetThenRemoveBeforeInitialization) {
297 multidevice_setup_remote()->SetHostDevice("id1", "authToken",
298 base::DoNothing());
299 multidevice_setup_remote().FlushForTesting();
300
301 privileged_host_device_setter_remote()->SetHostDevice("id2",
302 base::DoNothing());
303 privileged_host_device_setter_remote().FlushForTesting();
304
305 multidevice_setup_remote()->RemoveHostDevice();
306 multidevice_setup_remote().FlushForTesting();
307
308 EXPECT_FALSE(fake_multidevice_setup());
309
310 // Finish initialization; since the SetHostDevice() call was followed by a
311 // RemoveHostDevice() call, only the RemoveHostDevice() call should have been
312 // forwarded.
313 FinishInitialization();
314 EXPECT_TRUE(fake_multidevice_setup()->set_host_args().empty());
315 EXPECT_TRUE(fake_multidevice_setup()->set_host_without_auth_args().empty());
316 EXPECT_EQ(1u, fake_multidevice_setup()->num_remove_host_calls());
317 }
318
TEST_F(MultiDeviceSetupServiceTest,RemoveThenSetThenSetBeforeInitialization)319 TEST_F(MultiDeviceSetupServiceTest, RemoveThenSetThenSetBeforeInitialization) {
320 multidevice_setup_remote()->RemoveHostDevice();
321 multidevice_setup_remote().FlushForTesting();
322
323 privileged_host_device_setter_remote()->SetHostDevice("id1",
324 base::DoNothing());
325 privileged_host_device_setter_remote().FlushForTesting();
326
327 multidevice_setup_remote()->SetHostDevice("id2", "authToken2",
328 base::DoNothing());
329 multidevice_setup_remote().FlushForTesting();
330
331 multidevice_setup_remote()->SetHostDevice("id3", "authToken3",
332 base::DoNothing());
333 multidevice_setup_remote().FlushForTesting();
334
335 EXPECT_FALSE(fake_multidevice_setup());
336
337 // Finish initialization; only the second SetHostDevice() call should have
338 // been forwarded.
339 FinishInitialization();
340 EXPECT_EQ(0u, fake_multidevice_setup()->num_remove_host_calls());
341 EXPECT_TRUE(fake_multidevice_setup()->set_host_without_auth_args().empty());
342 EXPECT_EQ(1u, fake_multidevice_setup()->set_host_args().size());
343 EXPECT_EQ("id3", std::get<0>(fake_multidevice_setup()->set_host_args()[0]));
344 EXPECT_EQ("authToken3",
345 std::get<1>(fake_multidevice_setup()->set_host_args()[0]));
346 }
347
TEST_F(MultiDeviceSetupServiceTest,RemoveThenSetThenSetBeforeInitialization_NoAuthToken)348 TEST_F(MultiDeviceSetupServiceTest,
349 RemoveThenSetThenSetBeforeInitialization_NoAuthToken) {
350 multidevice_setup_remote()->RemoveHostDevice();
351 multidevice_setup_remote().FlushForTesting();
352
353 multidevice_setup_remote()->SetHostDevice("id1", "authToken1",
354 base::DoNothing());
355 multidevice_setup_remote().FlushForTesting();
356
357 multidevice_setup_remote()->SetHostDevice("id2", "authToken2",
358 base::DoNothing());
359 multidevice_setup_remote().FlushForTesting();
360
361 privileged_host_device_setter_remote()->SetHostDevice("id3",
362 base::DoNothing());
363 privileged_host_device_setter_remote().FlushForTesting();
364
365 EXPECT_FALSE(fake_multidevice_setup());
366
367 // Finish initialization; only the second SetHostDevice() call should have
368 // been forwarded.
369 FinishInitialization();
370 EXPECT_EQ(0u, fake_multidevice_setup()->num_remove_host_calls());
371 EXPECT_TRUE(fake_multidevice_setup()->set_host_args().empty());
372 EXPECT_EQ(1u, fake_multidevice_setup()->set_host_without_auth_args().size());
373 EXPECT_EQ("id3",
374 fake_multidevice_setup()->set_host_without_auth_args()[0].first);
375 }
376
TEST_F(MultiDeviceSetupServiceTest,FinishInitializationFirst)377 TEST_F(MultiDeviceSetupServiceTest, FinishInitializationFirst) {
378 // Finish initialization before calling anything; this should result in
379 // the calls being forwarded immediately.
380 FinishInitialization();
381
382 // SetAccountStatusChangeDelegate().
383 auto fake_account_status_change_delegate =
384 std::make_unique<FakeAccountStatusChangeDelegate>();
385 multidevice_setup_remote()->SetAccountStatusChangeDelegate(
386 fake_account_status_change_delegate->GenerateRemote());
387 multidevice_setup_remote().FlushForTesting();
388 EXPECT_TRUE(fake_multidevice_setup()->delegate());
389
390 // AddHostStatusObserver().
391 auto fake_host_status_observer = std::make_unique<FakeHostStatusObserver>();
392 multidevice_setup_remote()->AddHostStatusObserver(
393 fake_host_status_observer->GenerateRemote());
394 multidevice_setup_remote().FlushForTesting();
395 EXPECT_TRUE(fake_multidevice_setup()->HasAtLeastOneHostStatusObserver());
396
397 // AddFeatureStateObserver().
398 auto fake_feature_state_observer =
399 std::make_unique<FakeFeatureStateObserver>();
400 multidevice_setup_remote()->AddFeatureStateObserver(
401 fake_feature_state_observer->GenerateRemote());
402 multidevice_setup_remote().FlushForTesting();
403 EXPECT_TRUE(fake_multidevice_setup()->HasAtLeastOneFeatureStateObserver());
404
405 // GetEligibleHostDevices().
406 multidevice_setup_remote()->GetEligibleHostDevices(base::DoNothing());
407 multidevice_setup_remote().FlushForTesting();
408 EXPECT_EQ(1u, fake_multidevice_setup()->get_eligible_hosts_args().size());
409
410 // SetHostDevice().
411 multidevice_setup_remote()->SetHostDevice("id", "authToken",
412 base::DoNothing());
413 multidevice_setup_remote().FlushForTesting();
414 EXPECT_EQ(1u, fake_multidevice_setup()->set_host_args().size());
415
416 // RemoveHostDevice().
417 multidevice_setup_remote()->RemoveHostDevice();
418 multidevice_setup_remote().FlushForTesting();
419 EXPECT_EQ(1u, fake_multidevice_setup()->num_remove_host_calls());
420
421 // GetHostStatus().
422 multidevice_setup_remote()->GetHostStatus(base::DoNothing());
423 multidevice_setup_remote().FlushForTesting();
424 EXPECT_EQ(1u, fake_multidevice_setup()->get_host_args().size());
425
426 // SetFeatureEnabledState().
427 multidevice_setup_remote()->SetFeatureEnabledState(
428 mojom::Feature::kBetterTogetherSuite, true /* enabled */, "authToken",
429 base::DoNothing());
430 multidevice_setup_remote().FlushForTesting();
431 EXPECT_EQ(1u, fake_multidevice_setup()->set_feature_enabled_args().size());
432
433 // GetFeatureStates().
434 multidevice_setup_remote()->GetFeatureStates(base::DoNothing());
435 multidevice_setup_remote().FlushForTesting();
436 EXPECT_EQ(1u, fake_multidevice_setup()->get_feature_states_args().size());
437
438 // RetrySetHostNow().
439 multidevice_setup_remote()->RetrySetHostNow(base::DoNothing());
440 multidevice_setup_remote().FlushForTesting();
441 EXPECT_EQ(1u, fake_multidevice_setup()->retry_set_host_now_args().size());
442
443 // SetHostDevice(), without an auth token.
444 privileged_host_device_setter_remote()->SetHostDevice("id",
445 base::DoNothing());
446 privileged_host_device_setter_remote().FlushForTesting();
447 EXPECT_EQ(1u, fake_multidevice_setup()->set_host_without_auth_args().size());
448 }
449
450 } // namespace multidevice_setup
451
452 } // namespace chromeos
453