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