snooping_protection_notification_blocker_unittest.cc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  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/system/human_presence/snooping_protection_notification_blocker.h"
  5. #include <memory>
  6. #include <string>
  7. #include "ash/constants/ash_features.h"
  8. #include "ash/constants/ash_pref_names.h"
  9. #include "ash/constants/ash_switches.h"
  10. #include "ash/constants/notifier_catalogs.h"
  11. #include "ash/public/cpp/test/shell_test_api.h"
  12. #include "ash/public/cpp/test/test_system_tray_client.h"
  13. #include "ash/session/session_controller_impl.h"
  14. #include "ash/session/test_session_controller_client.h"
  15. #include "ash/shell.h"
  16. #include "ash/system/human_presence/snooping_protection_controller.h"
  17. #include "ash/system/human_presence/snooping_protection_notification_blocker_internal.h"
  18. #include "ash/system/message_center/message_center_controller.h"
  19. #include "ash/system/message_center/unified_message_center_bubble.h"
  20. #include "ash/system/network/sms_observer.h"
  21. #include "ash/system/unified/unified_system_tray.h"
  22. #include "ash/system/unified/unified_system_tray_bubble.h"
  23. #include "ash/test/ash_test_base.h"
  24. #include "base/memory/scoped_refptr.h"
  25. #include "base/no_destructor.h"
  26. #include "base/strings/utf_string_conversions.h"
  27. #include "base/test/scoped_command_line.h"
  28. #include "base/test/scoped_feature_list.h"
  29. #include "chromeos/ash/components/dbus/hps/hps_service.pb.h"
  30. #include "chromeos/ash/components/dbus/human_presence/fake_human_presence_dbus_client.h"
  31. #include "chromeos/ash/components/dbus/human_presence/human_presence_dbus_client.h"
  32. #include "components/account_id/account_id.h"
  33. #include "components/services/app_service/public/cpp/app_types.h"
  34. #include "components/services/app_service/public/cpp/app_update.h"
  35. #include "ui/base/l10n/l10n_util.h"
  36. #include "ui/gfx/image/image.h"
  37. #include "ui/message_center/message_center.h"
  38. #include "ui/message_center/public/cpp/notification.h"
  39. #include "ui/message_center/public/cpp/notification_types.h"
  40. #include "ui/message_center/public/cpp/notifier_id.h"
  41. #include "url/gurl.h"
  42. namespace ash {
  43. namespace {
  44. // Enables or disables the user pref for the entire feature.
  45. void SetSnoopingPref(bool enabled) {
  46. Shell::Get()->session_controller()->GetActivePrefService()->SetBoolean(
  47. prefs::kSnoopingProtectionEnabled, enabled);
  48. base::RunLoop().RunUntilIdle();
  49. }
  50. // Enables or disables the user pref for notification blocking.
  51. void SetBlockerPref(bool enabled) {
  52. Shell::Get()->session_controller()->GetActivePrefService()->SetBoolean(
  53. prefs::kSnoopingProtectionNotificationSuppressionEnabled, enabled);
  54. base::RunLoop().RunUntilIdle();
  55. }
  56. // Add a notification to the message center. An empty notifier title creates a
  57. // system notification.
  58. void AddNotification(const std::string& notification_id,
  59. const std::u16string& notifier_title) {
  60. const message_center::NotifierId notifier_id =
  61. notifier_title.empty()
  62. ? message_center::NotifierId(
  63. message_center::NotifierType::SYSTEM_COMPONENT, "system",
  64. NotificationCatalogName::kHPSNotify)
  65. : message_center::NotifierId(/*url=*/GURL(), notifier_title);
  66. message_center::MessageCenter::Get()->AddNotification(
  67. std::make_unique<message_center::Notification>(
  68. message_center::NOTIFICATION_TYPE_SIMPLE, notification_id,
  69. u"test-title", u"test-message", /*icon=*/ui::ImageModel(),
  70. /*display_source=*/std::u16string(), /*origin_url=*/GURL(),
  71. notifier_id, message_center::RichNotificationData(),
  72. base::MakeRefCounted<message_center::NotificationDelegate>()));
  73. }
  74. // Removes the notification with the given ID.
  75. void RemoveNotification(const std::string& notification_id) {
  76. message_center::MessageCenter::Get()->RemoveNotification(notification_id,
  77. /*by_user=*/true);
  78. }
  79. // Returns the number of popup notifications that are currently visible in the
  80. // message center.
  81. size_t VisiblePopupCount() {
  82. return message_center::MessageCenter::Get()->GetPopupNotifications().size();
  83. }
  84. // Returns the number of (popup or non-popup) notifications that are currently
  85. // visible in the message center queue.
  86. size_t VisibleNotificationCount() {
  87. return message_center::MessageCenter::Get()->GetVisibleNotifications().size();
  88. }
  89. // Returns true if the HPS notify informational popup is popped-up.
  90. bool InfoPopupVisible() {
  91. return message_center::MessageCenter::Get()->FindPopupNotificationById(
  92. SnoopingProtectionNotificationBlocker::kInfoNotificationId) !=
  93. nullptr;
  94. }
  95. // Returns the index at which the given substring appears in the informational
  96. // popup's message, or npos otherwise.
  97. size_t PositionInInfoPopupMessage(const std::u16string& substr) {
  98. const message_center::Notification* notification =
  99. message_center::MessageCenter::Get()->FindPopupNotificationById(
  100. SnoopingProtectionNotificationBlocker::kInfoNotificationId);
  101. return notification ? notification->message().find(substr)
  102. : std::u16string::npos;
  103. }
  104. // A blocker that blocks only a popup with the given ID.
  105. class IdPopupBlocker : public message_center::NotificationBlocker {
  106. public:
  107. IdPopupBlocker(message_center::MessageCenter* message_center)
  108. : NotificationBlocker(message_center) {}
  109. IdPopupBlocker(const IdPopupBlocker&) = delete;
  110. IdPopupBlocker& operator=(const IdPopupBlocker&) = delete;
  111. ~IdPopupBlocker() override = default;
  112. void SetTargetId(const std::string& target_id) {
  113. target_id_ = target_id;
  114. NotifyBlockingStateChanged();
  115. }
  116. // message_center::NotificationBlocker:
  117. bool ShouldShowNotificationAsPopup(
  118. const message_center::Notification& notification) const override {
  119. return notification.id() != target_id_;
  120. }
  121. private:
  122. std::string target_id_;
  123. };
  124. // An app registry cache that can be used to register test app names.
  125. class FakeAppRegistryCache {
  126. public:
  127. // The following methods match the interface of apps::AppRegistryCacheWrapper.
  128. static FakeAppRegistryCache& Get() {
  129. static base::NoDestructor<FakeAppRegistryCache> kInstance;
  130. return *kInstance;
  131. }
  132. // In the real class, returns the cache for the given user. We only maintain a
  133. // single fake cache.
  134. FakeAppRegistryCache* GetAppRegistryCache(const AccountId&) { return this; }
  135. template <typename FunctionType>
  136. bool ForOneApp(const std::string& app_id, FunctionType f) {
  137. for (const std::unique_ptr<apps::AppUpdate>& app : apps_) {
  138. if (app_id == app->AppId()) {
  139. f(*app);
  140. return true;
  141. }
  142. }
  143. return false;
  144. }
  145. // Test-only method to populate fake apps.
  146. void AddApp(std::unique_ptr<apps::AppUpdate> app) {
  147. apps_.push_back(std::move(app));
  148. }
  149. private:
  150. // Use pointers as we need a default constructor.
  151. std::vector<std::unique_ptr<apps::AppUpdate>> apps_;
  152. };
  153. // A test fixture that gives access to the HPS notify controller (to fake
  154. // snooping events).
  155. class SnoopingProtectionNotificationBlockerTest : public AshTestBase {
  156. public:
  157. SnoopingProtectionNotificationBlockerTest()
  158. : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
  159. scoped_feature_list_.InitWithFeatures({ash::features::kSnoopingProtection},
  160. {ash::features::kQuickDim});
  161. scoped_command_line_.GetProcessCommandLine()->AppendSwitch(
  162. switches::kHasHps);
  163. }
  164. SnoopingProtectionNotificationBlockerTest(
  165. const SnoopingProtectionNotificationBlockerTest&) = delete;
  166. SnoopingProtectionNotificationBlockerTest& operator=(
  167. const SnoopingProtectionNotificationBlockerTest&) = delete;
  168. ~SnoopingProtectionNotificationBlockerTest() override = default;
  169. // AshTestBase overrides:
  170. void SetUp() override {
  171. // Simulate a working DBus client.
  172. HumanPresenceDBusClient::InitializeFake();
  173. auto* dbus_client = FakeHumanPresenceDBusClient::Get();
  174. dbus_client->set_hps_service_is_available(true);
  175. hps::HpsResultProto state;
  176. state.set_value(hps::HpsResult::NEGATIVE);
  177. dbus_client->set_hps_notify_result(state);
  178. AshTestBase::SetUp();
  179. // The controller has now been initialized, part of which entails sending a
  180. // method to the DBus service. Here we wait for the service to
  181. // asynchronously respond.
  182. base::RunLoop().RunUntilIdle();
  183. // Make sure the controller is active by both logging in and enabling the
  184. // snooping protection pref.
  185. SetSnoopingPref(true);
  186. controller_ = Shell::Get()->snooping_protection_controller();
  187. message_center_ = message_center::MessageCenter::Get();
  188. }
  189. UnifiedMessageCenterBubble* GetMessageCenterBubble() {
  190. return GetPrimaryUnifiedSystemTray()->message_center_bubble();
  191. }
  192. bool HasInfoNotification() {
  193. message_center::Notification* notification =
  194. message_center::MessageCenter::Get()->FindVisibleNotificationById(
  195. SnoopingProtectionNotificationBlocker::kInfoNotificationId);
  196. return notification != nullptr;
  197. }
  198. void SimulateClick(int button_index) {
  199. message_center::Notification* notification =
  200. message_center::MessageCenter::Get()->FindVisibleNotificationById(
  201. SnoopingProtectionNotificationBlocker::kInfoNotificationId);
  202. notification->delegate()->Click(button_index, absl::nullopt);
  203. }
  204. int GetNumOsSmartPrivacySettingsOpened() {
  205. return GetSystemTrayClient()->show_os_smart_privacy_settings_count();
  206. }
  207. protected:
  208. SnoopingProtectionController* controller_ = nullptr;
  209. message_center::MessageCenter* message_center_ = nullptr;
  210. private:
  211. base::test::ScopedFeatureList scoped_feature_list_;
  212. base::test::ScopedCommandLine scoped_command_line_;
  213. };
  214. TEST_F(SnoopingProtectionNotificationBlockerTest, Snooping) {
  215. SetBlockerPref(true);
  216. // By default, no snooper detected.
  217. AddNotification("notification-1", u"notifier-1");
  218. EXPECT_EQ(VisiblePopupCount(), 1u);
  219. EXPECT_EQ(VisibleNotificationCount(), 1u);
  220. // Simulate snooper presence.
  221. hps::HpsResultProto state;
  222. state.set_value(hps::HpsResult::POSITIVE);
  223. controller_->OnHpsNotifyChanged(state);
  224. // When snooping is detected, the popup notification should be hidden but
  225. // remain in the notification queue. Note that, since the popup has been
  226. EXPECT_EQ(VisiblePopupCount(), 0u);
  227. EXPECT_EQ(VisibleNotificationCount(), 1u);
  228. // Add notifications while a snooper is present.
  229. AddNotification("notification-2", u"notifier-2");
  230. AddNotification("notification-3", u"notifier-3");
  231. EXPECT_EQ(VisiblePopupCount(), 1u); // Only our info popup.
  232. EXPECT_TRUE(InfoPopupVisible());
  233. EXPECT_EQ(VisibleNotificationCount(), 4u);
  234. // Simulate snooper absence. We wait for a moment to bypass the controller's
  235. // hysteresis logic.
  236. state.set_value(hps::HpsResult::NEGATIVE);
  237. controller_->OnHpsNotifyChanged(state);
  238. task_environment()->FastForwardBy(base::Seconds(10));
  239. // The unshown popups should appear since snooper has left.
  240. EXPECT_EQ(VisiblePopupCount(), 2u);
  241. EXPECT_FALSE(InfoPopupVisible());
  242. EXPECT_EQ(VisibleNotificationCount(), 3u);
  243. }
  244. TEST_F(SnoopingProtectionNotificationBlockerTest, Pref) {
  245. SetBlockerPref(false);
  246. // Start with one notification that shouldn't be hidden.
  247. AddNotification("notification-1", u"notifier-1");
  248. EXPECT_EQ(VisiblePopupCount(), 1u);
  249. EXPECT_FALSE(InfoPopupVisible());
  250. EXPECT_EQ(VisibleNotificationCount(), 1u);
  251. // Simulate snooper presence.
  252. hps::HpsResultProto state;
  253. state.set_value(hps::HpsResult::POSITIVE);
  254. controller_->OnHpsNotifyChanged(state);
  255. // Notifications should be visible up until the user enables the feature.
  256. EXPECT_EQ(VisiblePopupCount(), 1u);
  257. EXPECT_FALSE(InfoPopupVisible());
  258. EXPECT_EQ(VisibleNotificationCount(), 1u);
  259. SetBlockerPref(true);
  260. // Since notification 1 has been shown, we aren't blocking any popups and our
  261. // info popup need not be shown.
  262. EXPECT_EQ(VisiblePopupCount(), 0u);
  263. EXPECT_FALSE(InfoPopupVisible());
  264. EXPECT_EQ(VisibleNotificationCount(), 1u);
  265. // Add notifications while the feature is disabled. This should cause our info
  266. // popup and no other popups to be shown.
  267. AddNotification("notification-2", u"notifier-2");
  268. AddNotification("notification-3", u"notifier-3");
  269. EXPECT_EQ(VisiblePopupCount(), 1u);
  270. EXPECT_TRUE(InfoPopupVisible());
  271. EXPECT_EQ(VisibleNotificationCount(), 4u);
  272. // Notifications should be shown if *either* the whole setting or the
  273. // subfeature is enabled.
  274. SetSnoopingPref(false);
  275. // The new popups should appear when the feature is disabled.
  276. EXPECT_EQ(VisiblePopupCount(), 2u);
  277. EXPECT_FALSE(InfoPopupVisible());
  278. EXPECT_EQ(VisibleNotificationCount(), 3u);
  279. }
  280. TEST_F(SnoopingProtectionNotificationBlockerTest, SystemNotification) {
  281. SetBlockerPref(true);
  282. // One regular notification, one important notification that should be
  283. // allowlisted, and one important notification that could contain sensitive
  284. // information (and should therefore still be blocked).
  285. AddNotification("notification-1", u"notifier-1");
  286. AddNotification("notification-2", /*notifier_title=*/u"");
  287. AddNotification(
  288. SmsObserver::kNotificationPrefix + std::string("-notification-3"),
  289. /*notifier_title=*/u"");
  290. EXPECT_EQ(VisiblePopupCount(), 3u);
  291. EXPECT_FALSE(InfoPopupVisible());
  292. EXPECT_EQ(VisibleNotificationCount(), 3u);
  293. // Simulate snooper presence.
  294. hps::HpsResultProto state;
  295. state.set_value(hps::HpsResult::POSITIVE);
  296. controller_->OnHpsNotifyChanged(state);
  297. // The safe notification shouldn't be suppressed, but the sensitive
  298. // notification should be.
  299. EXPECT_EQ(VisiblePopupCount(), 2u);
  300. EXPECT_TRUE(InfoPopupVisible());
  301. // Regular notification disappears because it was already shown before the
  302. // snooper arrived.
  303. EXPECT_EQ(PositionInInfoPopupMessage(u"notifier-1"), std::u16string::npos);
  304. // Check that the system notification is labled as such.
  305. EXPECT_NE(PositionInInfoPopupMessage(u"System"), std::u16string::npos);
  306. EXPECT_EQ(VisibleNotificationCount(), 4u);
  307. }
  308. TEST_F(SnoopingProtectionNotificationBlockerTest, InfoPopup) {
  309. SetBlockerPref(true);
  310. // Simulate snooper presence.
  311. hps::HpsResultProto state;
  312. state.set_value(hps::HpsResult::POSITIVE);
  313. controller_->OnHpsNotifyChanged(state);
  314. // Two notifications we're blocking.
  315. AddNotification("notification-1", u"notifier-1");
  316. AddNotification("notification-2", u"notifier-2");
  317. EXPECT_EQ(VisiblePopupCount(), 1u); // Only our info popup.
  318. EXPECT_NE(PositionInInfoPopupMessage(u"notifier-1"), std::u16string::npos);
  319. EXPECT_NE(PositionInInfoPopupMessage(u"notifier-2"), std::u16string::npos);
  320. EXPECT_EQ(VisibleNotificationCount(), 3u);
  321. // Check that the user can remove the info popup and it will return.
  322. RemoveNotification(
  323. SnoopingProtectionNotificationBlocker::kInfoNotificationId);
  324. EXPECT_EQ(VisiblePopupCount(), 0u);
  325. AddNotification("notification-3", u"notifier-3");
  326. EXPECT_EQ(VisiblePopupCount(), 1u); // Only our info popup.
  327. EXPECT_NE(PositionInInfoPopupMessage(u"notifier-2"), std::u16string::npos);
  328. EXPECT_NE(PositionInInfoPopupMessage(u"notifier-3"), std::u16string::npos);
  329. }
  330. // Test that we don't report the notifiers of popups that we (alone) aren't
  331. // blocking.
  332. TEST_F(SnoopingProtectionNotificationBlockerTest, InfoPopupOtherBlocker) {
  333. IdPopupBlocker other_blocker(message_center_);
  334. other_blocker.SetTargetId("notification-2");
  335. SetBlockerPref(true);
  336. // Simulate snooper presence.
  337. hps::HpsResultProto state;
  338. state.set_value(hps::HpsResult::POSITIVE);
  339. controller_->OnHpsNotifyChanged(state);
  340. // One notification only we are blocking, and one notification that is also
  341. // blocked by another blocker.
  342. AddNotification("notification-1", u"notifier-1");
  343. AddNotification("notification-2", u"notifier-2");
  344. EXPECT_EQ(VisiblePopupCount(), 1u);
  345. EXPECT_NE(PositionInInfoPopupMessage(u"notifier-1"), std::u16string::npos);
  346. // Do not report that we're blocking a notification when it won't show up
  347. // after snooping ends.
  348. EXPECT_EQ(PositionInInfoPopupMessage(u"notifier-2"), std::u16string::npos);
  349. EXPECT_EQ(VisibleNotificationCount(), 3u);
  350. // Now update our other blocker not to block either notification.
  351. other_blocker.SetTargetId("notification-3");
  352. // We are now the sole blockers of both notifications, so should report both.
  353. EXPECT_EQ(VisiblePopupCount(), 1u);
  354. EXPECT_NE(PositionInInfoPopupMessage(u"notifier-1"), std::u16string::npos);
  355. EXPECT_NE(PositionInInfoPopupMessage(u"notifier-2"), std::u16string::npos);
  356. EXPECT_EQ(VisibleNotificationCount(), 3u);
  357. }
  358. // Test that the info popup message is changed as relevant notifications are
  359. // added and removed.
  360. TEST_F(SnoopingProtectionNotificationBlockerTest,
  361. InfoPopupChangingNotifications) {
  362. SetBlockerPref(true);
  363. // Simulate snooper presence.
  364. hps::HpsResultProto state;
  365. state.set_value(hps::HpsResult::POSITIVE);
  366. controller_->OnHpsNotifyChanged(state);
  367. // Newer notifiers should come before older ones.
  368. AddNotification("notification-1", u"notifier-1");
  369. AddNotification("notification-2", u"notifier-2");
  370. {
  371. const size_t pos_1 = PositionInInfoPopupMessage(u"notifier-1");
  372. const size_t pos_2 = PositionInInfoPopupMessage(u"notifier-2");
  373. EXPECT_LE(pos_2, pos_1);
  374. EXPECT_LE(pos_1, std::u16string::npos);
  375. }
  376. // Positions should be swapped if we see an old notifier again.
  377. AddNotification("notification-3", u"notifier-1");
  378. {
  379. const size_t pos_1 = PositionInInfoPopupMessage(u"notifier-1");
  380. const size_t pos_2 = PositionInInfoPopupMessage(u"notifier-2");
  381. EXPECT_LE(pos_1, pos_2);
  382. EXPECT_LE(pos_2, std::u16string::npos);
  383. }
  384. // Notifiers don't repeat.
  385. AddNotification("notification-4", u"notifier-1");
  386. {
  387. const size_t pos_1 = PositionInInfoPopupMessage(u"notifier-1");
  388. const size_t pos_2 = PositionInInfoPopupMessage(u"notifier-2");
  389. EXPECT_LE(pos_1, pos_2);
  390. EXPECT_LE(pos_2, std::u16string::npos);
  391. }
  392. // Notifiers are removed correctly.
  393. RemoveNotification("notification-4");
  394. RemoveNotification("notification-2");
  395. {
  396. const size_t pos_1 = PositionInInfoPopupMessage(u"notifier-1");
  397. const size_t pos_2 = PositionInInfoPopupMessage(u"notifier-2");
  398. EXPECT_NE(pos_1, std::u16string::npos);
  399. EXPECT_EQ(pos_2, std::u16string::npos);
  400. }
  401. }
  402. // Test that message center is visible when click "Show" button.
  403. TEST_F(SnoopingProtectionNotificationBlockerTest, ShowButtonClicked) {
  404. SetBlockerPref(true);
  405. // Simulate snooper presence.
  406. hps::HpsResultProto state;
  407. state.set_value(hps::HpsResult::POSITIVE);
  408. controller_->OnHpsNotifyChanged(state);
  409. AddNotification("notification-1", u"notifier-1");
  410. AddNotification("notification-2", u"notifier-2");
  411. EXPECT_TRUE(HasInfoNotification());
  412. // Click on show button.
  413. SimulateClick(/*button_index=*/0);
  414. EXPECT_TRUE(GetMessageCenterBubble()->IsMessageCenterVisible());
  415. }
  416. // Test that message center is visible when click Settings button.
  417. TEST_F(SnoopingProtectionNotificationBlockerTest, SettingsButtonClicked) {
  418. SetBlockerPref(true);
  419. // Simulate snooper presence.
  420. hps::HpsResultProto state;
  421. state.set_value(hps::HpsResult::POSITIVE);
  422. controller_->OnHpsNotifyChanged(state);
  423. AddNotification("notification-1", u"notifier-1");
  424. AddNotification("notification-2", u"notifier-2");
  425. EXPECT_TRUE(HasInfoNotification());
  426. // Click on show button.
  427. SimulateClick(/*button_index=*/1);
  428. EXPECT_EQ(1, GetNumOsSmartPrivacySettingsOpened());
  429. }
  430. TEST(SnoopingProtectionNotificationBlockerInternalTest, WebsiteNotifierTitles) {
  431. // Website without title uses a generic "web" string.
  432. const message_center::NotifierId untrusted_notifier(
  433. GURL("http://untrusted.com:443"));
  434. const std::u16string untrusted_title =
  435. hps_internal::GetNotifierTitle<FakeAppRegistryCache>(untrusted_notifier,
  436. AccountId());
  437. EXPECT_EQ(untrusted_title,
  438. l10n_util::GetStringUTF16(
  439. IDS_ASH_SMART_PRIVACY_SNOOPING_NOTIFICATION_WEB_TITLE_LOWER));
  440. // Website with a trusted title uses the title.
  441. const message_center::NotifierId trusted_notifier(
  442. GURL("https://trusted.com:443"), u"Trusted");
  443. const std::u16string trusted_title =
  444. hps_internal::GetNotifierTitle<FakeAppRegistryCache>(trusted_notifier,
  445. AccountId());
  446. EXPECT_EQ(trusted_title, u"Trusted");
  447. }
  448. TEST(SnoopingProtectionNotificationBlockerInternalTest, AppNotifierTitles) {
  449. // App without known title uses a generic "app" string.
  450. const message_center::NotifierId unknown_app_notifier(
  451. message_center::NotifierType::APPLICATION, "unknown-app");
  452. const std::u16string unknown_app_title =
  453. hps_internal::GetNotifierTitle<FakeAppRegistryCache>(unknown_app_notifier,
  454. AccountId());
  455. EXPECT_EQ(unknown_app_title,
  456. l10n_util::GetStringUTF16(
  457. IDS_ASH_SMART_PRIVACY_SNOOPING_NOTIFICATION_APP_TITLE_LOWER));
  458. // Create an app cache with one used and one unused app.
  459. auto* app_cache =
  460. FakeAppRegistryCache::Get().GetAppRegistryCache(AccountId());
  461. apps::App crostini_app_state(apps::AppType::kCrostini, "crostini-app");
  462. crostini_app_state.short_name = "Signal Messenger";
  463. auto crostini_app = std::make_unique<apps::AppUpdate>(
  464. &crostini_app_state, /*delta=*/nullptr, AccountId());
  465. app_cache->AddApp(std::move(crostini_app));
  466. apps::App arc_app_state(apps::AppType::kArc, "arc-app");
  467. arc_app_state.short_name = "Discord";
  468. auto arc_app = std::make_unique<apps::AppUpdate>(
  469. &arc_app_state, /*delta=*/nullptr, AccountId());
  470. app_cache->AddApp(std::move(arc_app));
  471. // App with a registered name uses that name.
  472. const message_center::NotifierId crostini_app_notifier(
  473. message_center::NotifierType::CROSTINI_APPLICATION, "crostini-app");
  474. const std::u16string crostini_app_title =
  475. hps_internal::GetNotifierTitle<FakeAppRegistryCache>(
  476. crostini_app_notifier, AccountId());
  477. EXPECT_EQ(crostini_app_title, u"Signal Messenger");
  478. }
  479. TEST(SnoopingProtectionNotificationBlockerInternalTest, PopupMessage) {
  480. // Proper app names should be presented as-is.
  481. const std::vector<std::u16string> list_1 = {u"App title"};
  482. const std::u16string list_1_msg =
  483. hps_internal::GetTitlesBlockedMessage(list_1);
  484. EXPECT_TRUE(list_1_msg.find(u"App title") != std::u16string::npos);
  485. // Improper app names should use a reasonable default. In this case, the
  486. // default should be capitalized since it is the first word in the message.
  487. const std::vector<std::u16string> list_2 = {l10n_util::GetStringUTF16(
  488. IDS_ASH_SMART_PRIVACY_SNOOPING_NOTIFICATION_WEB_TITLE_LOWER)};
  489. const std::u16string list_2_msg =
  490. hps_internal::GetTitlesBlockedMessage(list_2);
  491. EXPECT_TRUE(
  492. list_2_msg.find(l10n_util::GetStringUTF16(
  493. IDS_ASH_SMART_PRIVACY_SNOOPING_NOTIFICATION_WEB_TITLE_UPPER)) !=
  494. std::u16string::npos);
  495. // Subsequent improper app names should not be capitalized.
  496. const std::vector<std::u16string> list_3 = {
  497. u"App title",
  498. l10n_util::GetStringUTF16(
  499. IDS_ASH_SMART_PRIVACY_SNOOPING_NOTIFICATION_WEB_TITLE_LOWER)};
  500. const std::u16string list_3_msg =
  501. hps_internal::GetTitlesBlockedMessage(list_3);
  502. EXPECT_TRUE(
  503. list_3_msg.find(l10n_util::GetStringUTF16(
  504. IDS_ASH_SMART_PRIVACY_SNOOPING_NOTIFICATION_WEB_TITLE_UPPER)) ==
  505. std::u16string::npos);
  506. }
  507. } // namespace
  508. } // namespace ash