Commit 032f0903 authored by Joon Ahn's avatar Joon Ahn Committed by Chromium LUCI CQ

nearby: treat url-based text attachments as a link

http://screen/9h6LUEHGXebCfzv

Bug: 1158473
Change-Id: I568e0e72e12636799491584ad7f65f84e0305df2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2593510Reviewed-by: default avatarJames Vecore <vecore@google.com>
Commit-Queue: Joon Ahn <joonbug@chromium.org>
Cr-Commit-Position: refs/heads/master@{#837820}
parent 075dfec2
......@@ -255,6 +255,9 @@
<message name="IDS_NEARBY_NOTIFICATION_ACTION_OPEN_FOLDER" desc="Notification action button text that opens the folder to the received files.">
Open folder
</message>
<message name="IDS_NEARBY_NOTIFICATION_ACTION_OPEN_URL" desc="Notification action button text that opens the received URL.">
Open
</message>
<message name="IDS_NEARBY_NOTIFICATION_CONNECTION_REQUEST_MESSAGE" desc="Text shown as the message of a notfication when a nearby device requests a connection via Nearby Share.">
{COUNT, plural,
=1 {<ph name="DEVICE_NAME">$1<ex>Ted's Pixel 2</ex></ph> is sharing <ph name="ATTACHMENTS">$2<ex>1 item</ex></ph> with you.}
......
88bc76583253f2a3654f2e0bf0a06d74d2c26d7e
\ No newline at end of file
......@@ -61,6 +61,7 @@ class MockNearbySharingService : public NearbySharingService {
Open,
(const ShareTarget&, StatusCodesCallback),
(override));
MOCK_METHOD(void, OpenURL, (GURL), (override));
MOCK_METHOD(NearbyNotificationDelegate*,
GetNotificationDelegate,
(const std::string&),
......
......@@ -215,8 +215,15 @@ gfx::Image GetImageFromShareTarget(const ShareTarget& share_target) {
NearbyNotificationManager::ReceivedContentType GetReceivedContentType(
const ShareTarget& share_target) {
if (!share_target.text_attachments.empty())
if (!share_target.text_attachments.empty()) {
const TextAttachment& file = share_target.text_attachments[0];
if (share_target.text_attachments.size() == 1 &&
file.type() == sharing::mojom::TextMetadata::Type::kUrl) {
return NearbyNotificationManager::ReceivedContentType::kSingleUrl;
}
return NearbyNotificationManager::ReceivedContentType::kText;
}
if (share_target.file_attachments.size() != 1)
return NearbyNotificationManager::ReceivedContentType::kFiles;
......@@ -378,6 +385,10 @@ class SuccessNotificationDelegate : public NearbyNotificationDelegate {
DCHECK_EQ(0, *action_index);
CopyTextToClipboard();
break;
case NearbyNotificationManager::ReceivedContentType::kSingleUrl:
DCHECK_EQ(0, *action_index);
OpenTextLink();
break;
case NearbyNotificationManager::ReceivedContentType::kSingleImage:
switch (*action_index) {
case 0:
......@@ -420,6 +431,16 @@ class SuccessNotificationDelegate : public NearbyNotificationDelegate {
}
}
void OpenTextLink() {
const std::string& url = share_target_.text_attachments[0].text_body();
manager_->OpenURL(GURL(url));
if (testing_callback_) {
std::move(testing_callback_)
.Run(NearbyNotificationManager::SuccessNotificationAction::kOpenUrl);
}
}
void CopyTextToClipboard() {
DCHECK_GT(share_target_.text_attachments.size(), 0u);
const std::string& text = share_target_.text_attachments[0].text_body();
......@@ -725,6 +746,10 @@ void NearbyNotificationManager::ShowIncomingSuccess(
notification_actions.emplace_back(l10n_util::GetStringUTF16(
IDS_NEARBY_NOTIFICATION_ACTION_COPY_TO_CLIPBOARD));
break;
case ReceivedContentType::kSingleUrl:
notification_actions.emplace_back(
l10n_util::GetStringUTF16(IDS_NEARBY_NOTIFICATION_ACTION_OPEN_URL));
break;
case ReceivedContentType::kSingleImage:
notification_actions.emplace_back(l10n_util::GetStringUTF16(
IDS_NEARBY_NOTIFICATION_ACTION_OPEN_FOLDER));
......@@ -807,6 +832,10 @@ NearbyNotificationDelegate* NearbyNotificationManager::GetNotificationDelegate(
return iter->second.get();
}
void NearbyNotificationManager::OpenURL(GURL url) {
nearby_service_->OpenURL(url);
}
void NearbyNotificationManager::CancelTransfer() {
CloseTransfer();
nearby_service_->Cancel(*share_target_, base::DoNothing());
......
......@@ -35,13 +35,15 @@ class NearbyNotificationManager : public TransferUpdateCallback,
kCopyText,
kCopyImage,
kOpenDownloads,
kOpenUrl,
};
// Type of content we received that determines the actions we provide.
enum class ReceivedContentType {
kText, // Arbitrary text content
kSingleImage, // One image that will be shown as a preview
kFiles, // One or more generic files
kSingleImage, // One image that will be shown as a preview
kSingleUrl, // One URL that will be opened on click.
kText, // Arbitrary text content
};
NearbyNotificationManager(
......@@ -93,6 +95,8 @@ class NearbyNotificationManager : public TransferUpdateCallback,
NearbyNotificationDelegate* GetNotificationDelegate(
const std::string& notification_id);
void OpenURL(GURL url);
// Cancels the currently in progress transfer.
void CancelTransfer();
......
......@@ -65,6 +65,7 @@
namespace {
const char kTextBody[] = "text body";
const char kTextUrl[] = "https://google.com";
MATCHER_P(MatchesTarget, target, "") {
return arg.id == target.id;
......@@ -74,6 +75,10 @@ TextAttachment CreateTextAttachment(TextAttachment::Type type) {
return TextAttachment(type, kTextBody);
}
TextAttachment CreateUrlAttachment() {
return TextAttachment(TextAttachment::Type::kUrl, kTextUrl);
}
FileAttachment CreateFileAttachment(FileAttachment::Type type) {
return FileAttachment(/*id=*/0, /*size=*/10, /*file_name=*/"file.jpg",
/*mime_type=*/"example", type);
......@@ -171,6 +176,7 @@ class NearbyNotificationManagerTest : public testing::Test {
}
ShareTarget CreateIncomingShareTarget(int text_attachments,
int url_attachements,
int image_attachments,
int other_file_attachments) {
ShareTarget share_target;
......@@ -180,6 +186,10 @@ class NearbyNotificationManagerTest : public testing::Test {
CreateTextAttachment(TextAttachment::Type::kText));
}
for (int i = 0; i < url_attachements; i++) {
share_target.text_attachments.push_back(CreateUrlAttachment());
}
for (int i = 0; i < image_attachments; i++) {
base::ScopedAllowBlockingForTesting allow_blocking;
std::string name = base::StrCat({base::NumberToString(i), ".png"});
......@@ -209,6 +219,7 @@ class NearbyNotificationManagerTest : public testing::Test {
base::ScopedTempDir temp_dir_;
content::BrowserTaskEnvironment task_environment_{
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
std::unique_ptr<TestingProfileManager> profile_manager_;
TestingPrefServiceSimple pref_service_;
TestingProfile profile_;
std::unique_ptr<NotificationDisplayServiceTester> notification_tester_;
......@@ -928,9 +939,9 @@ TEST_F(NearbyNotificationManagerTest,
run_loop.Quit();
}));
ShareTarget share_target =
CreateIncomingShareTarget(/*text_attachments=*/0, /*image_attachments=*/1,
/*other_file_attachments=*/0);
ShareTarget share_target = CreateIncomingShareTarget(
/*text_attachments=*/0, /*url_attachments=*/0, /*image_attachments=*/1,
/*other_file_attachments=*/0);
manager()->ShowSuccess(share_target);
// Image decoding happens asynchronously so wait for the notification to show.
......@@ -975,9 +986,9 @@ TEST_F(NearbyNotificationManagerTest,
run_loop.Quit();
}));
ShareTarget share_target =
CreateIncomingShareTarget(/*text_attachments=*/0, /*image_attachments=*/1,
/*other_file_attachments=*/0);
ShareTarget share_target = CreateIncomingShareTarget(
/*text_attachments=*/0, /*url_attachments=*/0, /*image_attachments=*/1,
/*other_file_attachments=*/0);
manager()->ShowSuccess(share_target);
// Image decoding happens asynchronously so wait for the notification to show.
......@@ -1026,9 +1037,9 @@ TEST_F(NearbyNotificationManagerTest,
run_loop.Quit();
}));
ShareTarget share_target =
CreateIncomingShareTarget(/*text_attachments=*/0, /*image_attachments=*/2,
/*other_file_attachments=*/0);
ShareTarget share_target = CreateIncomingShareTarget(
/*text_attachments=*/0, /*url_attachments=*/0, /*image_attachments=*/2,
/*other_file_attachments=*/0);
manager()->ShowSuccess(share_target);
std::vector<message_center::Notification> notifications =
......@@ -1063,9 +1074,9 @@ TEST_F(NearbyNotificationManagerTest, SuccessNotificationClicked_TextReceived) {
run_loop.Quit();
}));
ShareTarget share_target =
CreateIncomingShareTarget(/*text_attachments=*/1, /*image_attachments=*/0,
/*other_file_attachments=*/0);
ShareTarget share_target = CreateIncomingShareTarget(
/*text_attachments=*/1, /*url_attachments=*/0, /*image_attachments=*/0,
/*other_file_attachments=*/0);
manager()->ShowSuccess(share_target);
std::vector<message_center::Notification> notifications =
......@@ -1089,6 +1100,41 @@ TEST_F(NearbyNotificationManagerTest, SuccessNotificationClicked_TextReceived) {
EXPECT_EQ(0u, GetDisplayedNotifications().size());
}
TEST_F(NearbyNotificationManagerTest, SuccessNotificationClicked_UrlReceived) {
base::RunLoop run_loop;
manager()->SetOnSuccessClickedForTesting(base::BindLambdaForTesting(
[&](NearbyNotificationManager::SuccessNotificationAction action) {
EXPECT_EQ(
NearbyNotificationManager::SuccessNotificationAction::kOpenUrl,
action);
run_loop.Quit();
}));
ShareTarget share_target = CreateIncomingShareTarget(
/*text_attachments=*/0, /*url_attachments=*/1, /*image_attachments=*/0,
/*other_file_attachments=*/0);
manager()->ShowSuccess(share_target);
std::vector<message_center::Notification> notifications =
GetDisplayedNotifications();
ASSERT_EQ(1u, notifications.size());
const message_center::Notification& notification = notifications[0];
ASSERT_EQ(1u, notification.buttons().size());
EXPECT_EQ(l10n_util::GetStringUTF16(IDS_NEARBY_NOTIFICATION_ACTION_OPEN_URL),
notification.buttons()[0].title);
EXPECT_CALL(*nearby_service_, OpenURL(testing::_)).Times(1);
notification_tester_->SimulateClick(NotificationHandler::Type::NEARBY_SHARE,
notification.id(),
/*action_index=*/0,
/*reply=*/base::nullopt);
run_loop.Run();
// Notification should be closed.
EXPECT_EQ(0u, GetDisplayedNotifications().size());
}
TEST_F(NearbyNotificationManagerTest,
SuccessNotificationClicked_SingleFileReceived) {
base::RunLoop run_loop;
......@@ -1100,9 +1146,9 @@ TEST_F(NearbyNotificationManagerTest,
run_loop.Quit();
}));
ShareTarget share_target =
CreateIncomingShareTarget(/*text_attachments=*/0, /*image_attachments=*/0,
/*other_file_attachments=*/1);
ShareTarget share_target = CreateIncomingShareTarget(
/*text_attachments=*/0, /*url_attachments=*/0, /*image_attachments=*/0,
/*other_file_attachments=*/1);
manager()->ShowSuccess(share_target);
std::vector<message_center::Notification> notifications =
......@@ -1136,9 +1182,9 @@ TEST_F(NearbyNotificationManagerTest,
run_loop.Quit();
}));
ShareTarget share_target =
CreateIncomingShareTarget(/*text_attachments=*/0, /*image_attachments=*/1,
/*other_file_attachments=*/2);
ShareTarget share_target = CreateIncomingShareTarget(
/*text_attachments=*/0, /*url_attachments=*/0, /*image_attachments=*/1,
/*other_file_attachments=*/2);
manager()->ShowSuccess(share_target);
std::vector<message_center::Notification> notifications =
......
......@@ -137,6 +137,9 @@ class NearbySharingService : public KeyedService {
virtual void Open(const ShareTarget& share_target,
StatusCodesCallback status_codes_callback) = 0;
// Opens an url target on a browser instance.
virtual void OpenURL(GURL url) = 0;
// Gets a delegate to handle events for |notification_id| or nullptr.
virtual NearbyNotificationDelegate* GetNotificationDelegate(
const std::string& notification_id) = 0;
......
......@@ -38,6 +38,8 @@
#include "chrome/browser/nearby_sharing/transfer_metadata_builder.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
#include "chrome/services/sharing/public/cpp/advertisement.h"
#include "chrome/services/sharing/public/cpp/conversions.h"
#include "chromeos/services/nearby/public/mojom/nearby_connections_types.mojom.h"
......@@ -844,6 +846,13 @@ void NearbySharingServiceImpl::Open(const ShareTarget& share_target,
std::move(status_codes_callback).Run(StatusCodes::kOk);
}
void NearbySharingServiceImpl::OpenURL(GURL url) {
DCHECK(profile_);
chrome::ScopedTabbedBrowserDisplayer displayer(profile_);
chrome::AddSelectedTabWithURL(displayer.browser(), url,
ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
}
NearbyNotificationDelegate* NearbySharingServiceImpl::GetNotificationDelegate(
const std::string& notification_id) {
if (!nearby_notification_manager_)
......
......@@ -103,6 +103,7 @@ class NearbySharingServiceImpl
StatusCodesCallback status_codes_callback) override;
void Open(const ShareTarget& share_target,
StatusCodesCallback status_codes_callback) override;
void OpenURL(GURL url) override;
NearbyNotificationDelegate* GetNotificationDelegate(
const std::string& notification_id) override;
NearbyShareSettings* GetSettings() override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment