[SysUi download integration] Add "copy to clipboard" button
This CL adds a notification button to copy the download image to clipboard if the image download has completed. A demo has been attached to the issue. Bug: b/326122967 Change-Id: I4d035757bdea75a00941cab1c16a9d5ca2eb435e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5310539 Commit-Queue: Andrew Xu <andrewxu@chromium.org> Reviewed-by: David Black <dmblack@google.com> Cr-Commit-Position: refs/heads/main@{#1265967}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
178307719b
commit
f7c36899ec
ash
chrome/browser/ui/ash/download_status
display_manager.ccdisplay_metadata.hdisplay_test_util.ccdisplay_test_util.hholding_space_display_client.ccholding_space_display_client_browsertest.ccnotification_display_client.ccnotification_display_client_browsertest.cc
tools/metrics/actions
@@ -7680,6 +7680,9 @@ To shut down the device, press and hold the power button on the device again.
|
|||||||
<message name="IDS_ASH_DOWNLOAD_COMMAND_TEXT_CANCEL" desc="Text of the command to cancel a download.">
|
<message name="IDS_ASH_DOWNLOAD_COMMAND_TEXT_CANCEL" desc="Text of the command to cancel a download.">
|
||||||
Cancel
|
Cancel
|
||||||
</message>
|
</message>
|
||||||
|
<message name="IDS_ASH_DOWNLOAD_COMMAND_TEXT_COPY_TO_CLIPBOARD" desc="Text of the command to copy the download file to clipboard.">
|
||||||
|
Copy to clipboard
|
||||||
|
</message>
|
||||||
<message name="IDS_ASH_DOWNLOAD_COMMAND_TEXT_PAUSE" desc="Text of the command to pause a download.">
|
<message name="IDS_ASH_DOWNLOAD_COMMAND_TEXT_PAUSE" desc="Text of the command to pause a download.">
|
||||||
Pause
|
Pause
|
||||||
</message>
|
</message>
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
78af3668f6d2945de8f98d57b602be639ddb81e8
|
@@ -25,6 +25,12 @@
|
|||||||
#include "chrome/browser/ui/ash/download_status/notification_display_client.h"
|
#include "chrome/browser/ui/ash/download_status/notification_display_client.h"
|
||||||
#include "chromeos/crosapi/mojom/download_controller.mojom.h"
|
#include "chromeos/crosapi/mojom/download_controller.mojom.h"
|
||||||
#include "chromeos/crosapi/mojom/download_status_updater.mojom.h"
|
#include "chromeos/crosapi/mojom/download_status_updater.mojom.h"
|
||||||
|
#include "net/base/mime_util.h"
|
||||||
|
#include "third_party/blink/public/common/mime_util/mime_util.h"
|
||||||
|
#include "ui/base/clipboard/clipboard_buffer.h"
|
||||||
|
#include "ui/base/clipboard/file_info.h"
|
||||||
|
#include "ui/base/clipboard/scoped_clipboard_writer.h"
|
||||||
|
#include "ui/gfx/image/image_skia.h"
|
||||||
|
|
||||||
namespace ash::download_status {
|
namespace ash::download_status {
|
||||||
|
|
||||||
@@ -134,6 +140,15 @@ std::optional<std::u16string> GetText(
|
|||||||
return file_path.get().BaseName().LossyDisplayName();
|
return file_path.get().BaseName().LossyDisplayName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if the file referred to by `file_path` is of an image MIME type.
|
||||||
|
bool HasSupportedImageMimeType(const base::FilePath& file_path) {
|
||||||
|
std::string mime_type;
|
||||||
|
if (net::GetMimeTypeFromFile(file_path, &mime_type)) {
|
||||||
|
return blink::IsSupportedImageMimeType(mime_type);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Opens the download file specified by `file_path` under the file system
|
// Opens the download file specified by `file_path` under the file system
|
||||||
// associated with `profile`.
|
// associated with `profile`.
|
||||||
void OpenFile(Profile* profile, const base::FilePath& file_path) {
|
void OpenFile(Profile* profile, const base::FilePath& file_path) {
|
||||||
@@ -240,22 +255,38 @@ DisplayMetadata DisplayManager::CalculateDisplayMetadata(
|
|||||||
&kResumeIcon, IDS_ASH_DOWNLOAD_COMMAND_TEXT_RESUME,
|
&kResumeIcon, IDS_ASH_DOWNLOAD_COMMAND_TEXT_RESUME,
|
||||||
CommandType::kResume);
|
CommandType::kResume);
|
||||||
}
|
}
|
||||||
|
const base::FilePath& full_path = *download_status.full_path;
|
||||||
switch (download_status.state) {
|
switch (download_status.state) {
|
||||||
case crosapi::mojom::DownloadState::kComplete:
|
case crosapi::mojom::DownloadState::kComplete:
|
||||||
// NOTE: `kOpenFile` is not shown so it doesn't require an icon/text_id.
|
// NOTE: `kOpenFile` is not shown so it doesn't require an icon/text_id.
|
||||||
command_infos.emplace_back(
|
command_infos.emplace_back(
|
||||||
base::BindRepeating(
|
base::BindRepeating(&DisplayManager::PerformCommand,
|
||||||
&DisplayManager::PerformCommand, weak_ptr_factory_.GetWeakPtr(),
|
weak_ptr_factory_.GetWeakPtr(),
|
||||||
CommandType::kOpenFile, *download_status.full_path),
|
CommandType::kOpenFile, full_path),
|
||||||
/*icon=*/nullptr, /*text_id=*/-1, CommandType::kOpenFile);
|
/*icon=*/nullptr, /*text_id=*/-1, CommandType::kOpenFile);
|
||||||
|
|
||||||
// NOTE: The `kShowInFolder` button does not have an icon.
|
// NOTE: The `kShowInFolder` button does not have an icon.
|
||||||
command_infos.emplace_back(
|
command_infos.emplace_back(
|
||||||
base::BindRepeating(
|
base::BindRepeating(&DisplayManager::PerformCommand,
|
||||||
&DisplayManager::PerformCommand, weak_ptr_factory_.GetWeakPtr(),
|
weak_ptr_factory_.GetWeakPtr(),
|
||||||
CommandType::kShowInFolder, *download_status.full_path),
|
CommandType::kShowInFolder, full_path),
|
||||||
/*icon=*/nullptr, IDS_ASH_DOWNLOAD_COMMAND_TEXT_SHOW_IN_FOLDER,
|
/*icon=*/nullptr, IDS_ASH_DOWNLOAD_COMMAND_TEXT_SHOW_IN_FOLDER,
|
||||||
CommandType::kShowInFolder);
|
CommandType::kShowInFolder);
|
||||||
|
|
||||||
|
// Add a command to copy the download file to clipboard if:
|
||||||
|
// 1. `download_status` has a valid image; AND
|
||||||
|
// 2. The download file is an image.
|
||||||
|
// NOTE: The `kCopyToClipboard` button does not require an icon.
|
||||||
|
if (const gfx::ImageSkia& image = download_status.image;
|
||||||
|
!image.isNull() && !image.size().IsEmpty() &&
|
||||||
|
HasSupportedImageMimeType(full_path)) {
|
||||||
|
command_infos.emplace_back(
|
||||||
|
base::BindRepeating(&DisplayManager::PerformCommand,
|
||||||
|
weak_ptr_factory_.GetWeakPtr(),
|
||||||
|
CommandType::kCopyToClipboard, full_path),
|
||||||
|
/*icon=*/nullptr, IDS_ASH_DOWNLOAD_COMMAND_TEXT_COPY_TO_CLIPBOARD,
|
||||||
|
CommandType::kCopyToClipboard);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case crosapi::mojom::DownloadState::kInProgress:
|
case crosapi::mojom::DownloadState::kInProgress:
|
||||||
// NOTE: `kShowInBrowser` is not shown so doesn't require an icon/text_id.
|
// NOTE: `kShowInBrowser` is not shown so doesn't require an icon/text_id.
|
||||||
@@ -284,7 +315,7 @@ DisplayMetadata DisplayManager::CalculateDisplayMetadata(
|
|||||||
}
|
}
|
||||||
display_metadata.command_infos = std::move(command_infos);
|
display_metadata.command_infos = std::move(command_infos);
|
||||||
|
|
||||||
display_metadata.file_path = *download_status.full_path;
|
display_metadata.file_path = full_path;
|
||||||
display_metadata.image = download_status.image;
|
display_metadata.image = download_status.image;
|
||||||
display_metadata.progress = GetProgress(download_status);
|
display_metadata.progress = GetProgress(download_status);
|
||||||
display_metadata.secondary_text = download_status.status_text;
|
display_metadata.secondary_text = download_status.status_text;
|
||||||
@@ -301,6 +332,13 @@ void DisplayManager::PerformCommand(
|
|||||||
download_status_updater_->Cancel(/*guid=*/std::get<std::string>(param),
|
download_status_updater_->Cancel(/*guid=*/std::get<std::string>(param),
|
||||||
/*callback=*/base::DoNothing());
|
/*callback=*/base::DoNothing());
|
||||||
break;
|
break;
|
||||||
|
case CommandType::kCopyToClipboard: {
|
||||||
|
ui::ScopedClipboardWriter scw(ui::ClipboardBuffer::kCopyPaste);
|
||||||
|
scw.WriteFilenames(ui::FileInfosToURIList(
|
||||||
|
/*filenames=*/{ui::FileInfo(std::get<base::FilePath>(param),
|
||||||
|
/*display_name=*/base::FilePath())}));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CommandType::kOpenFile:
|
case CommandType::kOpenFile:
|
||||||
OpenFile(profile_, std::get<base::FilePath>(param));
|
OpenFile(profile_, std::get<base::FilePath>(param));
|
||||||
break;
|
break;
|
||||||
|
@@ -22,6 +22,7 @@ namespace ash::download_status {
|
|||||||
// Lists the types of commands that can be performed on a displayed download.
|
// Lists the types of commands that can be performed on a displayed download.
|
||||||
enum class CommandType {
|
enum class CommandType {
|
||||||
kCancel,
|
kCancel,
|
||||||
|
kCopyToClipboard,
|
||||||
kOpenFile,
|
kOpenFile,
|
||||||
kPause,
|
kPause,
|
||||||
kResume,
|
kResume,
|
||||||
|
@@ -22,11 +22,12 @@ constexpr int64_t kUnknownTotalBytes = -1;
|
|||||||
|
|
||||||
crosapi::mojom::DownloadStatusPtr CreateDownloadStatus(
|
crosapi::mojom::DownloadStatusPtr CreateDownloadStatus(
|
||||||
Profile* profile,
|
Profile* profile,
|
||||||
|
std::string_view extension,
|
||||||
crosapi::mojom::DownloadState state,
|
crosapi::mojom::DownloadState state,
|
||||||
crosapi::mojom::DownloadProgressPtr progress) {
|
crosapi::mojom::DownloadProgressPtr progress) {
|
||||||
crosapi::mojom::DownloadStatusPtr download_status =
|
crosapi::mojom::DownloadStatusPtr download_status =
|
||||||
crosapi::mojom::DownloadStatus::New();
|
crosapi::mojom::DownloadStatus::New();
|
||||||
download_status->full_path = test::CreateFile(profile);
|
download_status->full_path = test::CreateFile(profile, extension);
|
||||||
download_status->guid = base::UnguessableToken::Create().ToString();
|
download_status->guid = base::UnguessableToken::Create().ToString();
|
||||||
download_status->progress = std::move(progress);
|
download_status->progress = std::move(progress);
|
||||||
download_status->state = state;
|
download_status->state = state;
|
||||||
@@ -36,10 +37,11 @@ crosapi::mojom::DownloadStatusPtr CreateDownloadStatus(
|
|||||||
|
|
||||||
crosapi::mojom::DownloadStatusPtr CreateInProgressDownloadStatus(
|
crosapi::mojom::DownloadStatusPtr CreateInProgressDownloadStatus(
|
||||||
Profile* profile,
|
Profile* profile,
|
||||||
|
std::string_view extension,
|
||||||
int64_t received_bytes,
|
int64_t received_bytes,
|
||||||
const std::optional<int64_t>& total_bytes) {
|
const std::optional<int64_t>& total_bytes) {
|
||||||
return CreateDownloadStatus(
|
return CreateDownloadStatus(
|
||||||
profile, crosapi::mojom::DownloadState::kInProgress,
|
profile, extension, crosapi::mojom::DownloadState::kInProgress,
|
||||||
crosapi::mojom::DownloadProgress::New(
|
crosapi::mojom::DownloadProgress::New(
|
||||||
/*loop=*/false, received_bytes,
|
/*loop=*/false, received_bytes,
|
||||||
total_bytes.value_or(kUnknownTotalBytes), /*visible=*/true));
|
total_bytes.value_or(kUnknownTotalBytes), /*visible=*/true));
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
#define CHROME_BROWSER_UI_ASH_DOWNLOAD_STATUS_DISPLAY_TEST_UTIL_H_
|
#define CHROME_BROWSER_UI_ASH_DOWNLOAD_STATUS_DISPLAY_TEST_UTIL_H_
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
#include "chromeos/crosapi/mojom/download_status_updater.mojom.h"
|
#include "chromeos/crosapi/mojom/download_status_updater.mojom.h"
|
||||||
|
|
||||||
@@ -13,10 +14,11 @@ class Profile;
|
|||||||
|
|
||||||
namespace ash::download_status {
|
namespace ash::download_status {
|
||||||
|
|
||||||
// Creates a download status associated with a file under the downloads
|
// Creates a download status associated with a file with the specified
|
||||||
// directory of `profile`.
|
// `extension` under the downloads directory of `profile`.
|
||||||
crosapi::mojom::DownloadStatusPtr CreateDownloadStatus(
|
crosapi::mojom::DownloadStatusPtr CreateDownloadStatus(
|
||||||
Profile* profile,
|
Profile* profile,
|
||||||
|
std::string_view extension,
|
||||||
crosapi::mojom::DownloadState state,
|
crosapi::mojom::DownloadState state,
|
||||||
crosapi::mojom::DownloadProgressPtr progress);
|
crosapi::mojom::DownloadProgressPtr progress);
|
||||||
|
|
||||||
@@ -24,6 +26,7 @@ crosapi::mojom::DownloadStatusPtr CreateDownloadStatus(
|
|||||||
// with a file under the downloads directory of `profile`.
|
// with a file under the downloads directory of `profile`.
|
||||||
crosapi::mojom::DownloadStatusPtr CreateInProgressDownloadStatus(
|
crosapi::mojom::DownloadStatusPtr CreateInProgressDownloadStatus(
|
||||||
Profile* profile,
|
Profile* profile,
|
||||||
|
std::string_view extension,
|
||||||
int64_t received_bytes,
|
int64_t received_bytes,
|
||||||
const std::optional<int64_t>& total_bytes = std::nullopt);
|
const std::optional<int64_t>& total_bytes = std::nullopt);
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "chrome/browser/ui/ash/download_status/holding_space_display_client.h"
|
#include "chrome/browser/ui/ash/download_status/holding_space_display_client.h"
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -28,14 +29,17 @@ namespace ash::download_status {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Returns the command ID corresponding to the given command type.
|
// Returns the command ID corresponding to the given command type if any. If
|
||||||
|
// there is no such command ID, returns `std::nullopt`.
|
||||||
// NOTE: It is fine to map both `CommandType::kOpenFile` and
|
// NOTE: It is fine to map both `CommandType::kOpenFile` and
|
||||||
// `CommandType::kShowInBrowser` to `kOpenItem`, because `kOpenItem` is not
|
// `CommandType::kShowInBrowser` to `kOpenItem`, because `kOpenItem` is not
|
||||||
// accessible from a holding space chip's context menu.
|
// accessible from a holding space chip's context menu.
|
||||||
HoldingSpaceCommandId ConvertCommandTypeToId(CommandType type) {
|
std::optional<HoldingSpaceCommandId> ConvertCommandTypeToId(CommandType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case CommandType::kCancel:
|
case CommandType::kCancel:
|
||||||
return HoldingSpaceCommandId::kCancelItem;
|
return HoldingSpaceCommandId::kCancelItem;
|
||||||
|
case CommandType::kCopyToClipboard:
|
||||||
|
return std::nullopt;
|
||||||
case CommandType::kOpenFile:
|
case CommandType::kOpenFile:
|
||||||
return HoldingSpaceCommandId::kOpenItem;
|
return HoldingSpaceCommandId::kOpenItem;
|
||||||
case CommandType::kPause:
|
case CommandType::kPause:
|
||||||
@@ -51,12 +55,16 @@ HoldingSpaceCommandId ConvertCommandTypeToId(CommandType type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the holding space item action corresponding to `type`.
|
// Returns the holding space item action corresponding to `type` if any. If
|
||||||
holding_space_metrics::ItemAction ConvertCommandTypeToAction(CommandType type) {
|
// there is no such action, returns `std::nullopt`.
|
||||||
|
std::optional<holding_space_metrics::ItemAction> ConvertCommandTypeToAction(
|
||||||
|
CommandType type) {
|
||||||
using ItemAction = holding_space_metrics::ItemAction;
|
using ItemAction = holding_space_metrics::ItemAction;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case CommandType::kCancel:
|
case CommandType::kCancel:
|
||||||
return ItemAction::kCancel;
|
return ItemAction::kCancel;
|
||||||
|
case CommandType::kCopyToClipboard:
|
||||||
|
return std::nullopt;
|
||||||
case CommandType::kOpenFile:
|
case CommandType::kOpenFile:
|
||||||
return ItemAction::kLaunch;
|
return ItemAction::kLaunch;
|
||||||
case CommandType::kPause:
|
case CommandType::kPause:
|
||||||
@@ -121,23 +129,31 @@ void HoldingSpaceDisplayClient::AddOrUpdate(
|
|||||||
// Generate in-progress commands from `display_metadata`.
|
// Generate in-progress commands from `display_metadata`.
|
||||||
std::vector<HoldingSpaceItem::InProgressCommand> in_progress_commands;
|
std::vector<HoldingSpaceItem::InProgressCommand> in_progress_commands;
|
||||||
for (const auto& command_info : display_metadata.command_infos) {
|
for (const auto& command_info : display_metadata.command_infos) {
|
||||||
if (const HoldingSpaceCommandId id =
|
const std::optional<HoldingSpaceCommandId> id =
|
||||||
ConvertCommandTypeToId(command_info.type);
|
ConvertCommandTypeToId(command_info.type);
|
||||||
holding_space_util::IsInProgressCommand(id)) {
|
const std::optional<holding_space_metrics::ItemAction> item_action =
|
||||||
in_progress_commands.emplace_back(
|
ConvertCommandTypeToAction(command_info.type);
|
||||||
id, command_info.text_id, command_info.icon,
|
|
||||||
base::BindRepeating(
|
// Skip `command_info` if:
|
||||||
[](holding_space_metrics::ItemAction action,
|
// 1. It does not have a corresponding ID; OR
|
||||||
const base::RepeatingClosure& command_callback,
|
// 2. Its corresponding ID is not for an in-progress command; OR
|
||||||
const HoldingSpaceItem* item, HoldingSpaceCommandId command_id,
|
// 3. It does not have a corresponding item action.
|
||||||
holding_space_metrics::EventSource event_source) {
|
if (!id || !holding_space_util::IsInProgressCommand(*id) || !item_action) {
|
||||||
command_callback.Run();
|
continue;
|
||||||
holding_space_metrics::RecordItemAction(
|
|
||||||
/*items=*/{item}, action, event_source);
|
|
||||||
},
|
|
||||||
ConvertCommandTypeToAction(command_info.type),
|
|
||||||
command_info.command_callback));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
in_progress_commands.emplace_back(
|
||||||
|
*id, command_info.text_id, command_info.icon,
|
||||||
|
base::BindRepeating(
|
||||||
|
[](holding_space_metrics::ItemAction action,
|
||||||
|
const base::RepeatingClosure& command_callback,
|
||||||
|
const HoldingSpaceItem* item, HoldingSpaceCommandId command_id,
|
||||||
|
holding_space_metrics::EventSource event_source) {
|
||||||
|
command_callback.Run();
|
||||||
|
holding_space_metrics::RecordItemAction(
|
||||||
|
/*items=*/{item}, action, event_source);
|
||||||
|
},
|
||||||
|
*item_action, command_info.command_callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specify the backing file.
|
// Specify the backing file.
|
||||||
|
@@ -137,17 +137,18 @@ IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest,
|
|||||||
Profile* const profile = ProfileManager::GetActiveUserProfile();
|
Profile* const profile = ProfileManager::GetActiveUserProfile();
|
||||||
crosapi::mojom::DownloadStatusPtr in_progress_download =
|
crosapi::mojom::DownloadStatusPtr in_progress_download =
|
||||||
CreateInProgressDownloadStatus(profile,
|
CreateInProgressDownloadStatus(profile,
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
in_progress_download->cancellable = true;
|
in_progress_download->cancellable = true;
|
||||||
Update(in_progress_download->Clone());
|
Update(in_progress_download->Clone());
|
||||||
crosapi::mojom::DownloadStatusPtr completed_download =
|
crosapi::mojom::DownloadStatusPtr completed_download = CreateDownloadStatus(
|
||||||
CreateDownloadStatus(profile, crosapi::mojom::DownloadState::kComplete,
|
profile, /*extension=*/"txt", crosapi::mojom::DownloadState::kComplete,
|
||||||
crosapi::mojom::DownloadProgress::New(
|
crosapi::mojom::DownloadProgress::New(
|
||||||
/*loop=*/false,
|
/*loop=*/false,
|
||||||
/*received_bytes=*/1024,
|
/*received_bytes=*/1024,
|
||||||
/*total_bytes=*/1024,
|
/*total_bytes=*/1024,
|
||||||
/*visible=*/false));
|
/*visible=*/false));
|
||||||
Update(completed_download->Clone());
|
Update(completed_download->Clone());
|
||||||
test_api().Show();
|
test_api().Show();
|
||||||
|
|
||||||
@@ -258,12 +259,13 @@ IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest,
|
|||||||
Profile* const profile = ProfileManager::GetActiveUserProfile();
|
Profile* const profile = ProfileManager::GetActiveUserProfile();
|
||||||
crosapi::mojom::DownloadStatusPtr in_progress_download =
|
crosapi::mojom::DownloadStatusPtr in_progress_download =
|
||||||
CreateInProgressDownloadStatus(profile,
|
CreateInProgressDownloadStatus(profile,
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
in_progress_download->cancellable = true;
|
in_progress_download->cancellable = true;
|
||||||
Update(in_progress_download->Clone());
|
Update(in_progress_download->Clone());
|
||||||
crosapi::mojom::DownloadStatusPtr completed_download = CreateDownloadStatus(
|
crosapi::mojom::DownloadStatusPtr completed_download = CreateDownloadStatus(
|
||||||
profile, crosapi::mojom::DownloadState::kComplete,
|
profile, /*extension=*/"txt", crosapi::mojom::DownloadState::kComplete,
|
||||||
crosapi::mojom::DownloadProgress::New(
|
crosapi::mojom::DownloadProgress::New(
|
||||||
/*loop=*/false,
|
/*loop=*/false,
|
||||||
/*received_bytes=*/1024, /*total_bytes=*/1024, /*visible=*/false));
|
/*received_bytes=*/1024, /*total_bytes=*/1024, /*visible=*/false));
|
||||||
@@ -367,14 +369,14 @@ IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest,
|
|||||||
IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest,
|
IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest,
|
||||||
ClickCompletedDownloadChip) {
|
ClickCompletedDownloadChip) {
|
||||||
// Add a completed download.
|
// Add a completed download.
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download = CreateDownloadStatus(
|
||||||
CreateDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
ProfileManager::GetActiveUserProfile(),
|
||||||
crosapi::mojom::DownloadState::kComplete,
|
/*extension=*/"txt", crosapi::mojom::DownloadState::kComplete,
|
||||||
crosapi::mojom::DownloadProgress::New(
|
crosapi::mojom::DownloadProgress::New(
|
||||||
/*loop=*/false,
|
/*loop=*/false,
|
||||||
/*received_bytes=*/1024,
|
/*received_bytes=*/1024,
|
||||||
/*total_bytes=*/1024,
|
/*total_bytes=*/1024,
|
||||||
/*visible=*/false));
|
/*visible=*/false));
|
||||||
Update(download->Clone());
|
Update(download->Clone());
|
||||||
test_api().Show();
|
test_api().Show();
|
||||||
|
|
||||||
@@ -416,6 +418,7 @@ IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest,
|
|||||||
// Add an in-progress download.
|
// Add an in-progress download.
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
Update(download->Clone());
|
Update(download->Clone());
|
||||||
@@ -456,6 +459,7 @@ IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest, CompleteDownload) {
|
|||||||
Profile* const active_profile = ProfileManager::GetActiveUserProfile();
|
Profile* const active_profile = ProfileManager::GetActiveUserProfile();
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
CreateInProgressDownloadStatus(active_profile,
|
CreateInProgressDownloadStatus(active_profile,
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
Update(download->Clone());
|
Update(download->Clone());
|
||||||
@@ -535,6 +539,7 @@ IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest, CompleteDownload) {
|
|||||||
// Add a new in-progress download with the duplicate download guid.
|
// Add a new in-progress download with the duplicate download guid.
|
||||||
crosapi::mojom::DownloadStatusPtr duplicate_download =
|
crosapi::mojom::DownloadStatusPtr duplicate_download =
|
||||||
CreateInProgressDownloadStatus(active_profile,
|
CreateInProgressDownloadStatus(active_profile,
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
duplicate_download->guid = download->guid;
|
duplicate_download->guid = download->guid;
|
||||||
@@ -548,8 +553,9 @@ IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest, CompleteDownload) {
|
|||||||
IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest,
|
IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest,
|
||||||
IndeterminateDownload) {
|
IndeterminateDownload) {
|
||||||
// Create a download with an unknown total bytes count.
|
// Create a download with an unknown total bytes count.
|
||||||
crosapi::mojom::DownloadStatusPtr download = CreateInProgressDownloadStatus(
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
ProfileManager::GetActiveUserProfile(), /*received_bytes=*/0);
|
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
||||||
|
/*extension=*/"txt", /*received_bytes=*/0);
|
||||||
Update(download->Clone());
|
Update(download->Clone());
|
||||||
test_api().Show();
|
test_api().Show();
|
||||||
|
|
||||||
@@ -568,6 +574,7 @@ IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest,
|
|||||||
// could happen when a download is blocked.
|
// could happen when a download is blocked.
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
download->progress->visible = false;
|
download->progress->visible = false;
|
||||||
@@ -592,6 +599,7 @@ IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest,
|
|||||||
InterruptDownload) {
|
InterruptDownload) {
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
Update(download->Clone());
|
Update(download->Clone());
|
||||||
@@ -610,6 +618,7 @@ IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest,
|
|||||||
PauseAndResumeDownloadViaContextMenu) {
|
PauseAndResumeDownloadViaContextMenu) {
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
download->pausable = true;
|
download->pausable = true;
|
||||||
@@ -689,6 +698,7 @@ IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest,
|
|||||||
PauseAndResumeDownloadViaSecondaryAction) {
|
PauseAndResumeDownloadViaSecondaryAction) {
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
download->pausable = true;
|
download->pausable = true;
|
||||||
@@ -773,6 +783,7 @@ IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest,
|
|||||||
IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest, SecondaryLabel) {
|
IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest, SecondaryLabel) {
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
Update(download->Clone());
|
Update(download->Clone());
|
||||||
@@ -806,6 +817,7 @@ IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest,
|
|||||||
ServiceSuspendedDuringDownload) {
|
ServiceSuspendedDuringDownload) {
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
Update(download->Clone());
|
Update(download->Clone());
|
||||||
@@ -849,6 +861,7 @@ IN_PROC_BROWSER_TEST_F(HoldingSpaceDisplayClientBrowserTest,
|
|||||||
// Create an in-progress download that can be canceled and paused.
|
// Create an in-progress download that can be canceled and paused.
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
download->cancellable = true;
|
download->cancellable = true;
|
||||||
|
@@ -144,6 +144,8 @@ const char* GetMetricString(CommandType command) {
|
|||||||
switch (command) {
|
switch (command) {
|
||||||
case CommandType::kCancel:
|
case CommandType::kCancel:
|
||||||
return "DownloadNotificationV2.Button_Cancel";
|
return "DownloadNotificationV2.Button_Cancel";
|
||||||
|
case CommandType::kCopyToClipboard:
|
||||||
|
return "DownloadNotificationV2.Button_CopyToClipboard";
|
||||||
case CommandType::kOpenFile:
|
case CommandType::kOpenFile:
|
||||||
return "DownloadNotificationV2.Click_Completed";
|
return "DownloadNotificationV2.Click_Completed";
|
||||||
case CommandType::kPause:
|
case CommandType::kPause:
|
||||||
@@ -167,6 +169,7 @@ bool IsBodyClickCommandType(CommandType command) {
|
|||||||
case CommandType::kShowInBrowser:
|
case CommandType::kShowInBrowser:
|
||||||
return true;
|
return true;
|
||||||
case CommandType::kCancel:
|
case CommandType::kCancel:
|
||||||
|
case CommandType::kCopyToClipboard:
|
||||||
case CommandType::kPause:
|
case CommandType::kPause:
|
||||||
case CommandType::kResume:
|
case CommandType::kResume:
|
||||||
case CommandType::kShowInFolder:
|
case CommandType::kShowInFolder:
|
||||||
@@ -180,6 +183,7 @@ bool IsBodyClickCommandType(CommandType command) {
|
|||||||
bool IsButtonClickCommandType(CommandType command) {
|
bool IsButtonClickCommandType(CommandType command) {
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case CommandType::kCancel:
|
case CommandType::kCancel:
|
||||||
|
case CommandType::kCopyToClipboard:
|
||||||
case CommandType::kPause:
|
case CommandType::kPause:
|
||||||
case CommandType::kResume:
|
case CommandType::kResume:
|
||||||
case CommandType::kShowInFolder:
|
case CommandType::kShowInFolder:
|
||||||
|
@@ -53,6 +53,8 @@
|
|||||||
#include "ui/aura/env_observer.h"
|
#include "ui/aura/env_observer.h"
|
||||||
#include "ui/aura/test/find_window.h"
|
#include "ui/aura/test/find_window.h"
|
||||||
#include "ui/aura/window.h"
|
#include "ui/aura/window.h"
|
||||||
|
#include "ui/base/clipboard/clipboard.h"
|
||||||
|
#include "ui/base/clipboard/clipboard_buffer.h"
|
||||||
#include "ui/base/l10n/l10n_util.h"
|
#include "ui/base/l10n/l10n_util.h"
|
||||||
#include "ui/gfx/image/image_unittest_util.h"
|
#include "ui/gfx/image/image_unittest_util.h"
|
||||||
#include "ui/message_center/public/cpp/notification.h"
|
#include "ui/message_center/public/cpp/notification.h"
|
||||||
@@ -75,7 +77,9 @@ using ::testing::_;
|
|||||||
using ::testing::AllOf;
|
using ::testing::AllOf;
|
||||||
using ::testing::Contains;
|
using ::testing::Contains;
|
||||||
using ::testing::Each;
|
using ::testing::Each;
|
||||||
|
using ::testing::ElementsAre;
|
||||||
using ::testing::Eq;
|
using ::testing::Eq;
|
||||||
|
using ::testing::Field;
|
||||||
using ::testing::Mock;
|
using ::testing::Mock;
|
||||||
using ::testing::NiceMock;
|
using ::testing::NiceMock;
|
||||||
using ::testing::Not;
|
using ::testing::Not;
|
||||||
@@ -123,6 +127,8 @@ int GetCommandTextId(CommandType command_type) {
|
|||||||
switch (command_type) {
|
switch (command_type) {
|
||||||
case CommandType::kCancel:
|
case CommandType::kCancel:
|
||||||
return IDS_ASH_DOWNLOAD_COMMAND_TEXT_CANCEL;
|
return IDS_ASH_DOWNLOAD_COMMAND_TEXT_CANCEL;
|
||||||
|
case CommandType::kCopyToClipboard:
|
||||||
|
return IDS_ASH_DOWNLOAD_COMMAND_TEXT_COPY_TO_CLIPBOARD;
|
||||||
case CommandType::kOpenFile:
|
case CommandType::kOpenFile:
|
||||||
NOTREACHED_NORETURN();
|
NOTREACHED_NORETURN();
|
||||||
case CommandType::kPause:
|
case CommandType::kPause:
|
||||||
@@ -251,6 +257,7 @@ IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest, CancelDownload) {
|
|||||||
}));
|
}));
|
||||||
crosapi::mojom::DownloadStatusPtr uncancellable_download =
|
crosapi::mojom::DownloadStatusPtr uncancellable_download =
|
||||||
CreateInProgressDownloadStatus(profile,
|
CreateInProgressDownloadStatus(profile,
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
uncancellable_download->cancellable = false;
|
uncancellable_download->cancellable = false;
|
||||||
@@ -278,6 +285,7 @@ IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest, CancelDownload) {
|
|||||||
}));
|
}));
|
||||||
crosapi::mojom::DownloadStatusPtr cancellable_download =
|
crosapi::mojom::DownloadStatusPtr cancellable_download =
|
||||||
CreateInProgressDownloadStatus(profile,
|
CreateInProgressDownloadStatus(profile,
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
cancellable_download->cancellable = true;
|
cancellable_download->cancellable = true;
|
||||||
@@ -335,13 +343,13 @@ IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest,
|
|||||||
[¬ification_id](const message_center::Notification& notification) {
|
[¬ification_id](const message_center::Notification& notification) {
|
||||||
notification_id = notification.id();
|
notification_id = notification.id();
|
||||||
}));
|
}));
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download = CreateDownloadStatus(
|
||||||
CreateDownloadStatus(profile, crosapi::mojom::DownloadState::kComplete,
|
profile, /*extension=*/"txt", crosapi::mojom::DownloadState::kComplete,
|
||||||
crosapi::mojom::DownloadProgress::New(
|
crosapi::mojom::DownloadProgress::New(
|
||||||
/*loop=*/false,
|
/*loop=*/false,
|
||||||
/*received_bytes=*/1024,
|
/*received_bytes=*/1024,
|
||||||
/*total_bytes=*/1024,
|
/*total_bytes=*/1024,
|
||||||
/*visible=*/false));
|
/*visible=*/false));
|
||||||
Update(download->Clone());
|
Update(download->Clone());
|
||||||
Mock::VerifyAndClearExpectations(&service_observer());
|
Mock::VerifyAndClearExpectations(&service_observer());
|
||||||
|
|
||||||
@@ -384,6 +392,7 @@ IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest,
|
|||||||
}));
|
}));
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
CreateInProgressDownloadStatus(profile,
|
CreateInProgressDownloadStatus(profile,
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
Update(download->Clone());
|
Update(download->Clone());
|
||||||
@@ -418,9 +427,10 @@ IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest,
|
|||||||
// still show.
|
// still show.
|
||||||
IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest, CompleteDownload) {
|
IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest, CompleteDownload) {
|
||||||
Profile* const profile = ProfileManager::GetActiveUserProfile();
|
Profile* const profile = ProfileManager::GetActiveUserProfile();
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download = CreateDownloadStatus(
|
||||||
CreateDownloadStatus(profile, crosapi::mojom::DownloadState::kInProgress,
|
profile,
|
||||||
/*progress=*/nullptr);
|
/*extension=*/"txt", crosapi::mojom::DownloadState::kInProgress,
|
||||||
|
/*progress=*/nullptr);
|
||||||
EXPECT_FALSE(download->target_file_path);
|
EXPECT_FALSE(download->target_file_path);
|
||||||
std::string notification_id;
|
std::string notification_id;
|
||||||
|
|
||||||
@@ -544,6 +554,7 @@ IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest,
|
|||||||
Profile* const profile = ProfileManager::GetActiveUserProfile();
|
Profile* const profile = ProfileManager::GetActiveUserProfile();
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
CreateInProgressDownloadStatus(profile,
|
CreateInProgressDownloadStatus(profile,
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
Update(download->Clone());
|
Update(download->Clone());
|
||||||
@@ -580,12 +591,14 @@ IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest, ImageDownload) {
|
|||||||
notification_id = notification.id();
|
notification_id = notification.id();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Create a download.
|
// Create an image download.
|
||||||
Profile* const profile = ProfileManager::GetActiveUserProfile();
|
Profile* const profile = ProfileManager::GetActiveUserProfile();
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download = CreateDownloadStatus(
|
||||||
CreateInProgressDownloadStatus(profile,
|
profile,
|
||||||
/*received_bytes=*/0,
|
/*extension=*/"png", crosapi::mojom::DownloadState::kInProgress,
|
||||||
/*total_bytes=*/1024);
|
crosapi::mojom::DownloadProgress::New(
|
||||||
|
/*loop=*/false, /*received_bytes=*/0,
|
||||||
|
/*total_bytes=*/1024, /*visible=*/true));
|
||||||
Update(download->Clone());
|
Update(download->Clone());
|
||||||
Mock::VerifyAndClearExpectations(&service_observer());
|
Mock::VerifyAndClearExpectations(&service_observer());
|
||||||
|
|
||||||
@@ -614,6 +627,49 @@ IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest, ImageDownload) {
|
|||||||
*large_image_view->original_image().bitmap(),
|
*large_image_view->original_image().bitmap(),
|
||||||
gfx::test::CreateBitmap(/*width=*/360,
|
gfx::test::CreateBitmap(/*width=*/360,
|
||||||
/*height=*/240, image_color)));
|
/*height=*/240, image_color)));
|
||||||
|
|
||||||
|
// An in-progress image download's notification should not have a 'Copy to
|
||||||
|
// clipboard' button.
|
||||||
|
const std::u16string copy_to_clipboard_button_text =
|
||||||
|
l10n_util::GetStringUTF16(
|
||||||
|
GetCommandTextId(CommandType::kCopyToClipboard));
|
||||||
|
EXPECT_THAT(
|
||||||
|
popup_view->GetActionButtonsForTest(),
|
||||||
|
Not(Contains(Pointee(Property(&views::LabelButton::GetText,
|
||||||
|
Eq(copy_to_clipboard_button_text))))));
|
||||||
|
|
||||||
|
// Complete `download`. Then check action buttons.
|
||||||
|
MarkDownloadStatusCompleted(*download);
|
||||||
|
Update(download->Clone());
|
||||||
|
const std::vector<raw_ptr<views::LabelButton, VectorExperimental>>
|
||||||
|
action_buttons = popup_view->GetActionButtonsForTest();
|
||||||
|
EXPECT_THAT(
|
||||||
|
action_buttons,
|
||||||
|
ElementsAre(
|
||||||
|
Pointee(Property(&views::LabelButton::GetText,
|
||||||
|
Eq(l10n_util::GetStringUTF16(
|
||||||
|
GetCommandTextId(CommandType::kShowInFolder))))),
|
||||||
|
Pointee(Property(&views::LabelButton::GetText,
|
||||||
|
Eq(copy_to_clipboard_button_text)))));
|
||||||
|
|
||||||
|
// Click the 'Copy to clipboard' button. Then verify the click is recorded.
|
||||||
|
base::UserActionTester tester;
|
||||||
|
auto copy_to_clipboard_button_iter =
|
||||||
|
base::ranges::find(action_buttons, copy_to_clipboard_button_text,
|
||||||
|
&views::LabelButton::GetText);
|
||||||
|
ASSERT_NE(copy_to_clipboard_button_iter, action_buttons.cend());
|
||||||
|
test::Click(*copy_to_clipboard_button_iter, ui::EF_NONE);
|
||||||
|
EXPECT_EQ(
|
||||||
|
tester.GetActionCount("DownloadNotificationV2.Button_CopyToClipboard"),
|
||||||
|
1);
|
||||||
|
|
||||||
|
// Verify the filename in the clipboard as expected.
|
||||||
|
base::test::TestFuture<std::vector<ui::FileInfo>> test_future;
|
||||||
|
ui::Clipboard::GetForCurrentThread()->ReadFilenames(
|
||||||
|
ui::ClipboardBuffer::kCopyPaste,
|
||||||
|
/*data_dst=*/nullptr, test_future.GetCallback());
|
||||||
|
EXPECT_THAT(test_future.Get(),
|
||||||
|
ElementsAre(Field(&ui::FileInfo::path, *download->full_path)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verifies that the notification of a download with an unknown total bytes
|
// Verifies that the notification of a download with an unknown total bytes
|
||||||
@@ -630,6 +686,7 @@ IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest,
|
|||||||
Profile* const profile = ProfileManager::GetActiveUserProfile();
|
Profile* const profile = ProfileManager::GetActiveUserProfile();
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
CreateInProgressDownloadStatus(profile,
|
CreateInProgressDownloadStatus(profile,
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0);
|
/*received_bytes=*/0);
|
||||||
|
|
||||||
Update(download->Clone());
|
Update(download->Clone());
|
||||||
@@ -668,6 +725,7 @@ IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest,
|
|||||||
}));
|
}));
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
CreateInProgressDownloadStatus(ProfileManager::GetActiveUserProfile(),
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
Update(download->Clone());
|
Update(download->Clone());
|
||||||
@@ -691,6 +749,7 @@ IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest,
|
|||||||
}));
|
}));
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
CreateInProgressDownloadStatus(profile,
|
CreateInProgressDownloadStatus(profile,
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
download->pausable = true;
|
download->pausable = true;
|
||||||
@@ -803,6 +862,7 @@ IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest, ShowInFolder) {
|
|||||||
}));
|
}));
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
CreateInProgressDownloadStatus(profile,
|
CreateInProgressDownloadStatus(profile,
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
Update(download->Clone());
|
Update(download->Clone());
|
||||||
@@ -860,6 +920,7 @@ IN_PROC_BROWSER_TEST_F(NotificationDisplayClientBrowserTest,
|
|||||||
Profile* const profile = ProfileManager::GetActiveUserProfile();
|
Profile* const profile = ProfileManager::GetActiveUserProfile();
|
||||||
crosapi::mojom::DownloadStatusPtr download =
|
crosapi::mojom::DownloadStatusPtr download =
|
||||||
CreateInProgressDownloadStatus(profile,
|
CreateInProgressDownloadStatus(profile,
|
||||||
|
/*extension=*/"txt",
|
||||||
/*received_bytes=*/0,
|
/*received_bytes=*/0,
|
||||||
/*total_bytes=*/1024);
|
/*total_bytes=*/1024);
|
||||||
download->cancellable = true;
|
download->cancellable = true;
|
||||||
|
@@ -9512,6 +9512,15 @@ should be able to be added at any place in this file.
|
|||||||
</description>
|
</description>
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
|
<action name="DownloadNotificationV2.Button_CopyToClipboard">
|
||||||
|
<owner>andrewxu@chromium.org</owner>
|
||||||
|
<owner>cros-system-ui-productivity-eng@google.com</owner>
|
||||||
|
<description>
|
||||||
|
User clicks "Copy to clipboard" button on a download notification
|
||||||
|
with the downloads integration V2 feature enabled.
|
||||||
|
</description>
|
||||||
|
</action>
|
||||||
|
|
||||||
<action name="DownloadNotificationV2.Button_Pause">
|
<action name="DownloadNotificationV2.Button_Pause">
|
||||||
<owner>andrewxu@chromium.org</owner>
|
<owner>andrewxu@chromium.org</owner>
|
||||||
<owner>cros-system-ui-productivity-eng@google.com</owner>
|
<owner>cros-system-ui-productivity-eng@google.com</owner>
|
||||||
|
Reference in New Issue
Block a user