multidevice_setup_state_updater_unittest.cc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. // Copyright 2020 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/components/phonehub/multidevice_setup_state_updater.h"
  5. #include "ash/components/phonehub/fake_multidevice_feature_access_manager.h"
  6. #include "ash/services/multidevice_setup/public/cpp/fake_multidevice_setup_client.h"
  7. #include "ash/services/multidevice_setup/public/cpp/prefs.h"
  8. #include "components/prefs/testing_pref_service.h"
  9. #include "testing/gtest/include/gtest/gtest.h"
  10. namespace ash {
  11. namespace phonehub {
  12. using multidevice_setup::mojom::Feature;
  13. using multidevice_setup::mojom::FeatureState;
  14. using multidevice_setup::mojom::HostStatus;
  15. class MultideviceSetupStateUpdaterTest : public testing::Test {
  16. protected:
  17. MultideviceSetupStateUpdaterTest() = default;
  18. ~MultideviceSetupStateUpdaterTest() override = default;
  19. MultideviceSetupStateUpdaterTest(const MultideviceSetupStateUpdaterTest&) =
  20. delete;
  21. MultideviceSetupStateUpdaterTest& operator=(
  22. const MultideviceSetupStateUpdaterTest&) = delete;
  23. // testing::Test:
  24. void SetUp() override {
  25. MultideviceSetupStateUpdater::RegisterPrefs(pref_service_.registry());
  26. multidevice_setup::RegisterFeaturePrefs(pref_service_.registry());
  27. // Set the host status and feature state to realistic default values used
  28. // during start-up.
  29. SetFeatureState(Feature::kPhoneHub,
  30. FeatureState::kUnavailableNoVerifiedHost_NoEligibleHosts);
  31. SetHostStatus(HostStatus::kNoEligibleHosts);
  32. }
  33. void CreateUpdater() {
  34. updater_ = std::make_unique<MultideviceSetupStateUpdater>(
  35. &pref_service_, &fake_multidevice_setup_client_,
  36. &fake_multidevice_feature_access_manager_);
  37. }
  38. void DestroyUpdater() { updater_.reset(); }
  39. void SetNotificationAccess(bool enabled) {
  40. fake_multidevice_feature_access_manager_
  41. .SetNotificationAccessStatusInternal(
  42. enabled
  43. ? MultideviceFeatureAccessManager::AccessStatus::kAccessGranted
  44. : MultideviceFeatureAccessManager::AccessStatus::
  45. kAvailableButNotGranted,
  46. MultideviceFeatureAccessManager::AccessProhibitedReason::kUnknown);
  47. }
  48. void SetCameraRollAccess(bool enabled) {
  49. fake_multidevice_feature_access_manager_.SetCameraRollAccessStatusInternal(
  50. enabled ? MultideviceFeatureAccessManager::AccessStatus::kAccessGranted
  51. : MultideviceFeatureAccessManager::AccessStatus::
  52. kAvailableButNotGranted);
  53. }
  54. void SetFeatureState(Feature feature, FeatureState feature_state) {
  55. fake_multidevice_setup_client_.SetFeatureState(feature, feature_state);
  56. }
  57. void SetHostStatus(HostStatus host_status) {
  58. fake_multidevice_setup_client_.SetHostStatusWithDevice(
  59. std::make_pair(host_status, absl::nullopt /* host_device */));
  60. }
  61. multidevice_setup::FakeMultiDeviceSetupClient*
  62. fake_multidevice_setup_client() {
  63. return &fake_multidevice_setup_client_;
  64. }
  65. void SetFeatureEnabledState(const std::string& pref_name, bool enabled) {
  66. pref_service_.SetBoolean(pref_name, enabled);
  67. }
  68. void ForceNotifyNotificationAccessChanged() {
  69. fake_multidevice_feature_access_manager_.NotifyNotificationAccessChanged();
  70. }
  71. void ForceNotifyCameraRollAccessChanged() {
  72. fake_multidevice_feature_access_manager_.NotifyCameraRollAccessChanged();
  73. }
  74. private:
  75. std::unique_ptr<MultideviceSetupStateUpdater> updater_;
  76. TestingPrefServiceSimple pref_service_;
  77. multidevice_setup::FakeMultiDeviceSetupClient fake_multidevice_setup_client_;
  78. FakeMultideviceFeatureAccessManager fake_multidevice_feature_access_manager_;
  79. };
  80. TEST_F(MultideviceSetupStateUpdaterTest, EnablePhoneHub) {
  81. CreateUpdater();
  82. // Test that there is a call to enable kPhoneHub--if it is currently
  83. // disabled--when host status goes from
  84. // kHostSetLocallyButWaitingForBackendConfirmation to kHostVerified.
  85. SetFeatureState(Feature::kPhoneHub, FeatureState::kDisabledByUser);
  86. SetHostStatus(HostStatus::kHostSetLocallyButWaitingForBackendConfirmation);
  87. SetHostStatus(HostStatus::kHostVerified);
  88. fake_multidevice_setup_client()->InvokePendingSetFeatureEnabledStateCallback(
  89. /*expected_feature=*/Feature::kPhoneHub,
  90. /*expected_enabled=*/true, /*expected_auth_token=*/absl::nullopt,
  91. /*success=*/true);
  92. }
  93. TEST_F(MultideviceSetupStateUpdaterTest, EnablePhoneHub_SetButNotVerified) {
  94. CreateUpdater();
  95. // Test that there is a call to enable kPhoneHub when host status goes from
  96. // kHostSetLocallyButWaitingForBackendConfirmation to
  97. // kHostSetButNotYetVerified, then finally to kHostVerified, when the feature
  98. // is currently disabled.
  99. SetFeatureState(Feature::kPhoneHub, FeatureState::kDisabledByUser);
  100. SetHostStatus(HostStatus::kHostSetLocallyButWaitingForBackendConfirmation);
  101. SetHostStatus(HostStatus::kHostSetButNotYetVerified);
  102. SetHostStatus(HostStatus::kHostVerified);
  103. fake_multidevice_setup_client()->InvokePendingSetFeatureEnabledStateCallback(
  104. /*expected_feature=*/Feature::kPhoneHub,
  105. /*expected_enabled=*/true, /*expected_auth_token=*/absl::nullopt,
  106. /*success=*/true);
  107. }
  108. TEST_F(MultideviceSetupStateUpdaterTest,
  109. EnablePhoneHub_WaitForDisabledStateBeforeEnabling) {
  110. CreateUpdater();
  111. // After the host is verified, ensure that we wait until the feature state is
  112. // "disabled" before enabling the feature. We don't want to go from
  113. // kNotSupportedByPhone to enabled, for instance.
  114. SetFeatureState(Feature::kPhoneHub, FeatureState::kNotSupportedByPhone);
  115. SetHostStatus(HostStatus::kHostSetLocallyButWaitingForBackendConfirmation);
  116. SetHostStatus(HostStatus::kHostVerified);
  117. SetFeatureState(Feature::kPhoneHub, FeatureState::kDisabledByUser);
  118. fake_multidevice_setup_client()->InvokePendingSetFeatureEnabledStateCallback(
  119. /*expected_feature=*/Feature::kPhoneHub,
  120. /*expected_enabled=*/true, /*expected_auth_token=*/absl::nullopt,
  121. /*success=*/true);
  122. }
  123. TEST_F(MultideviceSetupStateUpdaterTest,
  124. EnablePhoneHub_DisabledStateSetBeforeVerification) {
  125. CreateUpdater();
  126. // Much like EnablePhoneHub_WaitForDisabledStateBeforeEnabling, but here we
  127. // test that the order of the feature being set to disabled and the host being
  128. // verified does not matter.
  129. SetFeatureState(Feature::kPhoneHub, FeatureState::kNotSupportedByPhone);
  130. SetHostStatus(HostStatus::kHostSetLocallyButWaitingForBackendConfirmation);
  131. SetFeatureState(Feature::kPhoneHub, FeatureState::kDisabledByUser);
  132. SetHostStatus(HostStatus::kHostVerified);
  133. fake_multidevice_setup_client()->InvokePendingSetFeatureEnabledStateCallback(
  134. /*expected_feature=*/Feature::kPhoneHub,
  135. /*expected_enabled=*/true, /*expected_auth_token=*/absl::nullopt,
  136. /*success=*/true);
  137. }
  138. TEST_F(MultideviceSetupStateUpdaterTest,
  139. EnablePhoneHub_ReenableAfterMultideviceSetup) {
  140. CreateUpdater();
  141. // The user has a verified host phone, but chose to disable the Phone Hub
  142. // toggle in Settings.
  143. SetHostStatus(HostStatus::kHostVerified);
  144. SetFeatureState(Feature::kPhoneHub, FeatureState::kDisabledByUser);
  145. // The user disconnects the phone from the multi-device suite.
  146. SetHostStatus(HostStatus::kEligibleHostExistsButNoHostSet);
  147. // The user goes through multi-device setup again.
  148. SetHostStatus(HostStatus::kHostSetLocallyButWaitingForBackendConfirmation);
  149. SetHostStatus(HostStatus::kHostVerified);
  150. // The Phone Hub feature is automatically re-enabled.
  151. fake_multidevice_setup_client()->InvokePendingSetFeatureEnabledStateCallback(
  152. /*expected_feature=*/Feature::kPhoneHub,
  153. /*expected_enabled=*/true, /*expected_auth_token=*/absl::nullopt,
  154. /*success=*/true);
  155. }
  156. TEST_F(MultideviceSetupStateUpdaterTest, EnablePhoneHub_PersistIntentToEnable) {
  157. CreateUpdater();
  158. // Indicate intent to enable Phone Hub after host verification.
  159. SetHostStatus(HostStatus::kHostSetLocallyButWaitingForBackendConfirmation);
  160. // Simulate the user logging out and back in, for instance. And even though
  161. // some transient default values are set for the host status and feature
  162. // state, we should preserve the intent to enable Phone Hub.
  163. DestroyUpdater();
  164. SetFeatureState(Feature::kPhoneHub,
  165. FeatureState::kUnavailableNoVerifiedHost_NoEligibleHosts);
  166. SetHostStatus(HostStatus::kNoEligibleHosts);
  167. CreateUpdater();
  168. // The host status and feature state update to expected values.
  169. SetHostStatus(HostStatus::kHostVerified);
  170. SetFeatureState(Feature::kPhoneHub, FeatureState::kDisabledByUser);
  171. // The Phone Hub feature is expected to be enabled.
  172. fake_multidevice_setup_client()->InvokePendingSetFeatureEnabledStateCallback(
  173. /*expected_feature=*/Feature::kPhoneHub,
  174. /*expected_enabled=*/true, /*expected_auth_token=*/absl::nullopt,
  175. /*success=*/true);
  176. }
  177. TEST_F(
  178. MultideviceSetupStateUpdaterTest,
  179. EnablePhoneHub_PersistIntentToEnable_HandleTransientHostOrFeatureStates) {
  180. CreateUpdater();
  181. // Indicate intent to enable Phone Hub after host verification.
  182. SetHostStatus(HostStatus::kHostSetLocallyButWaitingForBackendConfirmation);
  183. // Simulate the user logging out and back in.
  184. DestroyUpdater();
  185. CreateUpdater();
  186. // Make sure to ignore transient updates after start-up. In other words,
  187. // maintain our intent to enable Phone Hub after verification.
  188. SetFeatureState(Feature::kPhoneHub,
  189. FeatureState::kUnavailableNoVerifiedHost_NoEligibleHosts);
  190. SetHostStatus(HostStatus::kNoEligibleHosts);
  191. // The host status and feature state update to expected values.
  192. SetHostStatus(HostStatus::kHostVerified);
  193. SetFeatureState(Feature::kPhoneHub, FeatureState::kDisabledByUser);
  194. // The Phone Hub feature is expected to be enabled.
  195. fake_multidevice_setup_client()->InvokePendingSetFeatureEnabledStateCallback(
  196. /*expected_feature=*/Feature::kPhoneHub,
  197. /*expected_enabled=*/true, /*expected_auth_token=*/absl::nullopt,
  198. /*success=*/true);
  199. }
  200. TEST_F(MultideviceSetupStateUpdaterTest, RevokePhoneHubNotificationsAccess) {
  201. SetNotificationAccess(true);
  202. CreateUpdater();
  203. // Test that there is a call to disable kPhoneHubNotifications when
  204. // notification access has been revoked.
  205. SetNotificationAccess(false);
  206. fake_multidevice_setup_client()->InvokePendingSetFeatureEnabledStateCallback(
  207. /*expected_feature=*/Feature::kPhoneHubNotifications,
  208. /*expected_enabled=*/false, /*expected_auth_token=*/absl::nullopt,
  209. /*success=*/true);
  210. }
  211. TEST_F(MultideviceSetupStateUpdaterTest, InvokePhoneHubNotificationsAccess) {
  212. SetNotificationAccess(false);
  213. SetFeatureState(Feature::kPhoneHub, FeatureState::kEnabledByUser);
  214. SetFeatureState(Feature::kPhoneHubNotifications,
  215. FeatureState::kDisabledByUser);
  216. CreateUpdater();
  217. // Test that there is a call to enable kPhoneHubNotifications when
  218. // notification access has been invoked.
  219. SetNotificationAccess(true);
  220. fake_multidevice_setup_client()->InvokePendingSetFeatureEnabledStateCallback(
  221. /*expected_feature=*/Feature::kPhoneHubNotifications,
  222. /*expected_enabled=*/true, /*expected_auth_token=*/absl::nullopt,
  223. /*success=*/true);
  224. }
  225. TEST_F(MultideviceSetupStateUpdaterTest,
  226. InitiallyEnablePhoneHubNotifications_OnlyEnableFromDefaultState) {
  227. SetNotificationAccess(true);
  228. SetFeatureState(Feature::kPhoneHub, FeatureState::kEnabledByUser);
  229. CreateUpdater();
  230. // If the notifications feature has not been explicitly set yet, enable it
  231. // when Phone Hub is enabled and access has been granted.
  232. ForceNotifyNotificationAccessChanged();
  233. fake_multidevice_setup_client()->InvokePendingSetFeatureEnabledStateCallback(
  234. /*expected_feature=*/Feature::kPhoneHubNotifications,
  235. /*expected_enabled=*/true, /*expected_auth_token=*/absl::nullopt,
  236. /*success=*/true);
  237. }
  238. TEST_F(MultideviceSetupStateUpdaterTest,
  239. ShouldNotEnablePhoneHubNotificationsIfFeatureIsNotDefaultState) {
  240. SetNotificationAccess(true);
  241. SetFeatureState(Feature::kPhoneHub, FeatureState::kEnabledByUser);
  242. // Simulate the notifications feature has been changed by user.
  243. SetFeatureEnabledState(
  244. ash::multidevice_setup::kPhoneHubNotificationsEnabledPrefName, false);
  245. CreateUpdater();
  246. // We take no action after access is granted because the Phone Hub
  247. // notifications feature state was already explicitly set; we respect the
  248. // user's choice.
  249. ForceNotifyNotificationAccessChanged();
  250. EXPECT_EQ(
  251. 0u,
  252. fake_multidevice_setup_client()->NumPendingSetFeatureEnabledStateCalls());
  253. }
  254. TEST_F(MultideviceSetupStateUpdaterTest,
  255. InitiallyEnableCameraRoll_OnlyEnableFromDefaultState) {
  256. SetCameraRollAccess(true);
  257. SetFeatureState(Feature::kPhoneHub, FeatureState::kEnabledByUser);
  258. CreateUpdater();
  259. // If the camera roll feature has not been explicitly set yet, enable it
  260. // when Phone Hub is enabled and access has been granted.
  261. ForceNotifyCameraRollAccessChanged();
  262. fake_multidevice_setup_client()->InvokePendingSetFeatureEnabledStateCallback(
  263. /*expected_feature=*/Feature::kPhoneHubCameraRoll,
  264. /*expected_enabled=*/true, /*expected_auth_token=*/absl::nullopt,
  265. /*success=*/true);
  266. }
  267. TEST_F(MultideviceSetupStateUpdaterTest,
  268. ShouldNotEnableCameraRollIfFeatureIsNotDefaultState) {
  269. SetCameraRollAccess(true);
  270. SetFeatureState(Feature::kPhoneHub, FeatureState::kEnabledByUser);
  271. // Simulate the camera roll feature has been changed by user.
  272. SetFeatureEnabledState(
  273. ash::multidevice_setup::kPhoneHubCameraRollEnabledPrefName, false);
  274. CreateUpdater();
  275. // We take no action after access is granted because the camera roll
  276. // feature state was already explicitly set; we respect the user's choice.
  277. ForceNotifyCameraRollAccessChanged();
  278. EXPECT_EQ(
  279. 0u,
  280. fake_multidevice_setup_client()->NumPendingSetFeatureEnabledStateCalls());
  281. }
  282. TEST_F(MultideviceSetupStateUpdaterTest,
  283. InitiallyEnableCameraRoll_DisablePhoneHub) {
  284. SetCameraRollAccess(false);
  285. SetFeatureState(Feature::kPhoneHub, FeatureState::kEnabledByUser);
  286. // Explicitly disable Phone Hub, all sub feature should be disabled
  287. SetFeatureState(Feature::kPhoneHub, FeatureState::kDisabledByUser);
  288. CreateUpdater();
  289. // No action after access is granted
  290. SetCameraRollAccess(true);
  291. EXPECT_EQ(
  292. 0u,
  293. fake_multidevice_setup_client()->NumPendingSetFeatureEnabledStateCalls());
  294. }
  295. TEST_F(MultideviceSetupStateUpdaterTest, RevokePhoneHubCameraRollAccess) {
  296. SetCameraRollAccess(true);
  297. CreateUpdater();
  298. // Test that there is a call to disable kPhoneHubCameraRoll when camera roll
  299. // access has been revoked.
  300. SetCameraRollAccess(false);
  301. fake_multidevice_setup_client()->InvokePendingSetFeatureEnabledStateCallback(
  302. /*expected_feature=*/Feature::kPhoneHubCameraRoll,
  303. /*expected_enabled=*/false, /*expected_auth_token=*/absl::nullopt,
  304. /*success=*/true);
  305. }
  306. TEST_F(MultideviceSetupStateUpdaterTest, InvokePhoneHubCameraRollAccess) {
  307. SetCameraRollAccess(false);
  308. SetFeatureState(Feature::kPhoneHub, FeatureState::kEnabledByUser);
  309. SetFeatureState(Feature::kPhoneHubCameraRoll, FeatureState::kDisabledByUser);
  310. CreateUpdater();
  311. // Test that there is a call to enable kPhoneHubCameraRoll when camera roll
  312. // access has been invoked.
  313. SetCameraRollAccess(true);
  314. fake_multidevice_setup_client()->InvokePendingSetFeatureEnabledStateCallback(
  315. /*expected_feature=*/Feature::kPhoneHubCameraRoll,
  316. /*expected_enabled=*/true, /*expected_auth_token=*/absl::nullopt,
  317. /*success=*/true);
  318. }
  319. } // namespace phonehub
  320. } // namespace ash