eche_recent_app_click_handler_unittest.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. // Copyright 2021 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/webui/eche_app_ui/eche_recent_app_click_handler.h"
  5. #include <string>
  6. #include "ash/components/phonehub/fake_phone_hub_manager.h"
  7. #include "ash/constants/ash_features.h"
  8. #include "ash/webui/eche_app_ui/eche_stream_status_change_handler.h"
  9. #include "ash/webui/eche_app_ui/fake_feature_status_provider.h"
  10. #include "ash/webui/eche_app_ui/fake_launch_app_helper.h"
  11. #include "ash/webui/eche_app_ui/launch_app_helper.h"
  12. #include "base/bind.h"
  13. #include "base/test/scoped_feature_list.h"
  14. #include "testing/gtest/include/gtest/gtest.h"
  15. #include "third_party/abseil-cpp/absl/types/optional.h"
  16. #include "ui/base/resource/resource_bundle.h"
  17. #include "ui/gfx/image/image.h"
  18. namespace ash {
  19. namespace eche_app {
  20. class EcheRecentAppClickHandlerTest : public testing::Test {
  21. protected:
  22. EcheRecentAppClickHandlerTest() = default;
  23. EcheRecentAppClickHandlerTest(const EcheRecentAppClickHandlerTest&) = delete;
  24. EcheRecentAppClickHandlerTest& operator=(
  25. const EcheRecentAppClickHandlerTest&) = delete;
  26. ~EcheRecentAppClickHandlerTest() override = default;
  27. // testing::Test:
  28. void SetUp() override {
  29. fake_phone_hub_manager_.fake_feature_status_provider()->SetStatus(
  30. phonehub::FeatureStatus::kEnabledAndConnected);
  31. fake_feature_status_provider_.SetStatus(FeatureStatus::kIneligible);
  32. scoped_feature_list_.InitWithFeatures(
  33. /*enabled_features=*/{features::kEcheSWA},
  34. /*disabled_features=*/{});
  35. launch_app_helper_ = std::make_unique<FakeLaunchAppHelper>(
  36. &fake_phone_hub_manager_,
  37. base::BindRepeating(
  38. &EcheRecentAppClickHandlerTest::FakeLaunchEcheAppFunction,
  39. base::Unretained(this)),
  40. base::BindRepeating(
  41. &EcheRecentAppClickHandlerTest::FakeLaunchNotificationFunction,
  42. base::Unretained(this)),
  43. base::BindRepeating(
  44. &EcheRecentAppClickHandlerTest::FakeCloseNotificationFunction,
  45. base::Unretained(this)));
  46. stream_status_change_handler_ =
  47. std::make_unique<EcheStreamStatusChangeHandler>();
  48. handler_ = std::make_unique<EcheRecentAppClickHandler>(
  49. &fake_phone_hub_manager_, &fake_feature_status_provider_,
  50. launch_app_helper_.get(), stream_status_change_handler_.get());
  51. }
  52. void TearDown() override {
  53. launch_app_helper_.reset();
  54. handler_.reset();
  55. stream_status_change_handler_.reset();
  56. }
  57. void FakeLaunchEcheAppFunction(const absl::optional<int64_t>& notification_id,
  58. const std::string& package_name,
  59. const std::u16string& visible_name,
  60. const absl::optional<int64_t>& user_id,
  61. const gfx::Image& icon) {
  62. package_name_ = package_name;
  63. visible_name_ = visible_name;
  64. user_id_ = user_id.value();
  65. }
  66. void FakeLaunchNotificationFunction(
  67. const absl::optional<std::u16string>& title,
  68. const absl::optional<std::u16string>& message,
  69. std::unique_ptr<LaunchAppHelper::NotificationInfo> info) {
  70. num_notifications_shown_++;
  71. }
  72. void FakeCloseNotificationFunction(const std::string& notification_id) {
  73. // Do nothing.
  74. }
  75. void SetStatus(FeatureStatus status) {
  76. fake_feature_status_provider_.SetStatus(status);
  77. }
  78. size_t GetNumberOfRecentAppsInteractionHandlers() {
  79. return fake_phone_hub_manager_.fake_recent_apps_interaction_handler()
  80. ->recent_app_click_observer_count();
  81. }
  82. void RecentAppClicked(
  83. const phonehub::Notification::AppMetadata& app_metadata) {
  84. handler_->OnRecentAppClicked(app_metadata);
  85. }
  86. void HandleNotificationClick(
  87. int64_t notification_id,
  88. const phonehub::Notification::AppMetadata& app_metadata) {
  89. handler_->HandleNotificationClick(notification_id, app_metadata);
  90. }
  91. void StreamStatusChanged(mojom::StreamStatus status) {
  92. handler_->OnStreamStatusChanged(status);
  93. }
  94. std::vector<phonehub::Notification::AppMetadata>
  95. FetchRecentAppMetadataList() {
  96. return fake_phone_hub_manager_.fake_recent_apps_interaction_handler()
  97. ->FetchRecentAppMetadataList();
  98. }
  99. void SetAppLaunchProhibitedReason(
  100. LaunchAppHelper::AppLaunchProhibitedReason reason) {
  101. launch_app_helper_->SetAppLaunchProhibitedReason(reason);
  102. }
  103. void reset() { num_notifications_shown_ = 0; }
  104. const std::string& get_package_name() { return package_name_; }
  105. const std::u16string& get_visible_name() { return visible_name_; }
  106. int64_t get_user_id() { return user_id_; }
  107. size_t num_notifications_shown() { return num_notifications_shown_; }
  108. private:
  109. phonehub::FakePhoneHubManager fake_phone_hub_manager_;
  110. base::test::ScopedFeatureList scoped_feature_list_;
  111. FakeFeatureStatusProvider fake_feature_status_provider_;
  112. std::unique_ptr<FakeLaunchAppHelper> launch_app_helper_;
  113. std::unique_ptr<EcheStreamStatusChangeHandler> stream_status_change_handler_;
  114. std::unique_ptr<EcheRecentAppClickHandler> handler_;
  115. std::string package_name_;
  116. std::u16string visible_name_;
  117. int64_t user_id_;
  118. size_t num_notifications_shown_ = 0;
  119. };
  120. TEST_F(EcheRecentAppClickHandlerTest, StatusChangeTransitions) {
  121. EXPECT_EQ(0u, GetNumberOfRecentAppsInteractionHandlers());
  122. SetStatus(FeatureStatus::kDisabled);
  123. EXPECT_EQ(0u, GetNumberOfRecentAppsInteractionHandlers());
  124. SetStatus(FeatureStatus::kDisconnected);
  125. EXPECT_EQ(1u, GetNumberOfRecentAppsInteractionHandlers());
  126. SetStatus(FeatureStatus::kConnecting);
  127. EXPECT_EQ(1u, GetNumberOfRecentAppsInteractionHandlers());
  128. SetStatus(FeatureStatus::kConnected);
  129. EXPECT_EQ(1u, GetNumberOfRecentAppsInteractionHandlers());
  130. SetStatus(FeatureStatus::kIneligible);
  131. EXPECT_EQ(0u, GetNumberOfRecentAppsInteractionHandlers());
  132. SetStatus(FeatureStatus::kDisconnected);
  133. EXPECT_EQ(1u, GetNumberOfRecentAppsInteractionHandlers());
  134. SetStatus(FeatureStatus::kDisabled);
  135. EXPECT_EQ(0u, GetNumberOfRecentAppsInteractionHandlers());
  136. SetStatus(FeatureStatus::kDisconnected);
  137. EXPECT_EQ(1u, GetNumberOfRecentAppsInteractionHandlers());
  138. SetStatus(FeatureStatus::kDependentFeature);
  139. EXPECT_EQ(0u, GetNumberOfRecentAppsInteractionHandlers());
  140. SetStatus(FeatureStatus::kDisconnected);
  141. EXPECT_EQ(1u, GetNumberOfRecentAppsInteractionHandlers());
  142. SetStatus(FeatureStatus::kDependentFeaturePending);
  143. EXPECT_EQ(0u, GetNumberOfRecentAppsInteractionHandlers());
  144. }
  145. TEST_F(EcheRecentAppClickHandlerTest, LaunchEcheAppFunction) {
  146. const int64_t user_id = 1;
  147. const char16_t app_visible_name[] = u"Fake App";
  148. const char package_name[] = "com.fakeapp";
  149. auto fake_app_metadata = phonehub::Notification::AppMetadata(
  150. app_visible_name, package_name, gfx::Image(),
  151. /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id);
  152. std::vector<phonehub::Notification::AppMetadata> app_metadata =
  153. FetchRecentAppMetadataList();
  154. EXPECT_EQ(app_metadata.size(), 0u);
  155. RecentAppClicked(fake_app_metadata);
  156. // Call one more time to make sure deduplication works.
  157. RecentAppClicked(fake_app_metadata);
  158. EXPECT_EQ(fake_app_metadata.package_name, get_package_name());
  159. EXPECT_EQ(fake_app_metadata.visible_app_name, get_visible_name());
  160. EXPECT_EQ(fake_app_metadata.user_id, get_user_id());
  161. // Streaming will bring the app to the list of recent apps.
  162. StreamStatusChanged(eche_app::mojom::StreamStatus::kStreamStatusStarted);
  163. app_metadata = FetchRecentAppMetadataList();
  164. EXPECT_EQ(fake_app_metadata.visible_app_name,
  165. app_metadata[0].visible_app_name);
  166. EXPECT_EQ(fake_app_metadata.package_name, app_metadata[0].package_name);
  167. EXPECT_EQ(fake_app_metadata.user_id, app_metadata[0].user_id);
  168. }
  169. TEST_F(EcheRecentAppClickHandlerTest, HandleNotificationClick) {
  170. const int64_t notification_id = 1;
  171. const int64_t user_id = 1;
  172. const char16_t app_visible_name[] = u"Fake App";
  173. const char package_name[] = "com.fakeapp";
  174. auto fake_app_metadata = phonehub::Notification::AppMetadata(
  175. app_visible_name, package_name, gfx::Image(),
  176. /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id);
  177. // Keep notification's metadata in handler if the stream has not started yet.
  178. HandleNotificationClick(notification_id, fake_app_metadata);
  179. std::vector<phonehub::Notification::AppMetadata> app_metadata =
  180. FetchRecentAppMetadataList();
  181. EXPECT_EQ(app_metadata.size(), 0u);
  182. // Update notification's metadata to recents list when the stream is started.
  183. StreamStatusChanged(eche_app::mojom::StreamStatus::kStreamStatusStarted);
  184. app_metadata = FetchRecentAppMetadataList();
  185. EXPECT_EQ(fake_app_metadata.visible_app_name,
  186. app_metadata[0].visible_app_name);
  187. EXPECT_EQ(fake_app_metadata.package_name, app_metadata[0].package_name);
  188. EXPECT_EQ(fake_app_metadata.user_id, app_metadata[0].user_id);
  189. }
  190. TEST_F(EcheRecentAppClickHandlerTest,
  191. HandleNotificationClickWhenStreamIsStarted) {
  192. const int64_t notification_id = 1;
  193. const int64_t user_id = 1;
  194. const char16_t app_visible_name[] = u"Fake App";
  195. const char package_name[] = "com.fakeapp";
  196. auto fake_app_metadata = phonehub::Notification::AppMetadata(
  197. app_visible_name, package_name, gfx::Image(),
  198. /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id);
  199. // Update notification's metadata to recents list directly when the stream is
  200. // started.
  201. StreamStatusChanged(eche_app::mojom::StreamStatus::kStreamStatusStarted);
  202. HandleNotificationClick(notification_id, fake_app_metadata);
  203. std::vector<phonehub::Notification::AppMetadata> app_metadata =
  204. FetchRecentAppMetadataList();
  205. EXPECT_EQ(fake_app_metadata.visible_app_name,
  206. app_metadata[0].visible_app_name);
  207. EXPECT_EQ(fake_app_metadata.package_name, app_metadata[0].package_name);
  208. EXPECT_EQ(fake_app_metadata.user_id, app_metadata[0].user_id);
  209. }
  210. TEST_F(EcheRecentAppClickHandlerTest,
  211. HandleRecentAppClickWithProhibitedReason) {
  212. const int64_t user_id = 1;
  213. const char16_t app_visible_name[] = u"Fake App";
  214. const char package_name[] = "com.fakeapp";
  215. auto fake_app_metadata = phonehub::Notification::AppMetadata(
  216. app_visible_name, package_name, gfx::Image(),
  217. /*icon_color=*/absl::nullopt, /*icon_is_monochrome=*/true, user_id);
  218. SetAppLaunchProhibitedReason(
  219. LaunchAppHelper::AppLaunchProhibitedReason::kDisabledByScreenLock);
  220. RecentAppClicked(fake_app_metadata);
  221. EXPECT_EQ(num_notifications_shown(), 1u);
  222. }
  223. } // namespace eche_app
  224. } // namespace ash