123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602 |
- // Copyright 2021 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/system/human_presence/snooping_protection_notification_blocker.h"
- #include <memory>
- #include <string>
- #include "ash/constants/ash_features.h"
- #include "ash/constants/ash_pref_names.h"
- #include "ash/constants/ash_switches.h"
- #include "ash/constants/notifier_catalogs.h"
- #include "ash/public/cpp/test/shell_test_api.h"
- #include "ash/public/cpp/test/test_system_tray_client.h"
- #include "ash/session/session_controller_impl.h"
- #include "ash/session/test_session_controller_client.h"
- #include "ash/shell.h"
- #include "ash/system/human_presence/snooping_protection_controller.h"
- #include "ash/system/human_presence/snooping_protection_notification_blocker_internal.h"
- #include "ash/system/message_center/message_center_controller.h"
- #include "ash/system/message_center/unified_message_center_bubble.h"
- #include "ash/system/network/sms_observer.h"
- #include "ash/system/unified/unified_system_tray.h"
- #include "ash/system/unified/unified_system_tray_bubble.h"
- #include "ash/test/ash_test_base.h"
- #include "base/memory/scoped_refptr.h"
- #include "base/no_destructor.h"
- #include "base/strings/utf_string_conversions.h"
- #include "base/test/scoped_command_line.h"
- #include "base/test/scoped_feature_list.h"
- #include "chromeos/ash/components/dbus/hps/hps_service.pb.h"
- #include "chromeos/ash/components/dbus/human_presence/fake_human_presence_dbus_client.h"
- #include "chromeos/ash/components/dbus/human_presence/human_presence_dbus_client.h"
- #include "components/account_id/account_id.h"
- #include "components/services/app_service/public/cpp/app_types.h"
- #include "components/services/app_service/public/cpp/app_update.h"
- #include "ui/base/l10n/l10n_util.h"
- #include "ui/gfx/image/image.h"
- #include "ui/message_center/message_center.h"
- #include "ui/message_center/public/cpp/notification.h"
- #include "ui/message_center/public/cpp/notification_types.h"
- #include "ui/message_center/public/cpp/notifier_id.h"
- #include "url/gurl.h"
- namespace ash {
- namespace {
- // Enables or disables the user pref for the entire feature.
- void SetSnoopingPref(bool enabled) {
- Shell::Get()->session_controller()->GetActivePrefService()->SetBoolean(
- prefs::kSnoopingProtectionEnabled, enabled);
- base::RunLoop().RunUntilIdle();
- }
- // Enables or disables the user pref for notification blocking.
- void SetBlockerPref(bool enabled) {
- Shell::Get()->session_controller()->GetActivePrefService()->SetBoolean(
- prefs::kSnoopingProtectionNotificationSuppressionEnabled, enabled);
- base::RunLoop().RunUntilIdle();
- }
- // Add a notification to the message center. An empty notifier title creates a
- // system notification.
- void AddNotification(const std::string& notification_id,
- const std::u16string& notifier_title) {
- const message_center::NotifierId notifier_id =
- notifier_title.empty()
- ? message_center::NotifierId(
- message_center::NotifierType::SYSTEM_COMPONENT, "system",
- NotificationCatalogName::kHPSNotify)
- : message_center::NotifierId(/*url=*/GURL(), notifier_title);
- message_center::MessageCenter::Get()->AddNotification(
- std::make_unique<message_center::Notification>(
- message_center::NOTIFICATION_TYPE_SIMPLE, notification_id,
- u"test-title", u"test-message", /*icon=*/ui::ImageModel(),
- /*display_source=*/std::u16string(), /*origin_url=*/GURL(),
- notifier_id, message_center::RichNotificationData(),
- base::MakeRefCounted<message_center::NotificationDelegate>()));
- }
- // Removes the notification with the given ID.
- void RemoveNotification(const std::string& notification_id) {
- message_center::MessageCenter::Get()->RemoveNotification(notification_id,
- /*by_user=*/true);
- }
- // Returns the number of popup notifications that are currently visible in the
- // message center.
- size_t VisiblePopupCount() {
- return message_center::MessageCenter::Get()->GetPopupNotifications().size();
- }
- // Returns the number of (popup or non-popup) notifications that are currently
- // visible in the message center queue.
- size_t VisibleNotificationCount() {
- return message_center::MessageCenter::Get()->GetVisibleNotifications().size();
- }
- // Returns true if the HPS notify informational popup is popped-up.
- bool InfoPopupVisible() {
- return message_center::MessageCenter::Get()->FindPopupNotificationById(
- SnoopingProtectionNotificationBlocker::kInfoNotificationId) !=
- nullptr;
- }
- // Returns the index at which the given substring appears in the informational
- // popup's message, or npos otherwise.
- size_t PositionInInfoPopupMessage(const std::u16string& substr) {
- const message_center::Notification* notification =
- message_center::MessageCenter::Get()->FindPopupNotificationById(
- SnoopingProtectionNotificationBlocker::kInfoNotificationId);
- return notification ? notification->message().find(substr)
- : std::u16string::npos;
- }
- // A blocker that blocks only a popup with the given ID.
- class IdPopupBlocker : public message_center::NotificationBlocker {
- public:
- IdPopupBlocker(message_center::MessageCenter* message_center)
- : NotificationBlocker(message_center) {}
- IdPopupBlocker(const IdPopupBlocker&) = delete;
- IdPopupBlocker& operator=(const IdPopupBlocker&) = delete;
- ~IdPopupBlocker() override = default;
- void SetTargetId(const std::string& target_id) {
- target_id_ = target_id;
- NotifyBlockingStateChanged();
- }
- // message_center::NotificationBlocker:
- bool ShouldShowNotificationAsPopup(
- const message_center::Notification& notification) const override {
- return notification.id() != target_id_;
- }
- private:
- std::string target_id_;
- };
- // An app registry cache that can be used to register test app names.
- class FakeAppRegistryCache {
- public:
- // The following methods match the interface of apps::AppRegistryCacheWrapper.
- static FakeAppRegistryCache& Get() {
- static base::NoDestructor<FakeAppRegistryCache> kInstance;
- return *kInstance;
- }
- // In the real class, returns the cache for the given user. We only maintain a
- // single fake cache.
- FakeAppRegistryCache* GetAppRegistryCache(const AccountId&) { return this; }
- template <typename FunctionType>
- bool ForOneApp(const std::string& app_id, FunctionType f) {
- for (const std::unique_ptr<apps::AppUpdate>& app : apps_) {
- if (app_id == app->AppId()) {
- f(*app);
- return true;
- }
- }
- return false;
- }
- // Test-only method to populate fake apps.
- void AddApp(std::unique_ptr<apps::AppUpdate> app) {
- apps_.push_back(std::move(app));
- }
- private:
- // Use pointers as we need a default constructor.
- std::vector<std::unique_ptr<apps::AppUpdate>> apps_;
- };
- // A test fixture that gives access to the HPS notify controller (to fake
- // snooping events).
- class SnoopingProtectionNotificationBlockerTest : public AshTestBase {
- public:
- SnoopingProtectionNotificationBlockerTest()
- : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
- scoped_feature_list_.InitWithFeatures({ash::features::kSnoopingProtection},
- {ash::features::kQuickDim});
- scoped_command_line_.GetProcessCommandLine()->AppendSwitch(
- switches::kHasHps);
- }
- SnoopingProtectionNotificationBlockerTest(
- const SnoopingProtectionNotificationBlockerTest&) = delete;
- SnoopingProtectionNotificationBlockerTest& operator=(
- const SnoopingProtectionNotificationBlockerTest&) = delete;
- ~SnoopingProtectionNotificationBlockerTest() override = default;
- // AshTestBase overrides:
- void SetUp() override {
- // Simulate a working DBus client.
- HumanPresenceDBusClient::InitializeFake();
- auto* dbus_client = FakeHumanPresenceDBusClient::Get();
- dbus_client->set_hps_service_is_available(true);
- hps::HpsResultProto state;
- state.set_value(hps::HpsResult::NEGATIVE);
- dbus_client->set_hps_notify_result(state);
- AshTestBase::SetUp();
- // The controller has now been initialized, part of which entails sending a
- // method to the DBus service. Here we wait for the service to
- // asynchronously respond.
- base::RunLoop().RunUntilIdle();
- // Make sure the controller is active by both logging in and enabling the
- // snooping protection pref.
- SetSnoopingPref(true);
- controller_ = Shell::Get()->snooping_protection_controller();
- message_center_ = message_center::MessageCenter::Get();
- }
- UnifiedMessageCenterBubble* GetMessageCenterBubble() {
- return GetPrimaryUnifiedSystemTray()->message_center_bubble();
- }
- bool HasInfoNotification() {
- message_center::Notification* notification =
- message_center::MessageCenter::Get()->FindVisibleNotificationById(
- SnoopingProtectionNotificationBlocker::kInfoNotificationId);
- return notification != nullptr;
- }
- void SimulateClick(int button_index) {
- message_center::Notification* notification =
- message_center::MessageCenter::Get()->FindVisibleNotificationById(
- SnoopingProtectionNotificationBlocker::kInfoNotificationId);
- notification->delegate()->Click(button_index, absl::nullopt);
- }
- int GetNumOsSmartPrivacySettingsOpened() {
- return GetSystemTrayClient()->show_os_smart_privacy_settings_count();
- }
- protected:
- SnoopingProtectionController* controller_ = nullptr;
- message_center::MessageCenter* message_center_ = nullptr;
- private:
- base::test::ScopedFeatureList scoped_feature_list_;
- base::test::ScopedCommandLine scoped_command_line_;
- };
- TEST_F(SnoopingProtectionNotificationBlockerTest, Snooping) {
- SetBlockerPref(true);
- // By default, no snooper detected.
- AddNotification("notification-1", u"notifier-1");
- EXPECT_EQ(VisiblePopupCount(), 1u);
- EXPECT_EQ(VisibleNotificationCount(), 1u);
- // Simulate snooper presence.
- hps::HpsResultProto state;
- state.set_value(hps::HpsResult::POSITIVE);
- controller_->OnHpsNotifyChanged(state);
- // When snooping is detected, the popup notification should be hidden but
- // remain in the notification queue. Note that, since the popup has been
- EXPECT_EQ(VisiblePopupCount(), 0u);
- EXPECT_EQ(VisibleNotificationCount(), 1u);
- // Add notifications while a snooper is present.
- AddNotification("notification-2", u"notifier-2");
- AddNotification("notification-3", u"notifier-3");
- EXPECT_EQ(VisiblePopupCount(), 1u); // Only our info popup.
- EXPECT_TRUE(InfoPopupVisible());
- EXPECT_EQ(VisibleNotificationCount(), 4u);
- // Simulate snooper absence. We wait for a moment to bypass the controller's
- // hysteresis logic.
- state.set_value(hps::HpsResult::NEGATIVE);
- controller_->OnHpsNotifyChanged(state);
- task_environment()->FastForwardBy(base::Seconds(10));
- // The unshown popups should appear since snooper has left.
- EXPECT_EQ(VisiblePopupCount(), 2u);
- EXPECT_FALSE(InfoPopupVisible());
- EXPECT_EQ(VisibleNotificationCount(), 3u);
- }
- TEST_F(SnoopingProtectionNotificationBlockerTest, Pref) {
- SetBlockerPref(false);
- // Start with one notification that shouldn't be hidden.
- AddNotification("notification-1", u"notifier-1");
- EXPECT_EQ(VisiblePopupCount(), 1u);
- EXPECT_FALSE(InfoPopupVisible());
- EXPECT_EQ(VisibleNotificationCount(), 1u);
- // Simulate snooper presence.
- hps::HpsResultProto state;
- state.set_value(hps::HpsResult::POSITIVE);
- controller_->OnHpsNotifyChanged(state);
- // Notifications should be visible up until the user enables the feature.
- EXPECT_EQ(VisiblePopupCount(), 1u);
- EXPECT_FALSE(InfoPopupVisible());
- EXPECT_EQ(VisibleNotificationCount(), 1u);
- SetBlockerPref(true);
- // Since notification 1 has been shown, we aren't blocking any popups and our
- // info popup need not be shown.
- EXPECT_EQ(VisiblePopupCount(), 0u);
- EXPECT_FALSE(InfoPopupVisible());
- EXPECT_EQ(VisibleNotificationCount(), 1u);
- // Add notifications while the feature is disabled. This should cause our info
- // popup and no other popups to be shown.
- AddNotification("notification-2", u"notifier-2");
- AddNotification("notification-3", u"notifier-3");
- EXPECT_EQ(VisiblePopupCount(), 1u);
- EXPECT_TRUE(InfoPopupVisible());
- EXPECT_EQ(VisibleNotificationCount(), 4u);
- // Notifications should be shown if *either* the whole setting or the
- // subfeature is enabled.
- SetSnoopingPref(false);
- // The new popups should appear when the feature is disabled.
- EXPECT_EQ(VisiblePopupCount(), 2u);
- EXPECT_FALSE(InfoPopupVisible());
- EXPECT_EQ(VisibleNotificationCount(), 3u);
- }
- TEST_F(SnoopingProtectionNotificationBlockerTest, SystemNotification) {
- SetBlockerPref(true);
- // One regular notification, one important notification that should be
- // allowlisted, and one important notification that could contain sensitive
- // information (and should therefore still be blocked).
- AddNotification("notification-1", u"notifier-1");
- AddNotification("notification-2", /*notifier_title=*/u"");
- AddNotification(
- SmsObserver::kNotificationPrefix + std::string("-notification-3"),
- /*notifier_title=*/u"");
- EXPECT_EQ(VisiblePopupCount(), 3u);
- EXPECT_FALSE(InfoPopupVisible());
- EXPECT_EQ(VisibleNotificationCount(), 3u);
- // Simulate snooper presence.
- hps::HpsResultProto state;
- state.set_value(hps::HpsResult::POSITIVE);
- controller_->OnHpsNotifyChanged(state);
- // The safe notification shouldn't be suppressed, but the sensitive
- // notification should be.
- EXPECT_EQ(VisiblePopupCount(), 2u);
- EXPECT_TRUE(InfoPopupVisible());
- // Regular notification disappears because it was already shown before the
- // snooper arrived.
- EXPECT_EQ(PositionInInfoPopupMessage(u"notifier-1"), std::u16string::npos);
- // Check that the system notification is labled as such.
- EXPECT_NE(PositionInInfoPopupMessage(u"System"), std::u16string::npos);
- EXPECT_EQ(VisibleNotificationCount(), 4u);
- }
- TEST_F(SnoopingProtectionNotificationBlockerTest, InfoPopup) {
- SetBlockerPref(true);
- // Simulate snooper presence.
- hps::HpsResultProto state;
- state.set_value(hps::HpsResult::POSITIVE);
- controller_->OnHpsNotifyChanged(state);
- // Two notifications we're blocking.
- AddNotification("notification-1", u"notifier-1");
- AddNotification("notification-2", u"notifier-2");
- EXPECT_EQ(VisiblePopupCount(), 1u); // Only our info popup.
- EXPECT_NE(PositionInInfoPopupMessage(u"notifier-1"), std::u16string::npos);
- EXPECT_NE(PositionInInfoPopupMessage(u"notifier-2"), std::u16string::npos);
- EXPECT_EQ(VisibleNotificationCount(), 3u);
- // Check that the user can remove the info popup and it will return.
- RemoveNotification(
- SnoopingProtectionNotificationBlocker::kInfoNotificationId);
- EXPECT_EQ(VisiblePopupCount(), 0u);
- AddNotification("notification-3", u"notifier-3");
- EXPECT_EQ(VisiblePopupCount(), 1u); // Only our info popup.
- EXPECT_NE(PositionInInfoPopupMessage(u"notifier-2"), std::u16string::npos);
- EXPECT_NE(PositionInInfoPopupMessage(u"notifier-3"), std::u16string::npos);
- }
- // Test that we don't report the notifiers of popups that we (alone) aren't
- // blocking.
- TEST_F(SnoopingProtectionNotificationBlockerTest, InfoPopupOtherBlocker) {
- IdPopupBlocker other_blocker(message_center_);
- other_blocker.SetTargetId("notification-2");
- SetBlockerPref(true);
- // Simulate snooper presence.
- hps::HpsResultProto state;
- state.set_value(hps::HpsResult::POSITIVE);
- controller_->OnHpsNotifyChanged(state);
- // One notification only we are blocking, and one notification that is also
- // blocked by another blocker.
- AddNotification("notification-1", u"notifier-1");
- AddNotification("notification-2", u"notifier-2");
- EXPECT_EQ(VisiblePopupCount(), 1u);
- EXPECT_NE(PositionInInfoPopupMessage(u"notifier-1"), std::u16string::npos);
- // Do not report that we're blocking a notification when it won't show up
- // after snooping ends.
- EXPECT_EQ(PositionInInfoPopupMessage(u"notifier-2"), std::u16string::npos);
- EXPECT_EQ(VisibleNotificationCount(), 3u);
- // Now update our other blocker not to block either notification.
- other_blocker.SetTargetId("notification-3");
- // We are now the sole blockers of both notifications, so should report both.
- EXPECT_EQ(VisiblePopupCount(), 1u);
- EXPECT_NE(PositionInInfoPopupMessage(u"notifier-1"), std::u16string::npos);
- EXPECT_NE(PositionInInfoPopupMessage(u"notifier-2"), std::u16string::npos);
- EXPECT_EQ(VisibleNotificationCount(), 3u);
- }
- // Test that the info popup message is changed as relevant notifications are
- // added and removed.
- TEST_F(SnoopingProtectionNotificationBlockerTest,
- InfoPopupChangingNotifications) {
- SetBlockerPref(true);
- // Simulate snooper presence.
- hps::HpsResultProto state;
- state.set_value(hps::HpsResult::POSITIVE);
- controller_->OnHpsNotifyChanged(state);
- // Newer notifiers should come before older ones.
- AddNotification("notification-1", u"notifier-1");
- AddNotification("notification-2", u"notifier-2");
- {
- const size_t pos_1 = PositionInInfoPopupMessage(u"notifier-1");
- const size_t pos_2 = PositionInInfoPopupMessage(u"notifier-2");
- EXPECT_LE(pos_2, pos_1);
- EXPECT_LE(pos_1, std::u16string::npos);
- }
- // Positions should be swapped if we see an old notifier again.
- AddNotification("notification-3", u"notifier-1");
- {
- const size_t pos_1 = PositionInInfoPopupMessage(u"notifier-1");
- const size_t pos_2 = PositionInInfoPopupMessage(u"notifier-2");
- EXPECT_LE(pos_1, pos_2);
- EXPECT_LE(pos_2, std::u16string::npos);
- }
- // Notifiers don't repeat.
- AddNotification("notification-4", u"notifier-1");
- {
- const size_t pos_1 = PositionInInfoPopupMessage(u"notifier-1");
- const size_t pos_2 = PositionInInfoPopupMessage(u"notifier-2");
- EXPECT_LE(pos_1, pos_2);
- EXPECT_LE(pos_2, std::u16string::npos);
- }
- // Notifiers are removed correctly.
- RemoveNotification("notification-4");
- RemoveNotification("notification-2");
- {
- const size_t pos_1 = PositionInInfoPopupMessage(u"notifier-1");
- const size_t pos_2 = PositionInInfoPopupMessage(u"notifier-2");
- EXPECT_NE(pos_1, std::u16string::npos);
- EXPECT_EQ(pos_2, std::u16string::npos);
- }
- }
- // Test that message center is visible when click "Show" button.
- TEST_F(SnoopingProtectionNotificationBlockerTest, ShowButtonClicked) {
- SetBlockerPref(true);
- // Simulate snooper presence.
- hps::HpsResultProto state;
- state.set_value(hps::HpsResult::POSITIVE);
- controller_->OnHpsNotifyChanged(state);
- AddNotification("notification-1", u"notifier-1");
- AddNotification("notification-2", u"notifier-2");
- EXPECT_TRUE(HasInfoNotification());
- // Click on show button.
- SimulateClick(/*button_index=*/0);
- EXPECT_TRUE(GetMessageCenterBubble()->IsMessageCenterVisible());
- }
- // Test that message center is visible when click Settings button.
- TEST_F(SnoopingProtectionNotificationBlockerTest, SettingsButtonClicked) {
- SetBlockerPref(true);
- // Simulate snooper presence.
- hps::HpsResultProto state;
- state.set_value(hps::HpsResult::POSITIVE);
- controller_->OnHpsNotifyChanged(state);
- AddNotification("notification-1", u"notifier-1");
- AddNotification("notification-2", u"notifier-2");
- EXPECT_TRUE(HasInfoNotification());
- // Click on show button.
- SimulateClick(/*button_index=*/1);
- EXPECT_EQ(1, GetNumOsSmartPrivacySettingsOpened());
- }
- TEST(SnoopingProtectionNotificationBlockerInternalTest, WebsiteNotifierTitles) {
- // Website without title uses a generic "web" string.
- const message_center::NotifierId untrusted_notifier(
- GURL("http://untrusted.com:443"));
- const std::u16string untrusted_title =
- hps_internal::GetNotifierTitle<FakeAppRegistryCache>(untrusted_notifier,
- AccountId());
- EXPECT_EQ(untrusted_title,
- l10n_util::GetStringUTF16(
- IDS_ASH_SMART_PRIVACY_SNOOPING_NOTIFICATION_WEB_TITLE_LOWER));
- // Website with a trusted title uses the title.
- const message_center::NotifierId trusted_notifier(
- GURL("https://trusted.com:443"), u"Trusted");
- const std::u16string trusted_title =
- hps_internal::GetNotifierTitle<FakeAppRegistryCache>(trusted_notifier,
- AccountId());
- EXPECT_EQ(trusted_title, u"Trusted");
- }
- TEST(SnoopingProtectionNotificationBlockerInternalTest, AppNotifierTitles) {
- // App without known title uses a generic "app" string.
- const message_center::NotifierId unknown_app_notifier(
- message_center::NotifierType::APPLICATION, "unknown-app");
- const std::u16string unknown_app_title =
- hps_internal::GetNotifierTitle<FakeAppRegistryCache>(unknown_app_notifier,
- AccountId());
- EXPECT_EQ(unknown_app_title,
- l10n_util::GetStringUTF16(
- IDS_ASH_SMART_PRIVACY_SNOOPING_NOTIFICATION_APP_TITLE_LOWER));
- // Create an app cache with one used and one unused app.
- auto* app_cache =
- FakeAppRegistryCache::Get().GetAppRegistryCache(AccountId());
- apps::App crostini_app_state(apps::AppType::kCrostini, "crostini-app");
- crostini_app_state.short_name = "Signal Messenger";
- auto crostini_app = std::make_unique<apps::AppUpdate>(
- &crostini_app_state, /*delta=*/nullptr, AccountId());
- app_cache->AddApp(std::move(crostini_app));
- apps::App arc_app_state(apps::AppType::kArc, "arc-app");
- arc_app_state.short_name = "Discord";
- auto arc_app = std::make_unique<apps::AppUpdate>(
- &arc_app_state, /*delta=*/nullptr, AccountId());
- app_cache->AddApp(std::move(arc_app));
- // App with a registered name uses that name.
- const message_center::NotifierId crostini_app_notifier(
- message_center::NotifierType::CROSTINI_APPLICATION, "crostini-app");
- const std::u16string crostini_app_title =
- hps_internal::GetNotifierTitle<FakeAppRegistryCache>(
- crostini_app_notifier, AccountId());
- EXPECT_EQ(crostini_app_title, u"Signal Messenger");
- }
- TEST(SnoopingProtectionNotificationBlockerInternalTest, PopupMessage) {
- // Proper app names should be presented as-is.
- const std::vector<std::u16string> list_1 = {u"App title"};
- const std::u16string list_1_msg =
- hps_internal::GetTitlesBlockedMessage(list_1);
- EXPECT_TRUE(list_1_msg.find(u"App title") != std::u16string::npos);
- // Improper app names should use a reasonable default. In this case, the
- // default should be capitalized since it is the first word in the message.
- const std::vector<std::u16string> list_2 = {l10n_util::GetStringUTF16(
- IDS_ASH_SMART_PRIVACY_SNOOPING_NOTIFICATION_WEB_TITLE_LOWER)};
- const std::u16string list_2_msg =
- hps_internal::GetTitlesBlockedMessage(list_2);
- EXPECT_TRUE(
- list_2_msg.find(l10n_util::GetStringUTF16(
- IDS_ASH_SMART_PRIVACY_SNOOPING_NOTIFICATION_WEB_TITLE_UPPER)) !=
- std::u16string::npos);
- // Subsequent improper app names should not be capitalized.
- const std::vector<std::u16string> list_3 = {
- u"App title",
- l10n_util::GetStringUTF16(
- IDS_ASH_SMART_PRIVACY_SNOOPING_NOTIFICATION_WEB_TITLE_LOWER)};
- const std::u16string list_3_msg =
- hps_internal::GetTitlesBlockedMessage(list_3);
- EXPECT_TRUE(
- list_3_msg.find(l10n_util::GetStringUTF16(
- IDS_ASH_SMART_PRIVACY_SNOOPING_NOTIFICATION_WEB_TITLE_UPPER)) ==
- std::u16string::npos);
- }
- } // namespace
- } // namespace ash
|