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 "chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h"
6 
7 #include <memory>
8 
9 #include "base/macros.h"
10 #include "base/test/scoped_feature_list.h"
11 #include "chrome/browser/chromeos/android_sms/android_sms_urls.h"
12 #include "chrome/browser/chromeos/android_sms/fake_android_sms_app_manager.h"
13 #include "chromeos/components/multidevice/remote_device_test_util.h"
14 #include "chromeos/components/phonehub/fake_notification_access_manager.h"
15 #include "chromeos/constants/chromeos_features.h"
16 #include "chromeos/services/multidevice_setup/public/cpp/fake_android_sms_pairing_state_tracker.h"
17 #include "chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup_client.h"
18 #include "components/content_settings/core/common/content_settings_pattern.h"
19 #include "components/prefs/testing_pref_service.h"
20 #include "content/public/test/test_web_ui.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 
23 namespace chromeos {
24 
25 namespace settings {
26 
27 namespace {
28 
29 class TestMultideviceHandler : public MultideviceHandler {
30  public:
TestMultideviceHandler(PrefService * prefs,multidevice_setup::MultiDeviceSetupClient * multidevice_setup_client,phonehub::NotificationAccessManager * notification_access_manager,multidevice_setup::AndroidSmsPairingStateTracker * android_sms_pairing_state_tracker,android_sms::AndroidSmsAppManager * android_sms_app_manager)31   TestMultideviceHandler(
32       PrefService* prefs,
33       multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
34       phonehub::NotificationAccessManager* notification_access_manager,
35       multidevice_setup::AndroidSmsPairingStateTracker*
36           android_sms_pairing_state_tracker,
37       android_sms::AndroidSmsAppManager* android_sms_app_manager)
38       : MultideviceHandler(prefs,
39                            multidevice_setup_client,
40                            notification_access_manager,
41                            android_sms_pairing_state_tracker,
42                            android_sms_app_manager) {}
43   ~TestMultideviceHandler() override = default;
44 
45   // Make public for testing.
46   using MultideviceHandler::AllowJavascript;
47   using MultideviceHandler::RegisterMessages;
48   using MultideviceHandler::set_web_ui;
49 };
50 
51 multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap
GenerateDefaultFeatureStatesMap()52 GenerateDefaultFeatureStatesMap() {
53   return multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap{
54       {multidevice_setup::mojom::Feature::kBetterTogetherSuite,
55        multidevice_setup::mojom::FeatureState::kUnavailableNoVerifiedHost},
56       {multidevice_setup::mojom::Feature::kInstantTethering,
57        multidevice_setup::mojom::FeatureState::kUnavailableNoVerifiedHost},
58       {multidevice_setup::mojom::Feature::kMessages,
59        multidevice_setup::mojom::FeatureState::kUnavailableNoVerifiedHost},
60       {multidevice_setup::mojom::Feature::kSmartLock,
61        multidevice_setup::mojom::FeatureState::kUnavailableNoVerifiedHost},
62       {multidevice_setup::mojom::Feature::kPhoneHub,
63        multidevice_setup::mojom::FeatureState::kUnavailableNoVerifiedHost},
64       {multidevice_setup::mojom::Feature::kPhoneHubNotifications,
65        multidevice_setup::mojom::FeatureState::kUnavailableNoVerifiedHost},
66       {multidevice_setup::mojom::Feature::kPhoneHubTaskContinuation,
67        multidevice_setup::mojom::FeatureState::kUnavailableNoVerifiedHost},
68       {multidevice_setup::mojom::Feature::kWifiSync,
69        multidevice_setup::mojom::FeatureState::kUnavailableNoVerifiedHost}};
70 }
71 
VerifyPageContentDict(const base::Value * value,multidevice_setup::mojom::HostStatus expected_host_status,const base::Optional<multidevice::RemoteDeviceRef> & expected_host_device,const multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap & feature_states_map)72 void VerifyPageContentDict(
73     const base::Value* value,
74     multidevice_setup::mojom::HostStatus expected_host_status,
75     const base::Optional<multidevice::RemoteDeviceRef>& expected_host_device,
76     const multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap&
77         feature_states_map) {
78   const base::DictionaryValue* page_content_dict;
79   EXPECT_TRUE(value->GetAsDictionary(&page_content_dict));
80 
81   int mode;
82   EXPECT_TRUE(page_content_dict->GetInteger("mode", &mode));
83   EXPECT_EQ(static_cast<int>(expected_host_status), mode);
84 
85   int better_together_state;
86   EXPECT_TRUE(page_content_dict->GetInteger("betterTogetherState",
87                                             &better_together_state));
88   auto it = feature_states_map.find(
89       multidevice_setup::mojom::Feature::kBetterTogetherSuite);
90   EXPECT_EQ(static_cast<int>(it->second), better_together_state);
91 
92   int instant_tethering_state;
93   EXPECT_TRUE(page_content_dict->GetInteger("instantTetheringState",
94                                             &instant_tethering_state));
95   it = feature_states_map.find(
96       multidevice_setup::mojom::Feature::kInstantTethering);
97   EXPECT_EQ(static_cast<int>(it->second), instant_tethering_state);
98 
99   int messages_state;
100   EXPECT_TRUE(page_content_dict->GetInteger("messagesState", &messages_state));
101   it = feature_states_map.find(multidevice_setup::mojom::Feature::kMessages);
102   EXPECT_EQ(static_cast<int>(it->second), messages_state);
103 
104   int smart_lock_state;
105   EXPECT_TRUE(
106       page_content_dict->GetInteger("smartLockState", &smart_lock_state));
107   it = feature_states_map.find(multidevice_setup::mojom::Feature::kSmartLock);
108   EXPECT_EQ(static_cast<int>(it->second), smart_lock_state);
109 
110   int phone_hub_state;
111   EXPECT_TRUE(page_content_dict->GetInteger("phoneHubState", &phone_hub_state));
112   it = feature_states_map.find(multidevice_setup::mojom::Feature::kPhoneHub);
113   EXPECT_EQ(static_cast<int>(it->second), phone_hub_state);
114 
115   int phone_hub_notifications_state;
116   EXPECT_TRUE(page_content_dict->GetInteger("phoneHubNotificationsState",
117                                             &phone_hub_notifications_state));
118   it = feature_states_map.find(
119       multidevice_setup::mojom::Feature::kPhoneHubNotifications);
120   EXPECT_EQ(static_cast<int>(it->second), phone_hub_notifications_state);
121 
122   int phone_hub_task_continuation_state;
123   EXPECT_TRUE(page_content_dict->GetInteger(
124       "phoneHubTaskContinuationState", &phone_hub_task_continuation_state));
125   it = feature_states_map.find(
126       multidevice_setup::mojom::Feature::kPhoneHubTaskContinuation);
127   EXPECT_EQ(static_cast<int>(it->second), phone_hub_task_continuation_state);
128 
129   int wifi_sync_state;
130   EXPECT_TRUE(page_content_dict->GetInteger("wifiSyncState", &wifi_sync_state));
131   it = feature_states_map.find(multidevice_setup::mojom::Feature::kWifiSync);
132   EXPECT_EQ(static_cast<int>(it->second), wifi_sync_state);
133 
134   std::string host_device_name;
135   if (expected_host_device) {
136     EXPECT_TRUE(
137         page_content_dict->GetString("hostDeviceName", &host_device_name));
138     EXPECT_EQ(expected_host_device->name(), host_device_name);
139   } else {
140     EXPECT_FALSE(
141         page_content_dict->GetString("hostDeviceName", &host_device_name));
142   }
143 }
144 
145 }  // namespace
146 
147 class MultideviceHandlerTest : public testing::Test {
148  protected:
MultideviceHandlerTest()149   MultideviceHandlerTest()
150       : test_device_(multidevice::CreateRemoteDeviceRefForTest()) {}
151   ~MultideviceHandlerTest() override = default;
152 
153   // testing::Test:
SetUp()154   void SetUp() override {
155     test_web_ui_ = std::make_unique<content::TestWebUI>();
156 
157     fake_multidevice_setup_client_ =
158         std::make_unique<multidevice_setup::FakeMultiDeviceSetupClient>();
159     fake_notification_access_manager_ =
160         std::make_unique<phonehub::FakeNotificationAccessManager>(
161             phonehub::NotificationAccessManager::AccessStatus::
162                 kAvailableButNotGranted);
163     fake_android_sms_pairing_state_tracker_ = std::make_unique<
164         multidevice_setup::FakeAndroidSmsPairingStateTracker>();
165     fake_android_sms_app_manager_ =
166         std::make_unique<android_sms::FakeAndroidSmsAppManager>();
167 
168     prefs_ = std::make_unique<TestingPrefServiceSimple>();
169 
170     handler_ = std::make_unique<TestMultideviceHandler>(
171         prefs_.get(), fake_multidevice_setup_client_.get(),
172         fake_notification_access_manager_.get(),
173         fake_android_sms_pairing_state_tracker_.get(),
174         fake_android_sms_app_manager_.get());
175     handler_->set_web_ui(test_web_ui_.get());
176     handler_->RegisterMessages();
177     handler_->AllowJavascript();
178 
179     scoped_feature_list_.InitWithFeatures({chromeos::features::kPhoneHub}, {});
180   }
181 
CallGetPageContentData()182   void CallGetPageContentData() {
183     size_t call_data_count_before_call = test_web_ui()->call_data().size();
184 
185     base::ListValue args;
186     args.AppendString("handlerFunctionName");
187     test_web_ui()->HandleReceivedMessage("getPageContentData", &args);
188 
189     EXPECT_EQ(call_data_count_before_call + 1u,
190               test_web_ui()->call_data().size());
191 
192     const content::TestWebUI::CallData& call_data =
193         CallDataAtIndex(call_data_count_before_call);
194     EXPECT_EQ("cr.webUIResponse", call_data.function_name());
195     EXPECT_EQ("handlerFunctionName", call_data.arg1()->GetString());
196     EXPECT_TRUE(call_data.arg2()->GetBool());
197     VerifyPageContent(call_data.arg3());
198   }
199 
CallRemoveHostDevice()200   void CallRemoveHostDevice() {
201     size_t num_remote_host_device_calls_before_call =
202         fake_multidevice_setup_client()->num_remove_host_device_called();
203     base::ListValue empty_args;
204     test_web_ui()->HandleReceivedMessage("removeHostDevice", &empty_args);
205     EXPECT_EQ(num_remote_host_device_calls_before_call + 1u,
206               fake_multidevice_setup_client()->num_remove_host_device_called());
207   }
208 
CallGetAndroidSmsInfo(bool expected_enabled,const GURL & expected_url)209   void CallGetAndroidSmsInfo(bool expected_enabled, const GURL& expected_url) {
210     size_t call_data_count_before_call = test_web_ui()->call_data().size();
211 
212     base::ListValue args;
213     args.AppendString("handlerFunctionName");
214     test_web_ui()->HandleReceivedMessage("getAndroidSmsInfo", &args);
215 
216     ASSERT_EQ(call_data_count_before_call + 1u,
217               test_web_ui()->call_data().size());
218     const content::TestWebUI::CallData& call_data =
219         CallDataAtIndex(call_data_count_before_call);
220     EXPECT_EQ("cr.webUIResponse", call_data.function_name());
221     EXPECT_EQ("handlerFunctionName", call_data.arg1()->GetString());
222     ASSERT_TRUE(call_data.arg2()->GetBool());
223     EXPECT_EQ(
224         ContentSettingsPattern::FromURLNoWildcard(expected_url).ToString(),
225         call_data.arg3()->FindKey("origin")->GetString());
226     EXPECT_EQ(expected_enabled,
227               call_data.arg3()->FindKey("enabled")->GetBool());
228   }
229 
CallAttemptNotificationSetup(bool has_access_been_granted)230   void CallAttemptNotificationSetup(bool has_access_been_granted) {
231     fake_notification_access_manager()->SetAccessStatusInternal(
232         has_access_been_granted
233             ? phonehub::NotificationAccessManager::AccessStatus::kAccessGranted
234             : phonehub::NotificationAccessManager::AccessStatus::
235                   kAvailableButNotGranted);
236     base::ListValue empty_args;
237     test_web_ui()->HandleReceivedMessage("attemptNotificationSetup",
238                                          &empty_args);
239   }
240 
CallCancelNotificationSetup()241   void CallCancelNotificationSetup() {
242     base::ListValue empty_args;
243     test_web_ui()->HandleReceivedMessage("cancelNotificationSetup",
244                                          &empty_args);
245   }
246 
SimulateHostStatusUpdate(multidevice_setup::mojom::HostStatus host_status,const base::Optional<multidevice::RemoteDeviceRef> & host_device)247   void SimulateHostStatusUpdate(
248       multidevice_setup::mojom::HostStatus host_status,
249       const base::Optional<multidevice::RemoteDeviceRef>& host_device) {
250     size_t call_data_count_before_call = test_web_ui()->call_data().size();
251 
252     fake_multidevice_setup_client_->SetHostStatusWithDevice(
253         std::make_pair(host_status, host_device));
254     EXPECT_EQ(call_data_count_before_call + 2u,
255               test_web_ui()->call_data().size());
256 
257     const content::TestWebUI::CallData& call_data =
258         CallDataAtIndex(call_data_count_before_call);
259     EXPECT_EQ("cr.webUIListenerCallback", call_data.function_name());
260     EXPECT_EQ("settings.updateMultidevicePageContentData",
261               call_data.arg1()->GetString());
262     VerifyPageContent(call_data.arg2());
263   }
264 
SimulateFeatureStatesUpdate(const multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap & feature_states_map)265   void SimulateFeatureStatesUpdate(
266       const multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap&
267           feature_states_map) {
268     size_t call_data_count_before_call = test_web_ui()->call_data().size();
269 
270     fake_multidevice_setup_client_->SetFeatureStates(feature_states_map);
271     EXPECT_EQ(call_data_count_before_call + 2u,
272               test_web_ui()->call_data().size());
273 
274     const content::TestWebUI::CallData& call_data =
275         CallDataAtIndex(call_data_count_before_call);
276     EXPECT_EQ("cr.webUIListenerCallback", call_data.function_name());
277     EXPECT_EQ("settings.updateMultidevicePageContentData",
278               call_data.arg1()->GetString());
279     VerifyPageContent(call_data.arg2());
280   }
281 
SimulatePairingStateUpdate(bool is_android_sms_pairing_complete)282   void SimulatePairingStateUpdate(bool is_android_sms_pairing_complete) {
283     size_t call_data_count_before_call = test_web_ui()->call_data().size();
284 
285     fake_android_sms_pairing_state_tracker_->SetPairingComplete(
286         is_android_sms_pairing_complete);
287     EXPECT_EQ(call_data_count_before_call + 2u,
288               test_web_ui()->call_data().size());
289 
290     const content::TestWebUI::CallData& call_data =
291         CallDataAtIndex(call_data_count_before_call);
292     EXPECT_EQ("cr.webUIListenerCallback", call_data.function_name());
293     EXPECT_EQ("settings.updateMultidevicePageContentData",
294               call_data.arg1()->GetString());
295     VerifyPageContent(call_data.arg2());
296   }
297 
CallRetryPendingHostSetup(bool success)298   void CallRetryPendingHostSetup(bool success) {
299     base::ListValue empty_args;
300     test_web_ui()->HandleReceivedMessage("retryPendingHostSetup", &empty_args);
301     fake_multidevice_setup_client()->InvokePendingRetrySetHostNowCallback(
302         success);
303   }
304 
CallSetUpAndroidSms()305   void CallSetUpAndroidSms() {
306     base::ListValue empty_args;
307     test_web_ui()->HandleReceivedMessage("setUpAndroidSms", &empty_args);
308   }
309 
CallSetFeatureEnabledState(multidevice_setup::mojom::Feature feature,bool enabled,const base::Optional<std::string> & auth_token,bool success)310   void CallSetFeatureEnabledState(multidevice_setup::mojom::Feature feature,
311                                   bool enabled,
312                                   const base::Optional<std::string>& auth_token,
313                                   bool success) {
314     size_t call_data_count_before_call = test_web_ui()->call_data().size();
315 
316     base::ListValue args;
317     args.AppendString("handlerFunctionName");
318     args.AppendInteger(static_cast<int>(feature));
319     args.AppendBoolean(enabled);
320     if (auth_token)
321       args.AppendString(*auth_token);
322 
323     base::ListValue empty_args;
324     test_web_ui()->HandleReceivedMessage("setFeatureEnabledState", &args);
325     fake_multidevice_setup_client()
326         ->InvokePendingSetFeatureEnabledStateCallback(
327             feature /* expected_feature */, enabled /* expected_enabled */,
328             auth_token /* expected_auth_token */, success);
329 
330     EXPECT_EQ(call_data_count_before_call + 1u,
331               test_web_ui()->call_data().size());
332     const content::TestWebUI::CallData& call_data =
333         CallDataAtIndex(call_data_count_before_call);
334     EXPECT_EQ("cr.webUIResponse", call_data.function_name());
335     EXPECT_EQ("handlerFunctionName", call_data.arg1()->GetString());
336     EXPECT_TRUE(call_data.arg2()->GetBool());
337     EXPECT_EQ(success, call_data.arg3()->GetBool());
338   }
339 
CallDataAtIndex(size_t index)340   const content::TestWebUI::CallData& CallDataAtIndex(size_t index) {
341     return *test_web_ui_->call_data()[index];
342   }
343 
test_web_ui()344   content::TestWebUI* test_web_ui() { return test_web_ui_.get(); }
345 
346   multidevice_setup::FakeMultiDeviceSetupClient*
fake_multidevice_setup_client()347   fake_multidevice_setup_client() {
348     return fake_multidevice_setup_client_.get();
349   }
350 
fake_android_sms_app_manager()351   android_sms::FakeAndroidSmsAppManager* fake_android_sms_app_manager() {
352     return fake_android_sms_app_manager_.get();
353   }
354 
fake_notification_access_manager()355   phonehub::FakeNotificationAccessManager* fake_notification_access_manager() {
356     return fake_notification_access_manager_.get();
357   }
358 
SimulateNotificationOptInStatusChange(phonehub::NotificationAccessSetupOperation::Status status)359   void SimulateNotificationOptInStatusChange(
360       phonehub::NotificationAccessSetupOperation::Status status) {
361     size_t call_data_count_before_call = test_web_ui()->call_data().size();
362 
363     fake_notification_access_manager()->SetNotificationSetupOperationStatus(
364         status);
365 
366     bool completed_successfully = status ==
367                                   phonehub::NotificationAccessSetupOperation::
368                                       Status::kCompletedSuccessfully;
369     if (completed_successfully)
370       call_data_count_before_call++;
371 
372     EXPECT_EQ(call_data_count_before_call + 1u,
373               test_web_ui()->call_data().size());
374     const content::TestWebUI::CallData& call_data =
375         CallDataAtIndex(call_data_count_before_call);
376     EXPECT_EQ("cr.webUIListenerCallback", call_data.function_name());
377     EXPECT_EQ("settings.onNotificationAccessSetupStatusChanged",
378               call_data.arg1()->GetString());
379     EXPECT_EQ(call_data.arg2()->GetInt(), static_cast<int32_t>(status));
380   }
381 
IsNotificationAccessSetupOperationInProgress()382   bool IsNotificationAccessSetupOperationInProgress() {
383     return fake_notification_access_manager()->IsSetupOperationInProgress();
384   }
385 
386   const multidevice::RemoteDeviceRef test_device_;
387 
388  private:
VerifyPageContent(const base::Value * value)389   void VerifyPageContent(const base::Value* value) {
390     VerifyPageContentDict(
391         value, fake_multidevice_setup_client_->GetHostStatus().first,
392         fake_multidevice_setup_client_->GetHostStatus().second,
393         fake_multidevice_setup_client_->GetFeatureStates());
394   }
395 
396   std::unique_ptr<TestingPrefServiceSimple> prefs_;
397   std::unique_ptr<content::TestWebUI> test_web_ui_;
398   std::unique_ptr<multidevice_setup::FakeMultiDeviceSetupClient>
399       fake_multidevice_setup_client_;
400   std::unique_ptr<phonehub::FakeNotificationAccessManager>
401       fake_notification_access_manager_;
402   std::unique_ptr<multidevice_setup::FakeAndroidSmsPairingStateTracker>
403       fake_android_sms_pairing_state_tracker_;
404 
405   multidevice_setup::MultiDeviceSetupClient::HostStatusWithDevice
406       host_status_with_device_;
407   multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap
408       feature_states_map_;
409   std::unique_ptr<android_sms::FakeAndroidSmsAppManager>
410       fake_android_sms_app_manager_;
411 
412   std::unique_ptr<TestMultideviceHandler> handler_;
413 
414   base::test::ScopedFeatureList scoped_feature_list_;
415 
416   DISALLOW_COPY_AND_ASSIGN(MultideviceHandlerTest);
417 };
418 
TEST_F(MultideviceHandlerTest,NotificationSetupFlow)419 TEST_F(MultideviceHandlerTest, NotificationSetupFlow) {
420   using Status = phonehub::NotificationAccessSetupOperation::Status;
421 
422   // Simulate success flow.
423   CallAttemptNotificationSetup(/*has_access_been_granted=*/false);
424   EXPECT_TRUE(IsNotificationAccessSetupOperationInProgress());
425 
426   SimulateNotificationOptInStatusChange(Status::kConnecting);
427   EXPECT_TRUE(IsNotificationAccessSetupOperationInProgress());
428 
429   SimulateNotificationOptInStatusChange(
430       Status::kSentMessageToPhoneAndWaitingForResponse);
431   EXPECT_TRUE(IsNotificationAccessSetupOperationInProgress());
432 
433   SimulateNotificationOptInStatusChange(Status::kCompletedSuccessfully);
434   EXPECT_FALSE(IsNotificationAccessSetupOperationInProgress());
435 
436   // Simulate cancel flow.
437   CallAttemptNotificationSetup(/*has_access_been_granted=*/false);
438   EXPECT_TRUE(IsNotificationAccessSetupOperationInProgress());
439 
440   CallCancelNotificationSetup();
441   EXPECT_FALSE(IsNotificationAccessSetupOperationInProgress());
442 
443   // Simulate failure via time-out flow.
444   CallAttemptNotificationSetup(/*has_access_been_granted=*/false);
445   EXPECT_TRUE(IsNotificationAccessSetupOperationInProgress());
446 
447   SimulateNotificationOptInStatusChange(Status::kConnecting);
448   EXPECT_TRUE(IsNotificationAccessSetupOperationInProgress());
449 
450   SimulateNotificationOptInStatusChange(Status::kTimedOutConnecting);
451   EXPECT_FALSE(IsNotificationAccessSetupOperationInProgress());
452 
453   // Simulate failure via connected then disconnected flow.
454   CallAttemptNotificationSetup(/*has_access_been_granted=*/false);
455   EXPECT_TRUE(IsNotificationAccessSetupOperationInProgress());
456 
457   SimulateNotificationOptInStatusChange(Status::kConnecting);
458   EXPECT_TRUE(IsNotificationAccessSetupOperationInProgress());
459 
460   SimulateNotificationOptInStatusChange(Status::kConnectionDisconnected);
461   EXPECT_FALSE(IsNotificationAccessSetupOperationInProgress());
462 
463   // If access has already been granted, a setup operation should not occur.
464   CallAttemptNotificationSetup(/*has_access_been_granted=*/true);
465   EXPECT_FALSE(IsNotificationAccessSetupOperationInProgress());
466 }
467 
TEST_F(MultideviceHandlerTest,PageContentData)468 TEST_F(MultideviceHandlerTest, PageContentData) {
469   CallGetPageContentData();
470   CallGetPageContentData();
471 
472   SimulateHostStatusUpdate(
473       multidevice_setup::mojom::HostStatus::kEligibleHostExistsButNoHostSet,
474       base::nullopt /* host_device */);
475   SimulateHostStatusUpdate(multidevice_setup::mojom::HostStatus::
476                                kHostSetLocallyButWaitingForBackendConfirmation,
477                            test_device_);
478   SimulateHostStatusUpdate(
479       multidevice_setup::mojom::HostStatus::kHostSetButNotYetVerified,
480       test_device_);
481   SimulateHostStatusUpdate(multidevice_setup::mojom::HostStatus::kHostVerified,
482                            test_device_);
483 
484   multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap
485       feature_states_map = GenerateDefaultFeatureStatesMap();
486   feature_states_map[multidevice_setup::mojom::Feature::kBetterTogetherSuite] =
487       multidevice_setup::mojom::FeatureState::kEnabledByUser;
488   SimulateFeatureStatesUpdate(feature_states_map);
489 
490   feature_states_map[multidevice_setup::mojom::Feature::kBetterTogetherSuite] =
491       multidevice_setup::mojom::FeatureState::kDisabledByUser;
492   SimulateFeatureStatesUpdate(feature_states_map);
493 
494   SimulatePairingStateUpdate(/*is_android_sms_pairing_complete=*/true);
495 }
496 
TEST_F(MultideviceHandlerTest,RetryPendingHostSetup)497 TEST_F(MultideviceHandlerTest, RetryPendingHostSetup) {
498   CallRetryPendingHostSetup(true /* success */);
499   CallRetryPendingHostSetup(false /* success */);
500 }
501 
TEST_F(MultideviceHandlerTest,SetUpAndroidSms)502 TEST_F(MultideviceHandlerTest, SetUpAndroidSms) {
503   EXPECT_FALSE(fake_android_sms_app_manager()->has_installed_app());
504   EXPECT_FALSE(fake_android_sms_app_manager()->has_launched_app());
505   CallSetUpAndroidSms();
506   EXPECT_TRUE(fake_android_sms_app_manager()->has_installed_app());
507   EXPECT_TRUE(fake_android_sms_app_manager()->has_launched_app());
508 }
509 
TEST_F(MultideviceHandlerTest,SetFeatureEnabledState)510 TEST_F(MultideviceHandlerTest, SetFeatureEnabledState) {
511   CallSetFeatureEnabledState(
512       multidevice_setup::mojom::Feature::kBetterTogetherSuite,
513       true /* enabled */, "authToken" /* auth_token */, true /* success */);
514   CallSetFeatureEnabledState(
515       multidevice_setup::mojom::Feature::kBetterTogetherSuite,
516       false /* enabled */, "authToken" /* auth_token */, false /* success */);
517   CallSetFeatureEnabledState(
518       multidevice_setup::mojom::Feature::kBetterTogetherSuite,
519       false /* enabled */, "authToken" /* auth_token */, true /* success */);
520 }
521 
TEST_F(MultideviceHandlerTest,RemoveHostDevice)522 TEST_F(MultideviceHandlerTest, RemoveHostDevice) {
523   CallRemoveHostDevice();
524   CallRemoveHostDevice();
525   CallRemoveHostDevice();
526 }
527 
TEST_F(MultideviceHandlerTest,GetAndroidSmsInfo)528 TEST_F(MultideviceHandlerTest, GetAndroidSmsInfo) {
529   // Check that getAndroidSmsInfo returns correct value.
530   CallGetAndroidSmsInfo(false /* expected_enabled */,
531                         android_sms::GetAndroidMessagesURL(
532                             true /* use_install_url */) /* expected_url */);
533 
534   // Change messages feature state and assert that the change
535   // callback is fired.
536   multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap
537       feature_states_map = GenerateDefaultFeatureStatesMap();
538   feature_states_map[multidevice_setup::mojom::Feature::kMessages] =
539       multidevice_setup::mojom::FeatureState::kEnabledByUser;
540 
541   size_t call_data_count_before_call = test_web_ui()->call_data().size();
542   SimulateFeatureStatesUpdate(feature_states_map);
543   const content::TestWebUI::CallData& call_data_1 =
544       CallDataAtIndex(call_data_count_before_call + 1);
545   EXPECT_EQ("cr.webUIListenerCallback", call_data_1.function_name());
546   EXPECT_EQ("settings.onAndroidSmsInfoChange", call_data_1.arg1()->GetString());
547 
548   // Check that getAndroidSmsInfo returns update value.
549   CallGetAndroidSmsInfo(true /* enabled */, android_sms::GetAndroidMessagesURL(
550                                                 true) /* expected_url */);
551 
552   // Now, update the installed URL. This should have resulted in another call.
553   fake_android_sms_app_manager()->SetInstalledAppUrl(
554       android_sms::GetAndroidMessagesURL(true /* use_install_url */,
555                                          android_sms::PwaDomain::kStaging));
556   const content::TestWebUI::CallData& call_data_2 =
557       CallDataAtIndex(call_data_count_before_call + 4);
558   EXPECT_EQ("cr.webUIListenerCallback", call_data_2.function_name());
559   EXPECT_EQ("settings.onAndroidSmsInfoChange", call_data_2.arg1()->GetString());
560   CallGetAndroidSmsInfo(
561       true /* enabled */,
562       android_sms::GetAndroidMessagesURL(
563           true /* use_install_url */,
564           android_sms::PwaDomain::kStaging) /* expected_url */);
565 }
566 
567 }  // namespace settings
568 
569 }  // namespace chromeos
570