multidevice_feature_access_manager_impl_unittest.cc 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944
  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_feature_access_manager_impl.h"
  5. #include <memory>
  6. #include "ash/components/phonehub/combined_access_setup_operation.h"
  7. #include "ash/components/phonehub/fake_connection_scheduler.h"
  8. #include "ash/components/phonehub/fake_feature_status_provider.h"
  9. #include "ash/components/phonehub/fake_message_sender.h"
  10. #include "ash/components/phonehub/notification_access_setup_operation.h"
  11. #include "ash/components/phonehub/pref_names.h"
  12. #include "ash/services/multidevice_setup/public/cpp/fake_multidevice_setup_client.h"
  13. #include "ash/webui/eche_app_ui/pref_names.h"
  14. #include "components/prefs/pref_registry_simple.h"
  15. #include "components/prefs/testing_pref_service.h"
  16. #include "testing/gtest/include/gtest/gtest.h"
  17. namespace ash {
  18. namespace phonehub {
  19. namespace {
  20. using AccessStatus = MultideviceFeatureAccessManager::AccessStatus;
  21. using AccessProhibitedReason =
  22. MultideviceFeatureAccessManager::AccessProhibitedReason;
  23. using FeatureState = multidevice_setup::mojom::FeatureState;
  24. using Feature = multidevice_setup::mojom::Feature;
  25. class FakeObserver : public MultideviceFeatureAccessManager::Observer {
  26. public:
  27. FakeObserver() = default;
  28. ~FakeObserver() override = default;
  29. size_t num_calls() const { return num_calls_; }
  30. // MultideviceFeatureAccessManager::Observer:
  31. void OnNotificationAccessChanged() override { ++num_calls_; }
  32. // MultideviceFeatureAccessManager::Observer:
  33. void OnCameraRollAccessChanged() override { ++num_calls_; }
  34. // MultideviceFeatureAccessManager::Observer:
  35. void OnFeatureSetupRequestSupportedChanged() override { ++num_calls_; }
  36. // MultideviceFeatureAccessManager::Observer:
  37. void OnAppsAccessChanged() override { ++num_calls_; }
  38. private:
  39. size_t num_calls_ = 0;
  40. };
  41. class FakeNotificationAccessSetupOperationDelegate
  42. : public NotificationAccessSetupOperation::Delegate {
  43. public:
  44. FakeNotificationAccessSetupOperationDelegate() = default;
  45. ~FakeNotificationAccessSetupOperationDelegate() override = default;
  46. NotificationAccessSetupOperation::Status status() const { return status_; }
  47. // NotificationAccessSetupOperation::Delegate:
  48. void OnNotificationStatusChange(
  49. NotificationAccessSetupOperation::Status new_status) override {
  50. status_ = new_status;
  51. }
  52. private:
  53. NotificationAccessSetupOperation::Status status_ =
  54. NotificationAccessSetupOperation::Status::kConnecting;
  55. };
  56. class FakeCombinedAccessSetupOperationDelegate
  57. : public CombinedAccessSetupOperation::Delegate {
  58. public:
  59. FakeCombinedAccessSetupOperationDelegate() = default;
  60. ~FakeCombinedAccessSetupOperationDelegate() override = default;
  61. CombinedAccessSetupOperation::Status status() const { return status_; }
  62. // CombinedAccessSetupOperation::Delegate:
  63. void OnCombinedStatusChange(
  64. CombinedAccessSetupOperation::Status new_status) override {
  65. status_ = new_status;
  66. }
  67. private:
  68. CombinedAccessSetupOperation::Status status_ =
  69. CombinedAccessSetupOperation::Status::kConnecting;
  70. };
  71. } // namespace
  72. class MultideviceFeatureAccessManagerImplTest : public testing::Test {
  73. protected:
  74. MultideviceFeatureAccessManagerImplTest() = default;
  75. MultideviceFeatureAccessManagerImplTest(
  76. const MultideviceFeatureAccessManagerImplTest&) = delete;
  77. MultideviceFeatureAccessManagerImplTest& operator=(
  78. const MultideviceFeatureAccessManagerImplTest&) = delete;
  79. ~MultideviceFeatureAccessManagerImplTest() override = default;
  80. // testing::Test:
  81. void SetUp() override {
  82. fake_multidevice_setup_client_ =
  83. std::make_unique<multidevice_setup::FakeMultiDeviceSetupClient>();
  84. MultideviceFeatureAccessManagerImpl::RegisterPrefs(
  85. pref_service_.registry());
  86. fake_feature_status_provider_ =
  87. std::make_unique<FakeFeatureStatusProvider>();
  88. fake_message_sender_ = std::make_unique<FakeMessageSender>();
  89. fake_connection_scheduler_ = std::make_unique<FakeConnectionScheduler>();
  90. pref_service_.registry()->RegisterIntegerPref(
  91. eche_app::prefs::kAppsAccessStatus,
  92. /*default_value=*/0);
  93. }
  94. void TearDown() override { manager_->RemoveObserver(&fake_observer_); }
  95. void InitializeAccessStatus(
  96. AccessStatus notification_expected_status,
  97. AccessStatus camera_roll_expected_status,
  98. AccessProhibitedReason reason = AccessProhibitedReason::kUnknown,
  99. bool feature_setup_request_supported = false) {
  100. pref_service_.SetInteger(prefs::kNotificationAccessStatus,
  101. static_cast<int>(notification_expected_status));
  102. pref_service_.SetInteger(prefs::kCameraRollAccessStatus,
  103. static_cast<int>(camera_roll_expected_status));
  104. pref_service_.SetInteger(prefs::kNotificationAccessProhibitedReason,
  105. static_cast<int>(reason));
  106. pref_service_.SetBoolean(prefs::kFeatureSetupRequestSupported,
  107. feature_setup_request_supported);
  108. SetNeedsOneTimeNotificationAccessUpdate(/*needs_update=*/false);
  109. manager_ = std::make_unique<MultideviceFeatureAccessManagerImpl>(
  110. &pref_service_, fake_multidevice_setup_client_.get(),
  111. fake_feature_status_provider_.get(), fake_message_sender_.get(),
  112. fake_connection_scheduler_.get());
  113. manager_->AddObserver(&fake_observer_);
  114. }
  115. void InitializeAppsAccessStatus(MultideviceFeatureAccessManager::AccessStatus
  116. apps_access_expected_status) {
  117. pref_service_.SetInteger(eche_app::prefs::kAppsAccessStatus,
  118. static_cast<int>(apps_access_expected_status));
  119. }
  120. NotificationAccessSetupOperation::Status
  121. GetNotificationAccessSetupOperationStatus() {
  122. return fake_notification_delegate_.status();
  123. }
  124. CombinedAccessSetupOperation::Status GetCombinedAccessSetupOperationStatus() {
  125. return fake_combined_delegate_.status();
  126. }
  127. void VerifyNotificationAccessGrantedState(AccessStatus expected_status) {
  128. VerifyNotificationAccessGrantedState(expected_status,
  129. AccessProhibitedReason::kUnknown);
  130. }
  131. void VerifyNotificationAccessGrantedState(
  132. AccessStatus expected_status,
  133. AccessProhibitedReason expected_reason) {
  134. EXPECT_EQ(static_cast<int>(expected_status),
  135. pref_service_.GetInteger(prefs::kNotificationAccessStatus));
  136. EXPECT_EQ(expected_status, manager_->GetNotificationAccessStatus());
  137. EXPECT_EQ(
  138. static_cast<int>(expected_reason),
  139. pref_service_.GetInteger(prefs::kNotificationAccessProhibitedReason));
  140. EXPECT_EQ(expected_reason,
  141. manager_->GetNotificationAccessProhibitedReason());
  142. }
  143. void VerifyCameraRollAccessGrantedState(AccessStatus expected_status) {
  144. EXPECT_EQ(static_cast<int>(expected_status),
  145. pref_service_.GetInteger(prefs::kCameraRollAccessStatus));
  146. EXPECT_EQ(expected_status, manager_->GetCameraRollAccessStatus());
  147. }
  148. void VerifyAppsAccessGrantedState(
  149. MultideviceFeatureAccessManager::AccessStatus expected_status) {
  150. EXPECT_EQ(static_cast<int>(expected_status),
  151. pref_service_.GetInteger(eche_app::prefs::kAppsAccessStatus));
  152. EXPECT_EQ(expected_status, manager_->GetAppsAccessStatus());
  153. }
  154. void VerifyFeatureSetupRequestSupported(bool expected) {
  155. EXPECT_EQ(expected,
  156. pref_service_.GetBoolean(prefs::kFeatureSetupRequestSupported));
  157. EXPECT_EQ(expected, manager_->GetFeatureSetupRequestSupported());
  158. }
  159. bool HasMultideviceFeatureSetupUiBeenDismissed() {
  160. return manager_->HasMultideviceFeatureSetupUiBeenDismissed();
  161. }
  162. void DismissSetupRequiredUi() { manager_->DismissSetupRequiredUi(); }
  163. std::unique_ptr<NotificationAccessSetupOperation>
  164. StartNotificationSetupOperation() {
  165. return manager_->AttemptNotificationSetup(&fake_notification_delegate_);
  166. }
  167. std::unique_ptr<CombinedAccessSetupOperation> StartCombinedSetupOperation(
  168. bool camera_roll,
  169. bool notifications) {
  170. return manager_->AttemptCombinedFeatureSetup(camera_roll, notifications,
  171. &fake_combined_delegate_);
  172. }
  173. bool IsNotificationSetupOperationInProgress() {
  174. return manager_->IsNotificationSetupOperationInProgress();
  175. }
  176. void SetNotificationAccessStatusInternal(AccessStatus status,
  177. AccessProhibitedReason reason) {
  178. manager_->SetNotificationAccessStatusInternal(status, reason);
  179. }
  180. void SetCameraRollAccessStatusInternal(AccessStatus status) {
  181. manager_->SetCameraRollAccessStatusInternal(status);
  182. }
  183. void SetFeatureSetupRequestSupportedInternal(bool supported) {
  184. manager_->SetFeatureSetupRequestSupportedInternal(supported);
  185. }
  186. void SetFeatureStatus(FeatureStatus status) {
  187. fake_feature_status_provider_->SetStatus(status);
  188. }
  189. FeatureStatus GetFeatureStatus() {
  190. return fake_feature_status_provider_->GetStatus();
  191. }
  192. size_t GetNumScheduleConnectionNowCalls() const {
  193. return fake_connection_scheduler_->num_schedule_connection_now_calls();
  194. }
  195. size_t GetNumShowNotificationAccessSetupRequestCount() const {
  196. return fake_message_sender_->show_notification_access_setup_request_count();
  197. }
  198. size_t GetCombinedAccessSetupRequestCallCount() const {
  199. return fake_message_sender_->GetFeatureSetupRequestCallCount();
  200. }
  201. size_t GetNumObserverCalls() const { return fake_observer_.num_calls(); }
  202. void SetNeedsOneTimeNotificationAccessUpdate(bool needs_update) {
  203. pref_service_.SetBoolean(prefs::kNeedsOneTimeNotificationAccessUpdate,
  204. needs_update);
  205. }
  206. void SetEcheFeatureState(FeatureState feature_state) {
  207. fake_multidevice_setup_client_->SetFeatureState(
  208. multidevice_setup::mojom::Feature::kEche, feature_state);
  209. }
  210. bool IsAccessRequestAllowed(Feature feature) {
  211. return manager_->IsAccessRequestAllowed(feature);
  212. }
  213. private:
  214. TestingPrefServiceSimple pref_service_;
  215. FakeObserver fake_observer_;
  216. FakeNotificationAccessSetupOperationDelegate fake_notification_delegate_;
  217. FakeCombinedAccessSetupOperationDelegate fake_combined_delegate_;
  218. std::unique_ptr<multidevice_setup::FakeMultiDeviceSetupClient>
  219. fake_multidevice_setup_client_;
  220. std::unique_ptr<FakeFeatureStatusProvider> fake_feature_status_provider_;
  221. std::unique_ptr<FakeMessageSender> fake_message_sender_;
  222. std::unique_ptr<FakeConnectionScheduler> fake_connection_scheduler_;
  223. std::unique_ptr<MultideviceFeatureAccessManager> manager_;
  224. };
  225. TEST_F(MultideviceFeatureAccessManagerImplTest, FeatureNotReadyForAccess) {
  226. InitializeAccessStatus(AccessStatus::kAccessGranted,
  227. AccessStatus::kAccessGranted);
  228. SetEcheFeatureState(FeatureState::kNotSupportedByChromebook);
  229. EXPECT_FALSE(IsAccessRequestAllowed(Feature::kEche));
  230. }
  231. TEST_F(MultideviceFeatureAccessManagerImplTest, FeatureReadyForAccess) {
  232. InitializeAccessStatus(AccessStatus::kAccessGranted,
  233. AccessStatus::kAccessGranted);
  234. SetEcheFeatureState(FeatureState::kEnabledByUser);
  235. EXPECT_TRUE(IsAccessRequestAllowed(Feature::kEche));
  236. SetEcheFeatureState(FeatureState::kDisabledByUser);
  237. EXPECT_TRUE(IsAccessRequestAllowed(Feature::kEche));
  238. }
  239. TEST_F(MultideviceFeatureAccessManagerImplTest, ShouldShowSetupRequiredUi) {
  240. // Notification setup is not dismissed initially even when access has been
  241. // granted.
  242. InitializeAccessStatus(AccessStatus::kAccessGranted,
  243. AccessStatus::kAccessGranted);
  244. EXPECT_FALSE(HasMultideviceFeatureSetupUiBeenDismissed());
  245. // Notification setup is not dismissed initially when access has not been
  246. // granted.
  247. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  248. AccessStatus::kAccessGranted);
  249. EXPECT_FALSE(HasMultideviceFeatureSetupUiBeenDismissed());
  250. // Simlulate dismissal of UI.
  251. DismissSetupRequiredUi();
  252. EXPECT_TRUE(HasMultideviceFeatureSetupUiBeenDismissed());
  253. // Dismissal value is persisted on initialization with access not granted.
  254. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  255. AccessStatus::kAccessGranted);
  256. EXPECT_TRUE(HasMultideviceFeatureSetupUiBeenDismissed());
  257. // Dismissal value is persisted on initialization with access granted.
  258. InitializeAccessStatus(AccessStatus::kAccessGranted,
  259. AccessStatus::kAccessGranted);
  260. EXPECT_TRUE(HasMultideviceFeatureSetupUiBeenDismissed());
  261. }
  262. TEST_F(MultideviceFeatureAccessManagerImplTest, AllAccessInitiallyGranted) {
  263. InitializeAccessStatus(AccessStatus::kAccessGranted,
  264. AccessStatus::kAccessGranted);
  265. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  266. VerifyCameraRollAccessGrantedState(AccessStatus::kAccessGranted);
  267. // Cannot start the notification access setup flow if notification and camera
  268. // roll access have already been granted.
  269. auto operation = StartNotificationSetupOperation();
  270. EXPECT_FALSE(operation);
  271. }
  272. TEST_F(MultideviceFeatureAccessManagerImplTest, OnFeatureStatusChanged) {
  273. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  274. AccessStatus::kAvailableButNotGranted);
  275. VerifyNotificationAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  276. VerifyCameraRollAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  277. // Set initial state to disconnected.
  278. SetFeatureStatus(FeatureStatus::kEnabledButDisconnected);
  279. EXPECT_EQ(0u, GetNumShowNotificationAccessSetupRequestCount());
  280. EXPECT_EQ(NotificationAccessSetupOperation::Status::kConnecting,
  281. GetNotificationAccessSetupOperationStatus());
  282. // Simulate feature status to be enabled and connected. SetupOperation is
  283. // also not in progress, so expect no new requests to be sent.
  284. SetFeatureStatus(FeatureStatus::kEnabledAndConnected);
  285. EXPECT_EQ(0u, GetNumShowNotificationAccessSetupRequestCount());
  286. EXPECT_EQ(NotificationAccessSetupOperation::Status::kConnecting,
  287. GetNotificationAccessSetupOperationStatus());
  288. // Simulate setup operation is in progress. This will trigger a sent
  289. // request.
  290. auto operation = StartNotificationSetupOperation();
  291. EXPECT_TRUE(operation);
  292. EXPECT_EQ(1u, GetNumShowNotificationAccessSetupRequestCount());
  293. EXPECT_EQ(NotificationAccessSetupOperation::Status::
  294. kSentMessageToPhoneAndWaitingForResponse,
  295. GetNotificationAccessSetupOperationStatus());
  296. // Set another feature status, expect status to be updated.
  297. SetFeatureStatus(FeatureStatus::kEnabledButDisconnected);
  298. EXPECT_EQ(1u, GetNumShowNotificationAccessSetupRequestCount());
  299. EXPECT_EQ(NotificationAccessSetupOperation::Status::kConnectionDisconnected,
  300. GetNotificationAccessSetupOperationStatus());
  301. }
  302. TEST_F(MultideviceFeatureAccessManagerImplTest, StartDisconnectedAndNoAccess) {
  303. // Set initial state to disconnected.
  304. SetFeatureStatus(FeatureStatus::kEnabledButDisconnected);
  305. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  306. AccessStatus::kAccessGranted);
  307. VerifyNotificationAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  308. VerifyCameraRollAccessGrantedState(AccessStatus::kAccessGranted);
  309. // Start a setup operation with enabled but disconnected status and access
  310. // not granted.
  311. auto operation = StartNotificationSetupOperation();
  312. EXPECT_TRUE(operation);
  313. EXPECT_EQ(1u, GetNumScheduleConnectionNowCalls());
  314. // Simulate changing states from connecting to connected.
  315. SetFeatureStatus(FeatureStatus::kEnabledAndConnecting);
  316. SetFeatureStatus(FeatureStatus::kEnabledAndConnected);
  317. // Verify that the request message has been sent and our operation status
  318. // is updated.
  319. EXPECT_EQ(1u, GetNumShowNotificationAccessSetupRequestCount());
  320. EXPECT_EQ(NotificationAccessSetupOperation::Status::
  321. kSentMessageToPhoneAndWaitingForResponse,
  322. GetNotificationAccessSetupOperationStatus());
  323. // Simulate getting a response back from the phone.
  324. SetNotificationAccessStatusInternal(AccessStatus::kAccessGranted,
  325. AccessProhibitedReason::kUnknown);
  326. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  327. EXPECT_EQ(NotificationAccessSetupOperation::Status::kCompletedSuccessfully,
  328. GetNotificationAccessSetupOperationStatus());
  329. }
  330. TEST_F(MultideviceFeatureAccessManagerImplTest,
  331. StartDisconnectedAndNoAccess_NotificationAccessIsProhibited) {
  332. // Set initial state to disconnected.
  333. SetFeatureStatus(FeatureStatus::kEnabledButDisconnected);
  334. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  335. AccessStatus::kAvailableButNotGranted);
  336. VerifyNotificationAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  337. VerifyCameraRollAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  338. // Start a setup operation with enabled but disconnected status and access
  339. // not granted.
  340. auto operation = StartNotificationSetupOperation();
  341. EXPECT_TRUE(operation);
  342. EXPECT_EQ(1u, GetNumScheduleConnectionNowCalls());
  343. // Simulate changing states from connecting to connected.
  344. SetFeatureStatus(FeatureStatus::kEnabledAndConnecting);
  345. SetFeatureStatus(FeatureStatus::kEnabledAndConnected);
  346. // Verify that the request message has been sent and our operation status
  347. // is updated.
  348. EXPECT_EQ(1u, GetNumShowNotificationAccessSetupRequestCount());
  349. EXPECT_EQ(NotificationAccessSetupOperation::Status::
  350. kSentMessageToPhoneAndWaitingForResponse,
  351. GetNotificationAccessSetupOperationStatus());
  352. // Simulate getting a response back from the phone.
  353. SetNotificationAccessStatusInternal(
  354. AccessStatus::kProhibited,
  355. AccessProhibitedReason::kDisabledByPhonePolicy);
  356. VerifyNotificationAccessGrantedState(
  357. AccessStatus::kProhibited,
  358. AccessProhibitedReason::kDisabledByPhonePolicy);
  359. EXPECT_EQ(
  360. NotificationAccessSetupOperation::Status::kProhibitedFromProvidingAccess,
  361. GetNotificationAccessSetupOperationStatus());
  362. }
  363. TEST_F(MultideviceFeatureAccessManagerImplTest, StartConnectingAndNoAccess) {
  364. // Set initial state to connecting.
  365. SetFeatureStatus(FeatureStatus::kEnabledAndConnecting);
  366. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  367. AccessStatus::kAvailableButNotGranted);
  368. VerifyNotificationAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  369. VerifyCameraRollAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  370. // Start a setup operation with enabled and connecting status and access
  371. // not granted.
  372. auto operation = StartNotificationSetupOperation();
  373. EXPECT_TRUE(operation);
  374. // Simulate changing states from connecting to connected.
  375. SetFeatureStatus(FeatureStatus::kEnabledAndConnected);
  376. // Verify that the request message has been sent and our operation status
  377. // is updated.
  378. EXPECT_EQ(1u, GetNumShowNotificationAccessSetupRequestCount());
  379. EXPECT_EQ(NotificationAccessSetupOperation::Status::
  380. kSentMessageToPhoneAndWaitingForResponse,
  381. GetNotificationAccessSetupOperationStatus());
  382. // Simulate getting a response back from the phone.
  383. SetNotificationAccessStatusInternal(AccessStatus::kAccessGranted,
  384. AccessProhibitedReason::kUnknown);
  385. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  386. EXPECT_EQ(NotificationAccessSetupOperation::Status::kCompletedSuccessfully,
  387. GetNotificationAccessSetupOperationStatus());
  388. }
  389. TEST_F(MultideviceFeatureAccessManagerImplTest, StartConnectedAndNoAccess) {
  390. // Set initial state to connected.
  391. SetFeatureStatus(FeatureStatus::kEnabledAndConnected);
  392. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  393. AccessStatus::kAvailableButNotGranted);
  394. VerifyNotificationAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  395. VerifyCameraRollAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  396. // Start a setup operation with enabled and connected status and access
  397. // not granted.
  398. auto operation = StartNotificationSetupOperation();
  399. EXPECT_TRUE(operation);
  400. // Verify that the request message has been sent and our operation status
  401. // is updated.
  402. EXPECT_EQ(1u, GetNumShowNotificationAccessSetupRequestCount());
  403. EXPECT_EQ(NotificationAccessSetupOperation::Status::
  404. kSentMessageToPhoneAndWaitingForResponse,
  405. GetNotificationAccessSetupOperationStatus());
  406. // Simulate getting a response back from the phone.
  407. SetNotificationAccessStatusInternal(AccessStatus::kAccessGranted,
  408. AccessProhibitedReason::kUnknown);
  409. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  410. EXPECT_EQ(NotificationAccessSetupOperation::Status::kCompletedSuccessfully,
  411. GetNotificationAccessSetupOperationStatus());
  412. }
  413. TEST_F(MultideviceFeatureAccessManagerImplTest,
  414. SimulateConnectingToDisconnected) {
  415. // Set initial state to connecting.
  416. SetFeatureStatus(FeatureStatus::kEnabledAndConnecting);
  417. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  418. AccessStatus::kAvailableButNotGranted);
  419. VerifyNotificationAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  420. VerifyCameraRollAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  421. auto operation = StartNotificationSetupOperation();
  422. EXPECT_TRUE(operation);
  423. // Simulate a disconnection and expect that status has been updated.
  424. SetFeatureStatus(FeatureStatus::kEnabledButDisconnected);
  425. EXPECT_EQ(NotificationAccessSetupOperation::Status::kTimedOutConnecting,
  426. GetNotificationAccessSetupOperationStatus());
  427. }
  428. TEST_F(MultideviceFeatureAccessManagerImplTest,
  429. SimulateConnectedToDisconnected) {
  430. // Simulate connected state.
  431. SetFeatureStatus(FeatureStatus::kEnabledAndConnected);
  432. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  433. AccessStatus::kAvailableButNotGranted);
  434. VerifyNotificationAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  435. VerifyCameraRollAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  436. auto operation = StartNotificationSetupOperation();
  437. EXPECT_TRUE(operation);
  438. EXPECT_EQ(1u, GetNumShowNotificationAccessSetupRequestCount());
  439. // Simulate a disconnection, expect status update.
  440. SetFeatureStatus(FeatureStatus::kEnabledButDisconnected);
  441. EXPECT_EQ(NotificationAccessSetupOperation::Status::kConnectionDisconnected,
  442. GetNotificationAccessSetupOperationStatus());
  443. }
  444. TEST_F(MultideviceFeatureAccessManagerImplTest, SimulateConnectedToDisabled) {
  445. // Simulate connected state.
  446. SetFeatureStatus(FeatureStatus::kEnabledAndConnected);
  447. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  448. AccessStatus::kAvailableButNotGranted);
  449. VerifyNotificationAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  450. VerifyCameraRollAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  451. auto operation = StartNotificationSetupOperation();
  452. EXPECT_TRUE(operation);
  453. EXPECT_EQ(1u, GetNumShowNotificationAccessSetupRequestCount());
  454. // Simulate disabling the feature, expect status update.
  455. SetFeatureStatus(FeatureStatus::kDisabled);
  456. EXPECT_EQ(NotificationAccessSetupOperation::Status::kConnectionDisconnected,
  457. GetNotificationAccessSetupOperationStatus());
  458. }
  459. TEST_F(MultideviceFeatureAccessManagerImplTest,
  460. FlipNotificationAccessGrantedToNotGranted) {
  461. InitializeAccessStatus(AccessStatus::kAccessGranted,
  462. AccessStatus::kAccessGranted);
  463. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  464. VerifyCameraRollAccessGrantedState(AccessStatus::kAccessGranted);
  465. // Simulate flipping notification access state to no granted.
  466. SetNotificationAccessStatusInternal(AccessStatus::kAvailableButNotGranted,
  467. AccessProhibitedReason::kUnknown);
  468. VerifyNotificationAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  469. EXPECT_EQ(1u, GetNumObserverCalls());
  470. }
  471. TEST_F(MultideviceFeatureAccessManagerImplTest,
  472. FlipNotificationAccessGrantedToProhibited) {
  473. InitializeAccessStatus(AccessStatus::kAccessGranted,
  474. AccessStatus::kAccessGranted);
  475. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  476. VerifyCameraRollAccessGrantedState(AccessStatus::kAccessGranted);
  477. // Simulate flipping notification access state to prohibited.
  478. SetNotificationAccessStatusInternal(
  479. AccessStatus::kProhibited,
  480. AccessProhibitedReason::kDisabledByPhonePolicy);
  481. VerifyNotificationAccessGrantedState(
  482. AccessStatus::kProhibited,
  483. AccessProhibitedReason::kDisabledByPhonePolicy);
  484. EXPECT_EQ(1u, GetNumObserverCalls());
  485. }
  486. TEST_F(MultideviceFeatureAccessManagerImplTest,
  487. FlipCameraRollAccessGrantedToNotGranted) {
  488. InitializeAccessStatus(AccessStatus::kAccessGranted,
  489. AccessStatus::kAccessGranted);
  490. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  491. VerifyCameraRollAccessGrantedState(AccessStatus::kAccessGranted);
  492. // Simulate flipping camera roll access state to no granted.
  493. SetCameraRollAccessStatusInternal(AccessStatus::kAvailableButNotGranted);
  494. VerifyCameraRollAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  495. EXPECT_EQ(1u, GetNumObserverCalls());
  496. }
  497. TEST_F(MultideviceFeatureAccessManagerImplTest, AccessNotChanged) {
  498. InitializeAccessStatus(AccessStatus::kAccessGranted,
  499. AccessStatus::kAccessGranted);
  500. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  501. VerifyCameraRollAccessGrantedState(AccessStatus::kAccessGranted);
  502. // If the access state is unchanged, we do not expect any notifications.
  503. SetNotificationAccessStatusInternal(AccessStatus::kAccessGranted,
  504. AccessProhibitedReason::kUnknown);
  505. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  506. EXPECT_EQ(0u, GetNumObserverCalls());
  507. }
  508. TEST_F(MultideviceFeatureAccessManagerImplTest,
  509. NeedsOneTimeNotificationAccessUpdate_AccessGranted) {
  510. InitializeAccessStatus(AccessStatus::kAccessGranted,
  511. AccessStatus::kAccessGranted);
  512. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  513. VerifyCameraRollAccessGrantedState(AccessStatus::kAccessGranted);
  514. // Send a one-time signal to observers if access is granted. See
  515. // http://crbug.com/1215559.
  516. SetNeedsOneTimeNotificationAccessUpdate(/*needs_update=*/true);
  517. SetNotificationAccessStatusInternal(AccessStatus::kAccessGranted,
  518. AccessProhibitedReason::kUnknown);
  519. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  520. EXPECT_EQ(1u, GetNumObserverCalls());
  521. // Observers should be notified only once ever.
  522. SetNotificationAccessStatusInternal(AccessStatus::kAccessGranted,
  523. AccessProhibitedReason::kUnknown);
  524. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  525. EXPECT_EQ(1u, GetNumObserverCalls());
  526. }
  527. TEST_F(MultideviceFeatureAccessManagerImplTest,
  528. NeedsOneTimeNotificationAccessUpdate_Prohibited) {
  529. InitializeAccessStatus(AccessStatus::kProhibited,
  530. AccessStatus::kAccessGranted,
  531. AccessProhibitedReason::kDisabledByPhonePolicy);
  532. VerifyNotificationAccessGrantedState(
  533. AccessStatus::kProhibited,
  534. AccessProhibitedReason::kDisabledByPhonePolicy);
  535. VerifyCameraRollAccessGrantedState(AccessStatus::kAccessGranted);
  536. // Only send the one-time signal to observers if access is granted. See
  537. // http://crbug.com/1215559.
  538. SetNeedsOneTimeNotificationAccessUpdate(/*needs_update=*/true);
  539. SetNotificationAccessStatusInternal(
  540. AccessStatus::kProhibited,
  541. AccessProhibitedReason::kDisabledByPhonePolicy);
  542. VerifyNotificationAccessGrantedState(
  543. AccessStatus::kProhibited,
  544. AccessProhibitedReason::kDisabledByPhonePolicy);
  545. EXPECT_EQ(0u, GetNumObserverCalls());
  546. }
  547. TEST_F(MultideviceFeatureAccessManagerImplTest,
  548. NotificationAccessProhibitedReason_FromProhibited) {
  549. InitializeAccessStatus(AccessStatus::kProhibited,
  550. AccessStatus::kAccessGranted);
  551. VerifyNotificationAccessGrantedState(AccessStatus::kProhibited);
  552. // Simulates an initial update after the pref is first added
  553. SetNotificationAccessStatusInternal(AccessStatus::kProhibited,
  554. AccessProhibitedReason::kWorkProfile);
  555. VerifyNotificationAccessGrantedState(AccessStatus::kProhibited,
  556. AccessProhibitedReason::kWorkProfile);
  557. EXPECT_EQ(1u, GetNumObserverCalls());
  558. // No update or observer notification should occur with no change
  559. SetNotificationAccessStatusInternal(AccessStatus::kProhibited,
  560. AccessProhibitedReason::kWorkProfile);
  561. VerifyNotificationAccessGrantedState(AccessStatus::kProhibited,
  562. AccessProhibitedReason::kWorkProfile);
  563. EXPECT_EQ(1u, GetNumObserverCalls());
  564. // This can happen if a user updates from Android <N to >=N
  565. SetNotificationAccessStatusInternal(
  566. AccessStatus::kProhibited,
  567. AccessProhibitedReason::kDisabledByPhonePolicy);
  568. VerifyNotificationAccessGrantedState(
  569. AccessStatus::kProhibited,
  570. AccessProhibitedReason::kDisabledByPhonePolicy);
  571. EXPECT_EQ(2u, GetNumObserverCalls());
  572. }
  573. TEST_F(MultideviceFeatureAccessManagerImplTest,
  574. NotificationAccessProhibitedReason_FromGranted) {
  575. InitializeAccessStatus(AccessStatus::kAccessGranted,
  576. AccessStatus::kAccessGranted);
  577. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  578. SetNotificationAccessStatusInternal(
  579. AccessStatus::kProhibited,
  580. AccessProhibitedReason::kDisabledByPhonePolicy);
  581. VerifyNotificationAccessGrantedState(
  582. AccessStatus::kProhibited,
  583. AccessProhibitedReason::kDisabledByPhonePolicy);
  584. EXPECT_EQ(1u, GetNumObserverCalls());
  585. }
  586. TEST_F(MultideviceFeatureAccessManagerImplTest, AppsAccessChanged) {
  587. InitializeAccessStatus(
  588. MultideviceFeatureAccessManager::AccessStatus::kAccessGranted,
  589. MultideviceFeatureAccessManager::AccessStatus::kAccessGranted);
  590. InitializeAppsAccessStatus(
  591. MultideviceFeatureAccessManager::AccessStatus::kAccessGranted);
  592. VerifyAppsAccessGrantedState(
  593. MultideviceFeatureAccessManager::AccessStatus::kAccessGranted);
  594. EXPECT_EQ(1u, GetNumObserverCalls());
  595. InitializeAppsAccessStatus(
  596. MultideviceFeatureAccessManager::AccessStatus::kAvailableButNotGranted);
  597. VerifyAppsAccessGrantedState(
  598. MultideviceFeatureAccessManager::AccessStatus::kAvailableButNotGranted);
  599. EXPECT_EQ(2u, GetNumObserverCalls());
  600. InitializeAppsAccessStatus(
  601. MultideviceFeatureAccessManager::AccessStatus::kProhibited);
  602. VerifyAppsAccessGrantedState(
  603. MultideviceFeatureAccessManager::AccessStatus::kProhibited);
  604. EXPECT_EQ(3u, GetNumObserverCalls());
  605. }
  606. TEST_F(MultideviceFeatureAccessManagerImplTest,
  607. FlipFeatureSetupRequestSupportedOn) {
  608. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  609. AccessStatus::kAvailableButNotGranted);
  610. VerifyFeatureSetupRequestSupported(false);
  611. SetFeatureSetupRequestSupportedInternal(true);
  612. VerifyFeatureSetupRequestSupported(true);
  613. EXPECT_EQ(1u, GetNumObserverCalls());
  614. }
  615. TEST_F(MultideviceFeatureAccessManagerImplTest,
  616. CombinedFeatureSetup_FeatureSetupRequestNotSupported) {
  617. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  618. AccessStatus::kAvailableButNotGranted);
  619. VerifyNotificationAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  620. VerifyCameraRollAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  621. VerifyFeatureSetupRequestSupported(false);
  622. // Cannot start the combined access setup flow if FeatureSetupRequest is not
  623. // supported.
  624. auto operation =
  625. StartCombinedSetupOperation(/*camera_roll=*/true, /*notifications=*/true);
  626. EXPECT_FALSE(operation);
  627. }
  628. TEST_F(MultideviceFeatureAccessManagerImplTest,
  629. CombinedFeatureSetup_AllFeaturesGranted_AllFeaturesRequested) {
  630. InitializeAccessStatus(AccessStatus::kAccessGranted,
  631. AccessStatus::kAccessGranted,
  632. AccessProhibitedReason::kUnknown,
  633. /*feature_setup_request_supported=*/true);
  634. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  635. VerifyCameraRollAccessGrantedState(AccessStatus::kAccessGranted);
  636. VerifyFeatureSetupRequestSupported(true);
  637. // Cannot start the combined access setup flow if requested feature access
  638. // has already been granted.
  639. auto operation =
  640. StartCombinedSetupOperation(/*camera_roll=*/true, /*notifications=*/true);
  641. EXPECT_FALSE(operation);
  642. }
  643. TEST_F(MultideviceFeatureAccessManagerImplTest,
  644. CombinedFeatureSetup_CameraRollGranted_AllFeaturesRequested) {
  645. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  646. AccessStatus::kAccessGranted,
  647. AccessProhibitedReason::kUnknown,
  648. /*feature_setup_request_supported=*/true);
  649. VerifyNotificationAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  650. VerifyCameraRollAccessGrantedState(AccessStatus::kAccessGranted);
  651. VerifyFeatureSetupRequestSupported(true);
  652. // Cannot start the combined access setup flow if requested feature access
  653. // has already been granted.
  654. auto operation =
  655. StartCombinedSetupOperation(/*camera_roll=*/true, /*notifications=*/true);
  656. EXPECT_FALSE(operation);
  657. }
  658. TEST_F(MultideviceFeatureAccessManagerImplTest,
  659. CombinedFeatureSetup_NotificationsGranted_AllFeaturesRequested) {
  660. InitializeAccessStatus(AccessStatus::kAccessGranted,
  661. AccessStatus::kAvailableButNotGranted,
  662. AccessProhibitedReason::kUnknown,
  663. /*feature_setup_request_supported=*/true);
  664. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  665. VerifyCameraRollAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  666. VerifyFeatureSetupRequestSupported(true);
  667. // Cannot start the combined access setup flow if requested feature access
  668. // has already been granted.
  669. auto operation =
  670. StartCombinedSetupOperation(/*camera_roll=*/true, /*notifications=*/true);
  671. EXPECT_FALSE(operation);
  672. }
  673. TEST_F(MultideviceFeatureAccessManagerImplTest,
  674. CombinedFeatureSetup_CameraRollGranted_NotificationsRequested) {
  675. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  676. AccessStatus::kAccessGranted,
  677. AccessProhibitedReason::kUnknown,
  678. /*feature_setup_request_supported=*/true);
  679. VerifyNotificationAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  680. VerifyCameraRollAccessGrantedState(AccessStatus::kAccessGranted);
  681. VerifyFeatureSetupRequestSupported(true);
  682. // Can start the combined access setup flow if requested feature access is not
  683. // granted, even if other feature is granted.
  684. auto operation = StartCombinedSetupOperation(/*camera_roll=*/false,
  685. /*notifications=*/true);
  686. EXPECT_TRUE(operation);
  687. }
  688. TEST_F(MultideviceFeatureAccessManagerImplTest,
  689. CombinedFeatureSetup_NotificationsGranted_CameraRollRequested) {
  690. InitializeAccessStatus(AccessStatus::kAccessGranted,
  691. AccessStatus::kAvailableButNotGranted,
  692. AccessProhibitedReason::kUnknown,
  693. /*feature_setup_request_supported=*/true);
  694. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  695. VerifyCameraRollAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  696. VerifyFeatureSetupRequestSupported(true);
  697. // Can start the combined access setup flow if requested feature access is not
  698. // granted, even if other feature is granted.
  699. auto operation = StartCombinedSetupOperation(/*camera_roll=*/true,
  700. /*notifications=*/false);
  701. EXPECT_TRUE(operation);
  702. }
  703. TEST_F(MultideviceFeatureAccessManagerImplTest,
  704. CombinedFeatureSetup_FullSetupFromDisconnected) {
  705. // Set initial state to disconnected.
  706. SetFeatureStatus(FeatureStatus::kEnabledButDisconnected);
  707. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  708. AccessStatus::kAvailableButNotGranted,
  709. AccessProhibitedReason::kUnknown,
  710. /*feature_setup_request_supported=*/true);
  711. VerifyNotificationAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  712. VerifyCameraRollAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  713. VerifyFeatureSetupRequestSupported(true);
  714. // Start combined setup operation
  715. auto operation = StartCombinedSetupOperation(/*camera_roll=*/true,
  716. /*notifications=*/true);
  717. EXPECT_TRUE(operation);
  718. EXPECT_EQ(0u, GetCombinedAccessSetupRequestCallCount());
  719. EXPECT_EQ(CombinedAccessSetupOperation::Status::kConnecting,
  720. GetCombinedAccessSetupOperationStatus());
  721. EXPECT_EQ(1u, GetNumScheduleConnectionNowCalls());
  722. // Simulate changing state to connecting.
  723. SetFeatureStatus(FeatureStatus::kEnabledAndConnecting);
  724. EXPECT_EQ(0u, GetCombinedAccessSetupRequestCallCount());
  725. EXPECT_EQ(CombinedAccessSetupOperation::Status::kConnecting,
  726. GetCombinedAccessSetupOperationStatus());
  727. EXPECT_EQ(1u, GetNumScheduleConnectionNowCalls());
  728. // Simulate changing state to connected.
  729. SetFeatureStatus(FeatureStatus::kEnabledAndConnected);
  730. EXPECT_EQ(1u, GetCombinedAccessSetupRequestCallCount());
  731. EXPECT_EQ(CombinedAccessSetupOperation::Status::
  732. kSentMessageToPhoneAndWaitingForResponse,
  733. GetCombinedAccessSetupOperationStatus());
  734. // Simulate Camera Roll being granted on phone.
  735. SetCameraRollAccessStatusInternal(AccessStatus::kAccessGranted);
  736. VerifyCameraRollAccessGrantedState(AccessStatus::kAccessGranted);
  737. EXPECT_EQ(CombinedAccessSetupOperation::Status::
  738. kSentMessageToPhoneAndWaitingForResponse,
  739. GetCombinedAccessSetupOperationStatus());
  740. // Simulate Notifications being granted on phone.
  741. SetNotificationAccessStatusInternal(AccessStatus::kAccessGranted,
  742. AccessProhibitedReason::kUnknown);
  743. VerifyNotificationAccessGrantedState(AccessStatus::kAccessGranted);
  744. EXPECT_EQ(CombinedAccessSetupOperation::Status::kCompletedSuccessfully,
  745. GetCombinedAccessSetupOperationStatus());
  746. }
  747. TEST_F(MultideviceFeatureAccessManagerImplTest,
  748. CombinedFeatureSetup_SimulateTimeout) {
  749. // Set initial state to connecting.
  750. SetFeatureStatus(FeatureStatus::kEnabledAndConnecting);
  751. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  752. AccessStatus::kAvailableButNotGranted,
  753. AccessProhibitedReason::kUnknown,
  754. /*feature_setup_request_supported=*/true);
  755. VerifyNotificationAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  756. VerifyCameraRollAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  757. VerifyFeatureSetupRequestSupported(true);
  758. // Start combined setup operation
  759. auto operation = StartCombinedSetupOperation(/*camera_roll=*/true,
  760. /*notifications=*/true);
  761. EXPECT_TRUE(operation);
  762. // Simulate a disconnection and expect that status has been updated.
  763. SetFeatureStatus(FeatureStatus::kEnabledButDisconnected);
  764. EXPECT_EQ(CombinedAccessSetupOperation::Status::kTimedOutConnecting,
  765. GetCombinedAccessSetupOperationStatus());
  766. }
  767. TEST_F(MultideviceFeatureAccessManagerImplTest,
  768. CombinedFeatureSetup_SimulateDisconnect) {
  769. // Set initial state to connected.
  770. SetFeatureStatus(FeatureStatus::kEnabledAndConnected);
  771. InitializeAccessStatus(AccessStatus::kAvailableButNotGranted,
  772. AccessStatus::kAvailableButNotGranted,
  773. AccessProhibitedReason::kUnknown,
  774. /*feature_setup_request_supported=*/true);
  775. VerifyNotificationAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  776. VerifyCameraRollAccessGrantedState(AccessStatus::kAvailableButNotGranted);
  777. VerifyFeatureSetupRequestSupported(true);
  778. // Start combined setup operation
  779. auto operation = StartCombinedSetupOperation(/*camera_roll=*/true,
  780. /*notifications=*/true);
  781. EXPECT_TRUE(operation);
  782. // Simulate a disconnection and expect that status has been updated.
  783. SetFeatureStatus(FeatureStatus::kEnabledButDisconnected);
  784. EXPECT_EQ(CombinedAccessSetupOperation::Status::kConnectionDisconnected,
  785. GetCombinedAccessSetupOperationStatus());
  786. }
  787. } // namespace phonehub
  788. } // namespace ash