feature_state_manager_impl_unittest.cc 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053
  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. #include "ash/services/multidevice_setup/feature_state_manager_impl.h"
  5. #include <memory>
  6. #include <vector>
  7. #include "ash/components/multidevice/remote_device_test_util.h"
  8. #include "ash/constants/ash_features.h"
  9. #include "ash/services/device_sync/public/cpp/fake_device_sync_client.h"
  10. #include "ash/services/multidevice_setup/fake_feature_state_manager.h"
  11. #include "ash/services/multidevice_setup/fake_global_state_feature_manager.h"
  12. #include "ash/services/multidevice_setup/fake_host_status_provider.h"
  13. #include "ash/services/multidevice_setup/public/cpp/fake_android_sms_pairing_state_tracker.h"
  14. #include "ash/services/multidevice_setup/public/cpp/prefs.h"
  15. #include "base/containers/contains.h"
  16. #include "base/test/scoped_feature_list.h"
  17. #include "base/test/task_environment.h"
  18. #include "components/sync_preferences/testing_pref_service_syncable.h"
  19. #include "testing/gtest/include/gtest/gtest.h"
  20. #include "third_party/abseil-cpp/absl/types/optional.h"
  21. namespace ash {
  22. namespace multidevice_setup {
  23. namespace {
  24. multidevice::RemoteDeviceRef CreateTestLocalDevice() {
  25. multidevice::RemoteDeviceRef local_device =
  26. multidevice::CreateRemoteDeviceRefForTest();
  27. // Set all client features to not supported.
  28. multidevice::RemoteDevice* raw_device =
  29. multidevice::GetMutableRemoteDevice(local_device);
  30. raw_device
  31. ->software_features[multidevice::SoftwareFeature::kBetterTogetherClient] =
  32. multidevice::SoftwareFeatureState::kNotSupported;
  33. raw_device
  34. ->software_features[multidevice::SoftwareFeature::kSmartLockClient] =
  35. multidevice::SoftwareFeatureState::kNotSupported;
  36. raw_device->software_features
  37. [multidevice::SoftwareFeature::kInstantTetheringClient] =
  38. multidevice::SoftwareFeatureState::kNotSupported;
  39. raw_device
  40. ->software_features[multidevice::SoftwareFeature::kMessagesForWebClient] =
  41. multidevice::SoftwareFeatureState::kNotSupported;
  42. raw_device->software_features[multidevice::SoftwareFeature::kPhoneHubClient] =
  43. multidevice::SoftwareFeatureState::kNotSupported;
  44. raw_device->software_features[multidevice::SoftwareFeature::kWifiSyncClient] =
  45. multidevice::SoftwareFeatureState::kNotSupported;
  46. return local_device;
  47. }
  48. multidevice::RemoteDeviceRef CreateTestHostDevice(
  49. bool empty_mac_address = false) {
  50. multidevice::RemoteDeviceRef host_device =
  51. multidevice::CreateRemoteDeviceRefForTest();
  52. // Set all host features to supported.
  53. multidevice::RemoteDevice* raw_device =
  54. multidevice::GetMutableRemoteDevice(host_device);
  55. raw_device
  56. ->software_features[multidevice::SoftwareFeature::kBetterTogetherHost] =
  57. multidevice::SoftwareFeatureState::kSupported;
  58. raw_device->software_features[multidevice::SoftwareFeature::kSmartLockHost] =
  59. multidevice::SoftwareFeatureState::kSupported;
  60. raw_device
  61. ->software_features[multidevice::SoftwareFeature::kInstantTetheringHost] =
  62. multidevice::SoftwareFeatureState::kSupported;
  63. raw_device
  64. ->software_features[multidevice::SoftwareFeature::kMessagesForWebHost] =
  65. multidevice::SoftwareFeatureState::kSupported;
  66. raw_device->software_features[multidevice::SoftwareFeature::kPhoneHubHost] =
  67. multidevice::SoftwareFeatureState::kSupported;
  68. raw_device->software_features[multidevice::SoftwareFeature::kWifiSyncHost] =
  69. multidevice::SoftwareFeatureState::kSupported;
  70. if (empty_mac_address)
  71. raw_device->bluetooth_public_address.clear();
  72. return host_device;
  73. }
  74. } // namespace
  75. class MultiDeviceSetupFeatureStateManagerImplTest : public testing::Test {
  76. public:
  77. MultiDeviceSetupFeatureStateManagerImplTest(
  78. const MultiDeviceSetupFeatureStateManagerImplTest&) = delete;
  79. MultiDeviceSetupFeatureStateManagerImplTest& operator=(
  80. const MultiDeviceSetupFeatureStateManagerImplTest&) = delete;
  81. protected:
  82. MultiDeviceSetupFeatureStateManagerImplTest()
  83. : test_local_device_(CreateTestLocalDevice()),
  84. test_host_device_(CreateTestHostDevice()) {}
  85. ~MultiDeviceSetupFeatureStateManagerImplTest() override = default;
  86. void SetupFeatureStateManager(bool is_secondary_user = false,
  87. bool empty_mac_address = false) {
  88. test_host_device_ = CreateTestHostDevice(empty_mac_address);
  89. test_pref_service_ =
  90. std::make_unique<sync_preferences::TestingPrefServiceSyncable>();
  91. user_prefs::PrefRegistrySyncable* registry = test_pref_service_->registry();
  92. RegisterFeaturePrefs(registry);
  93. fake_host_status_provider_ = std::make_unique<FakeHostStatusProvider>();
  94. fake_device_sync_client_ =
  95. std::make_unique<device_sync::FakeDeviceSyncClient>();
  96. fake_device_sync_client_->set_synced_devices(
  97. multidevice::RemoteDeviceRefList{test_local_device_,
  98. test_host_device_});
  99. fake_device_sync_client_->set_local_device_metadata(test_local_device_);
  100. fake_android_sms_pairing_state_tracker_ =
  101. std::make_unique<FakeAndroidSmsPairingStateTracker>();
  102. fake_android_sms_pairing_state_tracker_->SetPairingComplete(true);
  103. fake_global_state_feature_managers_.emplace(
  104. mojom::Feature::kWifiSync,
  105. std::make_unique<FakeGlobalStateFeatureManager>());
  106. manager_ = FeatureStateManagerImpl::Factory::Create(
  107. test_pref_service_.get(), fake_host_status_provider_.get(),
  108. fake_device_sync_client_.get(),
  109. fake_android_sms_pairing_state_tracker_.get(),
  110. {{mojom::Feature::kWifiSync,
  111. fake_global_state_feature_managers_.at(mojom::Feature::kWifiSync)
  112. .get()}},
  113. is_secondary_user);
  114. fake_observer_ = std::make_unique<FakeFeatureStateManagerObserver>();
  115. manager_->AddObserver(fake_observer_.get());
  116. }
  117. void TryAllUnverifiedHostStatesAndVerifyFeatureState(mojom::Feature feature) {
  118. bool previously_had_eligible_hosts =
  119. fake_host_status_provider_->GetHostWithStatus().host_status() !=
  120. mojom::HostStatus::kNoEligibleHosts;
  121. size_t num_observer_events_before_call =
  122. fake_observer_->feature_state_updates().size();
  123. size_t expected_num_observer_events_after_call =
  124. num_observer_events_before_call +
  125. (previously_had_eligible_hosts ? 1u : 0u);
  126. fake_host_status_provider_->SetHostWithStatus(
  127. mojom::HostStatus::kNoEligibleHosts, absl::nullopt /* host_device */);
  128. if (previously_had_eligible_hosts) {
  129. VerifyFeatureStateChange(
  130. num_observer_events_before_call, feature,
  131. mojom::FeatureState::kUnavailableNoVerifiedHost_NoEligibleHosts);
  132. }
  133. EXPECT_EQ(mojom::FeatureState::kUnavailableNoVerifiedHost_NoEligibleHosts,
  134. manager_->GetFeatureStates()[feature]);
  135. EXPECT_EQ(expected_num_observer_events_after_call,
  136. fake_observer_->feature_state_updates().size());
  137. fake_host_status_provider_->SetHostWithStatus(
  138. mojom::HostStatus::kEligibleHostExistsButNoHostSet,
  139. absl::nullopt /* host_device */);
  140. // Updating host status here updates feature state from
  141. // kUnavailableNoVerifiedHost_NoEligibleHosts to
  142. // kUnavailableNoVerifiedHost_HostExistsButNotSetAndVerified.
  143. expected_num_observer_events_after_call += 1;
  144. EXPECT_EQ(mojom::FeatureState::
  145. kUnavailableNoVerifiedHost_HostExistsButNotSetAndVerified,
  146. manager_->GetFeatureStates()[feature]);
  147. EXPECT_EQ(expected_num_observer_events_after_call,
  148. fake_observer_->feature_state_updates().size());
  149. fake_host_status_provider_->SetHostWithStatus(
  150. mojom::HostStatus::kHostSetLocallyButWaitingForBackendConfirmation,
  151. test_host_device_);
  152. EXPECT_EQ(mojom::FeatureState::
  153. kUnavailableNoVerifiedHost_HostExistsButNotSetAndVerified,
  154. manager_->GetFeatureStates()[feature]);
  155. EXPECT_EQ(expected_num_observer_events_after_call,
  156. fake_observer_->feature_state_updates().size());
  157. fake_host_status_provider_->SetHostWithStatus(
  158. mojom::HostStatus::kHostSetButNotYetVerified, test_host_device_);
  159. EXPECT_EQ(mojom::FeatureState::
  160. kUnavailableNoVerifiedHost_HostExistsButNotSetAndVerified,
  161. manager_->GetFeatureStates()[feature]);
  162. EXPECT_EQ(expected_num_observer_events_after_call,
  163. fake_observer_->feature_state_updates().size());
  164. }
  165. void SetVerifiedHost() {
  166. // Should not already be verified if we are setting it to be verified.
  167. EXPECT_NE(mojom::HostStatus::kHostVerified,
  168. fake_host_status_provider_->GetHostWithStatus().host_status());
  169. size_t num_observer_events_before_call =
  170. fake_observer_->feature_state_updates().size();
  171. SetSoftwareFeatureState(false /* use_local_device */,
  172. multidevice::SoftwareFeature::kBetterTogetherHost,
  173. multidevice::SoftwareFeatureState::kEnabled);
  174. fake_host_status_provider_->SetHostWithStatus(
  175. mojom::HostStatus::kHostVerified, test_host_device_);
  176. // Since the host is now verified, there should be a feature state update
  177. // for all features.
  178. EXPECT_EQ(num_observer_events_before_call + 1u,
  179. fake_observer_->feature_state_updates().size());
  180. }
  181. void MakeBetterTogetherSuiteDisabledByUser(
  182. const mojom::FeatureState& expected_state_upon_disabling =
  183. mojom::FeatureState::kDisabledByUser) {
  184. SetSoftwareFeatureState(true /* use_local_device */,
  185. multidevice::SoftwareFeature::kBetterTogetherClient,
  186. multidevice::SoftwareFeatureState::kSupported);
  187. test_pref_service_->SetBoolean(kBetterTogetherSuiteEnabledPrefName, false);
  188. EXPECT_EQ(
  189. expected_state_upon_disabling,
  190. manager_->GetFeatureStates()[mojom::Feature::kBetterTogetherSuite]);
  191. }
  192. void VerifyFeatureState(mojom::FeatureState expected_feature_state,
  193. mojom::Feature feature) {
  194. EXPECT_TRUE(base::Contains(manager_->GetFeatureStates(), feature));
  195. EXPECT_EQ(expected_feature_state, manager_->GetFeatureStates()[feature]);
  196. }
  197. void VerifyFeatureStateChange(size_t expected_index,
  198. mojom::Feature expected_feature,
  199. mojom::FeatureState expected_feature_state) {
  200. const FeatureStateManager::FeatureStatesMap& map =
  201. fake_observer_->feature_state_updates()[expected_index];
  202. const auto it = map.find(expected_feature);
  203. EXPECT_NE(map.end(), it);
  204. EXPECT_EQ(expected_feature_state, it->second);
  205. }
  206. void SetSoftwareFeatureState(
  207. bool use_local_device,
  208. multidevice::SoftwareFeature software_feature,
  209. multidevice::SoftwareFeatureState software_feature_state) {
  210. multidevice::RemoteDeviceRef& device =
  211. use_local_device ? test_local_device_ : test_host_device_;
  212. multidevice::GetMutableRemoteDevice(device)
  213. ->software_features[software_feature] = software_feature_state;
  214. fake_device_sync_client_->NotifyNewDevicesSynced();
  215. }
  216. void SetAndroidSmsPairingState(bool is_paired) {
  217. fake_android_sms_pairing_state_tracker_->SetPairingComplete(is_paired);
  218. }
  219. sync_preferences::TestingPrefServiceSyncable* test_pref_service() {
  220. return test_pref_service_.get();
  221. }
  222. FeatureStateManager* manager() { return manager_.get(); }
  223. base::flat_map<mojom::Feature,
  224. std::unique_ptr<FakeGlobalStateFeatureManager>>&
  225. global_state_feature_managers() {
  226. return fake_global_state_feature_managers_;
  227. }
  228. private:
  229. base::test::TaskEnvironment task_environment_;
  230. multidevice::RemoteDeviceRef test_local_device_;
  231. multidevice::RemoteDeviceRef test_host_device_;
  232. std::unique_ptr<sync_preferences::TestingPrefServiceSyncable>
  233. test_pref_service_;
  234. std::unique_ptr<FakeHostStatusProvider> fake_host_status_provider_;
  235. std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_;
  236. std::unique_ptr<FakeAndroidSmsPairingStateTracker>
  237. fake_android_sms_pairing_state_tracker_;
  238. base::flat_map<mojom::Feature, std::unique_ptr<FakeGlobalStateFeatureManager>>
  239. fake_global_state_feature_managers_;
  240. std::unique_ptr<FakeFeatureStateManagerObserver> fake_observer_;
  241. std::unique_ptr<FeatureStateManager> manager_;
  242. };
  243. TEST_F(MultiDeviceSetupFeatureStateManagerImplTest, BetterTogetherSuite) {
  244. SetupFeatureStateManager();
  245. TryAllUnverifiedHostStatesAndVerifyFeatureState(
  246. mojom::Feature::kBetterTogetherSuite);
  247. SetVerifiedHost();
  248. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  249. mojom::Feature::kBetterTogetherSuite);
  250. // Add support for the suite; it should still remain unsupported, since there
  251. // are no sub-features which are supported.
  252. SetSoftwareFeatureState(true /* use_local_device */,
  253. multidevice::SoftwareFeature::kBetterTogetherClient,
  254. multidevice::SoftwareFeatureState::kSupported);
  255. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  256. mojom::Feature::kBetterTogetherSuite);
  257. // Add support for child features.
  258. SetSoftwareFeatureState(true /* use_local_device */,
  259. multidevice::SoftwareFeature::kInstantTetheringClient,
  260. multidevice::SoftwareFeatureState::kSupported);
  261. SetSoftwareFeatureState(true /* use_local_device */,
  262. multidevice::SoftwareFeature::kSmartLockClient,
  263. multidevice::SoftwareFeatureState::kSupported);
  264. SetSoftwareFeatureState(true /* use_local_device */,
  265. multidevice::SoftwareFeature::kMessagesForWebClient,
  266. multidevice::SoftwareFeatureState::kSupported);
  267. SetSoftwareFeatureState(true /* use_local_device */,
  268. multidevice::SoftwareFeature::kPhoneHubClient,
  269. multidevice::SoftwareFeatureState::kSupported);
  270. SetSoftwareFeatureState(true /* use_local_device */,
  271. multidevice::SoftwareFeature::kWifiSyncClient,
  272. multidevice::SoftwareFeatureState::kSupported);
  273. // Now, the suite should be considered enabled.
  274. VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
  275. mojom::Feature::kBetterTogetherSuite);
  276. VerifyFeatureStateChange(6u /* expected_index */,
  277. mojom::Feature::kBetterTogetherSuite,
  278. mojom::FeatureState::kEnabledByUser);
  279. test_pref_service()->SetBoolean(kBetterTogetherSuiteEnabledPrefName, false);
  280. VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
  281. mojom::Feature::kBetterTogetherSuite);
  282. VerifyFeatureStateChange(7u /* expected_index */,
  283. mojom::Feature::kBetterTogetherSuite,
  284. mojom::FeatureState::kDisabledByUser);
  285. // Set all features to prohibited. This should cause the Better Together suite
  286. // to become prohibited as well.
  287. test_pref_service()->SetBoolean(kInstantTetheringAllowedPrefName, false);
  288. test_pref_service()->SetBoolean(kMessagesAllowedPrefName, false);
  289. test_pref_service()->SetBoolean(kSmartLockAllowedPrefName, false);
  290. test_pref_service()->SetBoolean(kPhoneHubAllowedPrefName, false);
  291. test_pref_service()->SetBoolean(kWifiSyncAllowedPrefName, false);
  292. VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
  293. mojom::Feature::kBetterTogetherSuite);
  294. VerifyFeatureStateChange(12u /* expected_index */,
  295. mojom::Feature::kBetterTogetherSuite,
  296. mojom::FeatureState::kProhibitedByPolicy);
  297. }
  298. TEST_F(MultiDeviceSetupFeatureStateManagerImplTest,
  299. BetterTogetherSuiteForSecondaryUsers) {
  300. SetupFeatureStateManager(/*is_secondary_user=*/true);
  301. TryAllUnverifiedHostStatesAndVerifyFeatureState(
  302. mojom::Feature::kBetterTogetherSuite);
  303. SetVerifiedHost();
  304. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  305. mojom::Feature::kBetterTogetherSuite);
  306. // Add support for the suite; it should still remain unsupported, since there
  307. // are no sub-features which are supported.
  308. SetSoftwareFeatureState(true /* use_local_device */,
  309. multidevice::SoftwareFeature::kBetterTogetherClient,
  310. multidevice::SoftwareFeatureState::kSupported);
  311. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  312. mojom::Feature::kBetterTogetherSuite);
  313. // Add support for child features.
  314. SetSoftwareFeatureState(true /* use_local_device */,
  315. multidevice::SoftwareFeature::kInstantTetheringClient,
  316. multidevice::SoftwareFeatureState::kSupported);
  317. SetSoftwareFeatureState(true /* use_local_device */,
  318. multidevice::SoftwareFeature::kSmartLockClient,
  319. multidevice::SoftwareFeatureState::kSupported);
  320. SetSoftwareFeatureState(true /* use_local_device */,
  321. multidevice::SoftwareFeature::kMessagesForWebClient,
  322. multidevice::SoftwareFeatureState::kSupported);
  323. SetSoftwareFeatureState(true /* use_local_device */,
  324. multidevice::SoftwareFeature::kPhoneHubClient,
  325. multidevice::SoftwareFeatureState::kSupported);
  326. SetSoftwareFeatureState(true /* use_local_device */,
  327. multidevice::SoftwareFeature::kWifiSyncClient,
  328. multidevice::SoftwareFeatureState::kSupported);
  329. // Now, the suite should be considered enabled.
  330. VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
  331. mojom::Feature::kBetterTogetherSuite);
  332. VerifyFeatureStateChange(5u /* expected_index */,
  333. mojom::Feature::kBetterTogetherSuite,
  334. mojom::FeatureState::kEnabledByUser);
  335. test_pref_service()->SetBoolean(kBetterTogetherSuiteEnabledPrefName, false);
  336. VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
  337. mojom::Feature::kBetterTogetherSuite);
  338. VerifyFeatureStateChange(6u /* expected_index */,
  339. mojom::Feature::kBetterTogetherSuite,
  340. mojom::FeatureState::kDisabledByUser);
  341. // Set all features to prohibited. This should cause the Better Together suite
  342. // to become prohibited as well.
  343. test_pref_service()->SetBoolean(kInstantTetheringAllowedPrefName, false);
  344. test_pref_service()->SetBoolean(kMessagesAllowedPrefName, false);
  345. test_pref_service()->SetBoolean(kSmartLockAllowedPrefName, false);
  346. test_pref_service()->SetBoolean(kPhoneHubAllowedPrefName, false);
  347. test_pref_service()->SetBoolean(kWifiSyncAllowedPrefName, false);
  348. VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
  349. mojom::Feature::kBetterTogetherSuite);
  350. VerifyFeatureStateChange(11u /* expected_index */,
  351. mojom::Feature::kBetterTogetherSuite,
  352. mojom::FeatureState::kProhibitedByPolicy);
  353. }
  354. TEST_F(MultiDeviceSetupFeatureStateManagerImplTest, InstantTethering) {
  355. SetupFeatureStateManager();
  356. TryAllUnverifiedHostStatesAndVerifyFeatureState(
  357. mojom::Feature::kInstantTethering);
  358. SetVerifiedHost();
  359. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  360. mojom::Feature::kInstantTethering);
  361. SetSoftwareFeatureState(true /* use_local_device */,
  362. multidevice::SoftwareFeature::kInstantTetheringClient,
  363. multidevice::SoftwareFeatureState::kSupported);
  364. VerifyFeatureState(mojom::FeatureState::kNotSupportedByPhone,
  365. mojom::Feature::kInstantTethering);
  366. VerifyFeatureStateChange(2u /* expected_index */,
  367. mojom::Feature::kInstantTethering,
  368. mojom::FeatureState::kNotSupportedByPhone);
  369. SetSoftwareFeatureState(false /* use_local_device */,
  370. multidevice::SoftwareFeature::kInstantTetheringHost,
  371. multidevice::SoftwareFeatureState::kEnabled);
  372. VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
  373. mojom::Feature::kInstantTethering);
  374. VerifyFeatureStateChange(3u /* expected_index */,
  375. mojom::Feature::kInstantTethering,
  376. mojom::FeatureState::kEnabledByUser);
  377. MakeBetterTogetherSuiteDisabledByUser();
  378. VerifyFeatureState(mojom::FeatureState::kUnavailableSuiteDisabled,
  379. mojom::Feature::kInstantTethering);
  380. VerifyFeatureStateChange(5u /* expected_index */,
  381. mojom::Feature::kInstantTethering,
  382. mojom::FeatureState::kUnavailableSuiteDisabled);
  383. test_pref_service()->SetBoolean(kInstantTetheringEnabledPrefName, false);
  384. VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
  385. mojom::Feature::kInstantTethering);
  386. VerifyFeatureStateChange(6u /* expected_index */,
  387. mojom::Feature::kInstantTethering,
  388. mojom::FeatureState::kDisabledByUser);
  389. test_pref_service()->SetBoolean(kInstantTetheringAllowedPrefName, false);
  390. VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
  391. mojom::Feature::kInstantTethering);
  392. VerifyFeatureStateChange(7u /* expected_index */,
  393. mojom::Feature::kInstantTethering,
  394. mojom::FeatureState::kProhibitedByPolicy);
  395. }
  396. TEST_F(MultiDeviceSetupFeatureStateManagerImplTest, Messages) {
  397. SetupFeatureStateManager();
  398. TryAllUnverifiedHostStatesAndVerifyFeatureState(mojom::Feature::kMessages);
  399. SetVerifiedHost();
  400. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  401. mojom::Feature::kMessages);
  402. SetSoftwareFeatureState(true /* use_local_device */,
  403. multidevice::SoftwareFeature::kMessagesForWebClient,
  404. multidevice::SoftwareFeatureState::kSupported);
  405. VerifyFeatureState(mojom::FeatureState::kNotSupportedByPhone,
  406. mojom::Feature::kMessages);
  407. VerifyFeatureStateChange(2u /* expected_index */, mojom::Feature::kMessages,
  408. mojom::FeatureState::kNotSupportedByPhone);
  409. SetSoftwareFeatureState(false /* use_local_device */,
  410. multidevice::SoftwareFeature::kMessagesForWebHost,
  411. multidevice::SoftwareFeatureState::kEnabled);
  412. VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
  413. mojom::Feature::kMessages);
  414. VerifyFeatureStateChange(3u /* expected_index */, mojom::Feature::kMessages,
  415. mojom::FeatureState::kEnabledByUser);
  416. SetAndroidSmsPairingState(false /* is_paired */);
  417. VerifyFeatureState(mojom::FeatureState::kFurtherSetupRequired,
  418. mojom::Feature::kMessages);
  419. VerifyFeatureStateChange(4u /* expected_index */, mojom::Feature::kMessages,
  420. mojom::FeatureState::kFurtherSetupRequired);
  421. SetAndroidSmsPairingState(true /* is_paired */);
  422. VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
  423. mojom::Feature::kMessages);
  424. VerifyFeatureStateChange(5u /* expected_index */, mojom::Feature::kMessages,
  425. mojom::FeatureState::kEnabledByUser);
  426. SetAndroidSmsPairingState(false /* is_paired */);
  427. MakeBetterTogetherSuiteDisabledByUser();
  428. VerifyFeatureState(mojom::FeatureState::kUnavailableSuiteDisabled,
  429. mojom::Feature::kMessages);
  430. VerifyFeatureStateChange(8u /* expected_index */, mojom::Feature::kMessages,
  431. mojom::FeatureState::kUnavailableSuiteDisabled);
  432. SetAndroidSmsPairingState(true /* is_paired */);
  433. VerifyFeatureState(mojom::FeatureState::kUnavailableSuiteDisabled,
  434. mojom::Feature::kMessages);
  435. test_pref_service()->SetBoolean(kMessagesEnabledPrefName, false);
  436. VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
  437. mojom::Feature::kMessages);
  438. VerifyFeatureStateChange(9u /* expected_index */, mojom::Feature::kMessages,
  439. mojom::FeatureState::kDisabledByUser);
  440. test_pref_service()->SetBoolean(kMessagesAllowedPrefName, false);
  441. VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
  442. mojom::Feature::kMessages);
  443. VerifyFeatureStateChange(10u /* expected_index */, mojom::Feature::kMessages,
  444. mojom::FeatureState::kProhibitedByPolicy);
  445. }
  446. TEST_F(MultiDeviceSetupFeatureStateManagerImplTest, SmartLock) {
  447. SetupFeatureStateManager();
  448. TryAllUnverifiedHostStatesAndVerifyFeatureState(mojom::Feature::kSmartLock);
  449. SetVerifiedHost();
  450. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  451. mojom::Feature::kSmartLock);
  452. SetSoftwareFeatureState(true /* use_local_device */,
  453. multidevice::SoftwareFeature::kSmartLockClient,
  454. multidevice::SoftwareFeatureState::kSupported);
  455. VerifyFeatureState(mojom::FeatureState::kUnavailableInsufficientSecurity,
  456. mojom::Feature::kSmartLock);
  457. VerifyFeatureStateChange(
  458. 2u /* expected_index */, mojom::Feature::kSmartLock,
  459. mojom::FeatureState::kUnavailableInsufficientSecurity);
  460. SetSoftwareFeatureState(false /* use_local_device */,
  461. multidevice::SoftwareFeature::kSmartLockHost,
  462. multidevice::SoftwareFeatureState::kEnabled);
  463. VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
  464. mojom::Feature::kSmartLock);
  465. VerifyFeatureStateChange(3u /* expected_index */, mojom::Feature::kSmartLock,
  466. mojom::FeatureState::kEnabledByUser);
  467. MakeBetterTogetherSuiteDisabledByUser();
  468. VerifyFeatureState(mojom::FeatureState::kUnavailableSuiteDisabled,
  469. mojom::Feature::kSmartLock);
  470. VerifyFeatureStateChange(5u /* expected_index */, mojom::Feature::kSmartLock,
  471. mojom::FeatureState::kUnavailableSuiteDisabled);
  472. test_pref_service()->SetBoolean(kSmartLockEnabledPrefName, false);
  473. VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
  474. mojom::Feature::kSmartLock);
  475. VerifyFeatureStateChange(6u /* expected_index */, mojom::Feature::kSmartLock,
  476. mojom::FeatureState::kDisabledByUser);
  477. test_pref_service()->SetBoolean(kSmartLockAllowedPrefName, false);
  478. VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
  479. mojom::Feature::kSmartLock);
  480. VerifyFeatureStateChange(7u /* expected_index */, mojom::Feature::kSmartLock,
  481. mojom::FeatureState::kProhibitedByPolicy);
  482. }
  483. TEST_F(MultiDeviceSetupFeatureStateManagerImplTest,
  484. PhoneHubBluetoothAddressNotSynced) {
  485. SetupFeatureStateManager(/*is_secondary_user=*/false,
  486. /*empty_mac_address=*/true);
  487. const std::vector<mojom::Feature> kAllPhoneHubFeatures{
  488. mojom::Feature::kPhoneHub, mojom::Feature::kPhoneHubCameraRoll,
  489. mojom::Feature::kPhoneHubNotifications,
  490. mojom::Feature::kPhoneHubTaskContinuation, mojom::Feature::kEche};
  491. for (const auto& phone_hub_feature : kAllPhoneHubFeatures)
  492. TryAllUnverifiedHostStatesAndVerifyFeatureState(phone_hub_feature);
  493. SetVerifiedHost();
  494. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  495. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  496. phone_hub_feature);
  497. }
  498. SetSoftwareFeatureState(true /* use_local_device */,
  499. multidevice::SoftwareFeature::kPhoneHubClient,
  500. multidevice::SoftwareFeatureState::kSupported);
  501. SetSoftwareFeatureState(true /* use_local_device */,
  502. multidevice::SoftwareFeature::kEcheClient,
  503. multidevice::SoftwareFeatureState::kSupported);
  504. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  505. VerifyFeatureState(mojom::FeatureState::kNotSupportedByPhone,
  506. phone_hub_feature);
  507. }
  508. // This pref is disabled for existing Better Together users; they must go to
  509. // settings to explicitly enable PhoneHub.
  510. test_pref_service()->SetBoolean(kPhoneHubEnabledPrefName, true);
  511. SetSoftwareFeatureState(false /* use_local_device */,
  512. multidevice::SoftwareFeature::kPhoneHubHost,
  513. multidevice::SoftwareFeatureState::kEnabled);
  514. SetSoftwareFeatureState(true /* use_local_device */,
  515. multidevice::SoftwareFeature::kEcheHost,
  516. multidevice::SoftwareFeatureState::kSupported);
  517. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  518. VerifyFeatureState(mojom::FeatureState::kNotSupportedByPhone,
  519. phone_hub_feature);
  520. }
  521. VerifyFeatureStateChange(kAllPhoneHubFeatures.size() * 2 /* expected_index */,
  522. mojom::Feature::kPhoneHub,
  523. mojom::FeatureState::kNotSupportedByPhone);
  524. MakeBetterTogetherSuiteDisabledByUser(
  525. /*expected_state_upon_disabling=*/mojom::FeatureState::kDisabledByUser);
  526. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  527. VerifyFeatureState(mojom::FeatureState::kNotSupportedByPhone,
  528. phone_hub_feature);
  529. }
  530. VerifyFeatureStateChange(
  531. kAllPhoneHubFeatures.size() * 2 + 1 /* expected_index */,
  532. mojom::Feature::kPhoneHub, mojom::FeatureState::kNotSupportedByPhone);
  533. test_pref_service()->SetBoolean(kPhoneHubNotificationsEnabledPrefName, false);
  534. VerifyFeatureState(mojom::FeatureState::kNotSupportedByPhone,
  535. mojom::Feature::kPhoneHubNotifications);
  536. test_pref_service()->SetBoolean(kPhoneHubNotificationsEnabledPrefName, true);
  537. test_pref_service()->SetBoolean(kPhoneHubEnabledPrefName, false);
  538. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  539. VerifyFeatureState(mojom::FeatureState::kNotSupportedByPhone,
  540. phone_hub_feature);
  541. }
  542. test_pref_service()->SetBoolean(kPhoneHubNotificationsAllowedPrefName, false);
  543. VerifyFeatureState(mojom::FeatureState::kNotSupportedByPhone,
  544. mojom::Feature::kPhoneHubNotifications);
  545. VerifyFeatureStateChange(
  546. kAllPhoneHubFeatures.size() * 2 + 2 /* expected_index */,
  547. mojom::Feature::kPhoneHubNotifications,
  548. mojom::FeatureState::kNotSupportedByPhone);
  549. // Prohibiting Phone Hub implicitly prohibits all of its sub-features.
  550. test_pref_service()->SetBoolean(kPhoneHubAllowedPrefName, false);
  551. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  552. VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
  553. phone_hub_feature);
  554. }
  555. VerifyFeatureStateChange(
  556. kAllPhoneHubFeatures.size() * 2 + 3 /* expected_index */,
  557. mojom::Feature::kPhoneHub, mojom::FeatureState::kProhibitedByPolicy);
  558. }
  559. TEST_F(MultiDeviceSetupFeatureStateManagerImplTest, PhoneHubForSecondaryUsers) {
  560. SetupFeatureStateManager(/*is_secondary_user=*/true);
  561. const std::vector<mojom::Feature> kAllPhoneHubFeatures{
  562. mojom::Feature::kPhoneHub, mojom::Feature::kPhoneHubCameraRoll,
  563. mojom::Feature::kPhoneHubNotifications,
  564. mojom::Feature::kPhoneHubTaskContinuation, mojom::Feature::kEche};
  565. for (const auto& phone_hub_feature : kAllPhoneHubFeatures)
  566. TryAllUnverifiedHostStatesAndVerifyFeatureState(phone_hub_feature);
  567. SetVerifiedHost();
  568. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  569. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  570. phone_hub_feature);
  571. }
  572. SetSoftwareFeatureState(true /* use_local_device */,
  573. multidevice::SoftwareFeature::kPhoneHubClient,
  574. multidevice::SoftwareFeatureState::kSupported);
  575. SetSoftwareFeatureState(true /* use_local_device */,
  576. multidevice::SoftwareFeature::kEcheClient,
  577. multidevice::SoftwareFeatureState::kSupported);
  578. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  579. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  580. phone_hub_feature);
  581. }
  582. // This pref should is disabled for existing Better Together users;
  583. // they must go to settings to explicitly enable PhoneHub.
  584. test_pref_service()->SetBoolean(kPhoneHubEnabledPrefName, true);
  585. SetSoftwareFeatureState(false /* use_local_device */,
  586. multidevice::SoftwareFeature::kPhoneHubHost,
  587. multidevice::SoftwareFeatureState::kEnabled);
  588. SetSoftwareFeatureState(false /* use_local_device */,
  589. multidevice::SoftwareFeature::kEcheHost,
  590. multidevice::SoftwareFeatureState::kEnabled);
  591. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  592. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  593. phone_hub_feature);
  594. }
  595. MakeBetterTogetherSuiteDisabledByUser(
  596. /*expected_state_upon_disabling=*/mojom::FeatureState::
  597. kNotSupportedByChromebook);
  598. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  599. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  600. phone_hub_feature);
  601. }
  602. test_pref_service()->SetBoolean(kPhoneHubNotificationsEnabledPrefName, false);
  603. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  604. mojom::Feature::kPhoneHubNotifications);
  605. test_pref_service()->SetBoolean(kPhoneHubNotificationsEnabledPrefName, true);
  606. test_pref_service()->SetBoolean(kPhoneHubEnabledPrefName, false);
  607. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  608. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  609. phone_hub_feature);
  610. }
  611. test_pref_service()->SetBoolean(kPhoneHubNotificationsAllowedPrefName, false);
  612. VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
  613. mojom::Feature::kPhoneHubNotifications);
  614. VerifyFeatureStateChange(kAllPhoneHubFeatures.size() * 2 /* expected_index */,
  615. mojom::Feature::kPhoneHubNotifications,
  616. mojom::FeatureState::kProhibitedByPolicy);
  617. // Prohibiting Phone Hub implicitly prohibits all of its sub-features.
  618. test_pref_service()->SetBoolean(kPhoneHubAllowedPrefName, false);
  619. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  620. VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
  621. phone_hub_feature);
  622. }
  623. VerifyFeatureStateChange(
  624. kAllPhoneHubFeatures.size() * 2 + 1 /* expected_index */,
  625. mojom::Feature::kPhoneHub, mojom::FeatureState::kProhibitedByPolicy);
  626. }
  627. TEST_F(MultiDeviceSetupFeatureStateManagerImplTest, PhoneHub) {
  628. SetupFeatureStateManager();
  629. const std::vector<mojom::Feature> kAllPhoneHubFeatures{
  630. mojom::Feature::kPhoneHub, mojom::Feature::kPhoneHubNotifications,
  631. mojom::Feature::kPhoneHubTaskContinuation};
  632. for (const auto& phone_hub_feature : kAllPhoneHubFeatures)
  633. TryAllUnverifiedHostStatesAndVerifyFeatureState(phone_hub_feature);
  634. SetVerifiedHost();
  635. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  636. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  637. phone_hub_feature);
  638. }
  639. SetSoftwareFeatureState(true /* use_local_device */,
  640. multidevice::SoftwareFeature::kPhoneHubClient,
  641. multidevice::SoftwareFeatureState::kSupported);
  642. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  643. VerifyFeatureState(mojom::FeatureState::kNotSupportedByPhone,
  644. phone_hub_feature);
  645. }
  646. VerifyFeatureStateChange(kAllPhoneHubFeatures.size() * 2 /* expected_index */,
  647. mojom::Feature::kPhoneHub,
  648. mojom::FeatureState::kNotSupportedByPhone);
  649. // The top-level Phone Hub enabled pref is disabled for existing Better
  650. // Together users; they must go to settings to explicitly enable PhoneHub.
  651. // Likewise, the Phone Hub notifications enabled pref is disabled by default
  652. // to ensure the phone grants access.
  653. test_pref_service()->SetBoolean(kPhoneHubEnabledPrefName, true);
  654. test_pref_service()->SetBoolean(kPhoneHubNotificationsEnabledPrefName, true);
  655. SetSoftwareFeatureState(false /* use_local_device */,
  656. multidevice::SoftwareFeature::kPhoneHubHost,
  657. multidevice::SoftwareFeatureState::kEnabled);
  658. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  659. VerifyFeatureState(mojom::FeatureState::kEnabledByUser, phone_hub_feature);
  660. }
  661. VerifyFeatureStateChange(
  662. kAllPhoneHubFeatures.size() * 2 + 1 /* expected_index */,
  663. mojom::Feature::kPhoneHub, mojom::FeatureState::kEnabledByUser);
  664. MakeBetterTogetherSuiteDisabledByUser();
  665. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  666. VerifyFeatureState(mojom::FeatureState::kUnavailableSuiteDisabled,
  667. phone_hub_feature);
  668. }
  669. VerifyFeatureStateChange(
  670. kAllPhoneHubFeatures.size() * 2 + 3 /* expected_index */,
  671. mojom::Feature::kPhoneHub,
  672. mojom::FeatureState::kUnavailableSuiteDisabled);
  673. test_pref_service()->SetBoolean(kPhoneHubNotificationsEnabledPrefName, false);
  674. VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
  675. mojom::Feature::kPhoneHubNotifications);
  676. VerifyFeatureStateChange(
  677. kAllPhoneHubFeatures.size() * 2 + 4 /* expected_index */,
  678. mojom::Feature::kPhoneHubNotifications,
  679. mojom::FeatureState::kDisabledByUser);
  680. // Re-enable Phone Hub notifications, then disable Phone Hub, which implicitly
  681. // implicitly makes all of its sub-features unavailable.
  682. test_pref_service()->SetBoolean(kPhoneHubNotificationsEnabledPrefName, true);
  683. test_pref_service()->SetBoolean(kPhoneHubEnabledPrefName, false);
  684. VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
  685. mojom::Feature::kPhoneHub);
  686. VerifyFeatureState(mojom::FeatureState::kUnavailableTopLevelFeatureDisabled,
  687. mojom::Feature::kPhoneHubNotifications);
  688. VerifyFeatureState(mojom::FeatureState::kUnavailableTopLevelFeatureDisabled,
  689. mojom::Feature::kPhoneHubTaskContinuation);
  690. VerifyFeatureStateChange(
  691. kAllPhoneHubFeatures.size() * 2 + 6 /* expected_index */,
  692. mojom::Feature::kPhoneHub, mojom::FeatureState::kDisabledByUser);
  693. test_pref_service()->SetBoolean(kPhoneHubNotificationsAllowedPrefName, false);
  694. VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
  695. mojom::Feature::kPhoneHubNotifications);
  696. VerifyFeatureStateChange(
  697. kAllPhoneHubFeatures.size() * 2 + 7 /* expected_index */,
  698. mojom::Feature::kPhoneHubNotifications,
  699. mojom::FeatureState::kProhibitedByPolicy);
  700. // Prohibiting Phone Hub implicitly prohibits all of its sub-features.
  701. test_pref_service()->SetBoolean(kPhoneHubAllowedPrefName, false);
  702. for (const auto& phone_hub_feature : kAllPhoneHubFeatures) {
  703. VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
  704. phone_hub_feature);
  705. }
  706. VerifyFeatureStateChange(
  707. kAllPhoneHubFeatures.size() * 2 + 8 /* expected_index */,
  708. mojom::Feature::kPhoneHub, mojom::FeatureState::kProhibitedByPolicy);
  709. }
  710. TEST_F(MultiDeviceSetupFeatureStateManagerImplTest, CameraRoll) {
  711. SetupFeatureStateManager();
  712. TryAllUnverifiedHostStatesAndVerifyFeatureState(
  713. mojom::Feature::kPhoneHubCameraRoll);
  714. SetVerifiedHost();
  715. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  716. mojom::Feature::kPhoneHub);
  717. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  718. mojom::Feature::kPhoneHubCameraRoll);
  719. SetSoftwareFeatureState(true /* use_local_device */,
  720. multidevice::SoftwareFeature::kPhoneHubClient,
  721. multidevice::SoftwareFeatureState::kSupported);
  722. SetSoftwareFeatureState(
  723. true /* use_local_device */,
  724. multidevice::SoftwareFeature::kPhoneHubCameraRollClient,
  725. multidevice::SoftwareFeatureState::kSupported);
  726. VerifyFeatureState(mojom::FeatureState::kNotSupportedByPhone,
  727. mojom::Feature::kPhoneHub);
  728. VerifyFeatureState(mojom::FeatureState::kNotSupportedByPhone,
  729. mojom::Feature::kPhoneHubCameraRoll);
  730. SetSoftwareFeatureState(false /* use_local_device */,
  731. multidevice::SoftwareFeature::kPhoneHubHost,
  732. multidevice::SoftwareFeatureState::kEnabled);
  733. SetSoftwareFeatureState(false /* use_local_device */,
  734. multidevice::SoftwareFeature::kPhoneHubCameraRollHost,
  735. multidevice::SoftwareFeatureState::kEnabled);
  736. VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
  737. mojom::Feature::kPhoneHub);
  738. VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
  739. mojom::Feature::kPhoneHubCameraRoll);
  740. // Camera Roll does not automatically enable with Phone Hub
  741. test_pref_service()->SetBoolean(kPhoneHubEnabledPrefName, true);
  742. VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
  743. mojom::Feature::kPhoneHub);
  744. VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
  745. mojom::Feature::kPhoneHubCameraRoll);
  746. // Enable Camera Roll
  747. test_pref_service()->SetBoolean(kPhoneHubCameraRollEnabledPrefName, true);
  748. VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
  749. mojom::Feature::kPhoneHub);
  750. VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
  751. mojom::Feature::kPhoneHubCameraRoll);
  752. // Camera Roll is automatically disabled when Phone Hub is disabled
  753. test_pref_service()->SetBoolean(kPhoneHubEnabledPrefName, false);
  754. VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
  755. mojom::Feature::kPhoneHub);
  756. VerifyFeatureState(mojom::FeatureState::kUnavailableTopLevelFeatureDisabled,
  757. mojom::Feature::kPhoneHubCameraRoll);
  758. // Camera Roll restores its previous state when Phone Hub is enabled
  759. test_pref_service()->SetBoolean(kPhoneHubEnabledPrefName, true);
  760. VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
  761. mojom::Feature::kPhoneHub);
  762. VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
  763. mojom::Feature::kPhoneHubCameraRoll);
  764. // Prohibiting Camera Roll does not prohibit Phone Hub
  765. test_pref_service()->SetBoolean(kPhoneHubCameraRollAllowedPrefName, false);
  766. VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
  767. mojom::Feature::kPhoneHub);
  768. VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
  769. mojom::Feature::kPhoneHubCameraRoll);
  770. // Prohibiting Phone Hub does prohibit Camera Roll
  771. test_pref_service()->SetBoolean(kPhoneHubCameraRollAllowedPrefName, true);
  772. test_pref_service()->SetBoolean(kPhoneHubAllowedPrefName, false);
  773. VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
  774. mojom::Feature::kPhoneHub);
  775. VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
  776. mojom::Feature::kPhoneHubCameraRoll);
  777. }
  778. TEST_F(MultiDeviceSetupFeatureStateManagerImplTest, WifiSync) {
  779. SetupFeatureStateManager();
  780. // Set the initial global state to disabled, so that the wifi sync feature
  781. // state will be |kDisabledByUser| when it becomes supported on both the host
  782. // and client devices.
  783. global_state_feature_managers()[mojom::Feature::kWifiSync]
  784. ->SetIsFeatureEnabled(false);
  785. TryAllUnverifiedHostStatesAndVerifyFeatureState(mojom::Feature::kWifiSync);
  786. SetVerifiedHost();
  787. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  788. mojom::Feature::kWifiSync);
  789. SetSoftwareFeatureState(true /* use_local_device */,
  790. multidevice::SoftwareFeature::kWifiSyncClient,
  791. multidevice::SoftwareFeatureState::kSupported);
  792. VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
  793. mojom::Feature::kWifiSync);
  794. VerifyFeatureStateChange(2u /* expected_index */, mojom::Feature::kWifiSync,
  795. mojom::FeatureState::kDisabledByUser);
  796. // The GlobalStateFeatureManager should be updated when the host state changes
  797. // to |kEnabled|. It will then update the feature state to |kEnabledByUser|.
  798. global_state_feature_managers()[mojom::Feature::kWifiSync]
  799. ->SetIsFeatureEnabled(true);
  800. SetSoftwareFeatureState(false /* use_local_device */,
  801. multidevice::SoftwareFeature::kWifiSyncHost,
  802. multidevice::SoftwareFeatureState::kEnabled);
  803. VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
  804. mojom::Feature::kWifiSync);
  805. VerifyFeatureStateChange(3u /* expected_index */, mojom::Feature::kWifiSync,
  806. mojom::FeatureState::kEnabledByUser);
  807. // Simulate user toggling the wifi sync state, and verify that the
  808. // GlobalStateFeatureManager was updated accordingly.
  809. manager()->SetFeatureEnabledState(mojom::Feature::kWifiSync, false);
  810. VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
  811. mojom::Feature::kWifiSync);
  812. VerifyFeatureStateChange(4u /* expected_index */, mojom::Feature::kWifiSync,
  813. mojom::FeatureState::kDisabledByUser);
  814. EXPECT_FALSE(global_state_feature_managers()[mojom::Feature::kWifiSync]
  815. ->IsFeatureEnabled());
  816. manager()->SetFeatureEnabledState(mojom::Feature::kWifiSync, true);
  817. VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
  818. mojom::Feature::kWifiSync);
  819. VerifyFeatureStateChange(5u /* expected_index */, mojom::Feature::kWifiSync,
  820. mojom::FeatureState::kEnabledByUser);
  821. EXPECT_TRUE(global_state_feature_managers()[mojom::Feature::kWifiSync]
  822. ->IsFeatureEnabled());
  823. MakeBetterTogetherSuiteDisabledByUser();
  824. VerifyFeatureState(mojom::FeatureState::kUnavailableSuiteDisabled,
  825. mojom::Feature::kWifiSync);
  826. VerifyFeatureStateChange(7u /* expected_index */, mojom::Feature::kWifiSync,
  827. mojom::FeatureState::kUnavailableSuiteDisabled);
  828. test_pref_service()->SetBoolean(kWifiSyncAllowedPrefName, false);
  829. VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
  830. mojom::Feature::kWifiSync);
  831. VerifyFeatureStateChange(8u /* expected_index */, mojom::Feature::kWifiSync,
  832. mojom::FeatureState::kProhibitedByPolicy);
  833. }
  834. TEST_F(MultiDeviceSetupFeatureStateManagerImplTest, Eche) {
  835. SetupFeatureStateManager();
  836. TryAllUnverifiedHostStatesAndVerifyFeatureState(mojom::Feature::kEche);
  837. SetVerifiedHost();
  838. SetSoftwareFeatureState(true /* use_local_device */,
  839. multidevice::SoftwareFeature::kPhoneHubClient,
  840. multidevice::SoftwareFeatureState::kSupported);
  841. VerifyFeatureState(mojom::FeatureState::kNotSupportedByPhone,
  842. mojom::Feature::kEche);
  843. VerifyFeatureStateChange(2u /* expected_index */, mojom::Feature::kEche,
  844. mojom::FeatureState::kNotSupportedByPhone);
  845. SetSoftwareFeatureState(false /* use_local_device */,
  846. multidevice::SoftwareFeature::kPhoneHubHost,
  847. multidevice::SoftwareFeatureState::kEnabled);
  848. VerifyFeatureState(mojom::FeatureState::kNotSupportedByChromebook,
  849. mojom::Feature::kEche);
  850. VerifyFeatureStateChange(3u /* expected_index */, mojom::Feature::kEche,
  851. mojom::FeatureState::kNotSupportedByChromebook);
  852. SetSoftwareFeatureState(true /* use_local_device */,
  853. multidevice::SoftwareFeature::kEcheClient,
  854. multidevice::SoftwareFeatureState::kSupported);
  855. VerifyFeatureStateChange(4u /* expected_index */, mojom::Feature::kEche,
  856. mojom::FeatureState::kNotSupportedByPhone);
  857. // The top-level Phone Hub enabled pref is disabled for existing Better
  858. // Together users; they must go to settings to explicitly enable PhoneHub.
  859. test_pref_service()->SetBoolean(kEcheEnabledPrefName, true);
  860. SetSoftwareFeatureState(false /* use_local_device */,
  861. multidevice::SoftwareFeature::kEcheHost,
  862. multidevice::SoftwareFeatureState::kSupported);
  863. VerifyFeatureState(mojom::FeatureState::kUnavailableTopLevelFeatureDisabled,
  864. mojom::Feature::kEche);
  865. VerifyFeatureStateChange(
  866. 5u /* expected_index */, mojom::Feature::kEche,
  867. mojom::FeatureState::kUnavailableTopLevelFeatureDisabled);
  868. test_pref_service()->SetBoolean(kPhoneHubEnabledPrefName, true);
  869. VerifyFeatureState(mojom::FeatureState::kEnabledByUser,
  870. mojom::Feature::kEche);
  871. VerifyFeatureStateChange(6u /* expected_index */, mojom::Feature::kEche,
  872. mojom::FeatureState::kEnabledByUser);
  873. MakeBetterTogetherSuiteDisabledByUser();
  874. VerifyFeatureState(mojom::FeatureState::kUnavailableSuiteDisabled,
  875. mojom::Feature::kEche);
  876. VerifyFeatureStateChange(8u /* expected_index */, mojom::Feature::kEche,
  877. mojom::FeatureState::kUnavailableSuiteDisabled);
  878. test_pref_service()->SetBoolean(kEcheEnabledPrefName, false);
  879. VerifyFeatureState(mojom::FeatureState::kDisabledByUser,
  880. mojom::Feature::kEche);
  881. VerifyFeatureStateChange(9u /* expected_index */, mojom::Feature::kEche,
  882. mojom::FeatureState::kDisabledByUser);
  883. // Re-enable Eche, then disable Phone Hub, which implicitly
  884. // makes Eche unavailable.
  885. test_pref_service()->SetBoolean(kEcheEnabledPrefName, true);
  886. test_pref_service()->SetBoolean(kPhoneHubEnabledPrefName, false);
  887. VerifyFeatureState(mojom::FeatureState::kUnavailableTopLevelFeatureDisabled,
  888. mojom::Feature::kEche);
  889. VerifyFeatureStateChange(
  890. 11u /* expected_index */, mojom::Feature::kEche,
  891. mojom::FeatureState::kUnavailableTopLevelFeatureDisabled);
  892. // Prohibiting Phone Hub implicitly prohibits Eche features.
  893. test_pref_service()->SetBoolean(kPhoneHubAllowedPrefName, false);
  894. VerifyFeatureState(mojom::FeatureState::kProhibitedByPolicy,
  895. mojom::Feature::kEche);
  896. VerifyFeatureStateChange(12u /* expected_index */, mojom::Feature::kEche,
  897. mojom::FeatureState::kProhibitedByPolicy);
  898. }
  899. } // namespace multidevice_setup
  900. } // namespace ash