123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- // Copyright 2020 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/clipboard/clipboard_history_util.h"
- #include <array>
- #include "ash/clipboard/clipboard_history_item.h"
- #include "ash/metrics/histogram_macros.h"
- #include "ash/resources/vector_icons/vector_icons.h"
- #include "ash/session/session_controller_impl.h"
- #include "ash/shell.h"
- #include "ash/style/ash_color_provider.h"
- #include "ash/style/dark_light_mode_controller_impl.h"
- #include "base/files/file_path.h"
- #include "base/strings/string_split.h"
- #include "base/strings/utf_string_conversions.h"
- #include "chromeos/ui/base/file_icon_util.h"
- #include "ui/base/clipboard/clipboard_data.h"
- #include "ui/base/clipboard/custom_data_helper.h"
- #include "ui/gfx/paint_vector_icon.h"
- namespace ash {
- namespace ClipboardHistoryUtil {
- namespace {
- constexpr char16_t kFileSystemSourcesType[] = u"fs/sources";
- // The array of formats in order of decreasing priority.
- constexpr ui::ClipboardInternalFormat kPrioritizedFormats[] = {
- ui::ClipboardInternalFormat::kPng,
- ui::ClipboardInternalFormat::kHtml,
- ui::ClipboardInternalFormat::kText,
- ui::ClipboardInternalFormat::kRtf,
- ui::ClipboardInternalFormat::kFilenames,
- ui::ClipboardInternalFormat::kBookmark,
- ui::ClipboardInternalFormat::kWeb,
- ui::ClipboardInternalFormat::kCustom};
- } // namespace
- absl::optional<ui::ClipboardInternalFormat> CalculateMainFormat(
- const ui::ClipboardData& data) {
- for (const auto& format : kPrioritizedFormats) {
- if (ContainsFormat(data, format)) {
- return format;
- }
- }
- return absl::nullopt;
- }
- ClipboardHistoryDisplayFormat CalculateDisplayFormat(
- const ui::ClipboardData& data) {
- switch (CalculateMainFormat(data).value()) {
- case ui::ClipboardInternalFormat::kPng:
- return ClipboardHistoryDisplayFormat::kPng;
- case ui::ClipboardInternalFormat::kHtml:
- if ((data.markup_data().find("<img") == std::string::npos) &&
- (data.markup_data().find("<table") == std::string::npos)) {
- return ClipboardHistoryDisplayFormat::kText;
- }
- return ClipboardHistoryDisplayFormat::kHtml;
- case ui::ClipboardInternalFormat::kText:
- case ui::ClipboardInternalFormat::kSvg:
- case ui::ClipboardInternalFormat::kRtf:
- case ui::ClipboardInternalFormat::kBookmark:
- case ui::ClipboardInternalFormat::kWeb:
- return ClipboardHistoryDisplayFormat::kText;
- case ui::ClipboardInternalFormat::kFilenames:
- return ClipboardHistoryDisplayFormat::kFile;
- case ui::ClipboardInternalFormat::kCustom:
- return ContainsFileSystemData(data)
- ? ClipboardHistoryDisplayFormat::kFile
- : ClipboardHistoryDisplayFormat::kText;
- }
- }
- bool ContainsFormat(const ui::ClipboardData& data,
- ui::ClipboardInternalFormat format) {
- return data.format() & static_cast<int>(format);
- }
- void RecordClipboardHistoryItemDeleted(const ClipboardHistoryItem& item) {
- UMA_HISTOGRAM_ENUMERATION(
- "Ash.ClipboardHistory.ContextMenu.DisplayFormatDeleted",
- CalculateDisplayFormat(item.data()));
- }
- void RecordClipboardHistoryItemPasted(const ClipboardHistoryItem& item) {
- UMA_HISTOGRAM_ENUMERATION(
- "Ash.ClipboardHistory.ContextMenu.DisplayFormatPasted",
- CalculateDisplayFormat(item.data()));
- }
- bool ContainsFileSystemData(const ui::ClipboardData& data) {
- return !GetFileSystemSources(data).empty();
- }
- void GetSplitFileSystemData(const ui::ClipboardData& data,
- std::vector<base::StringPiece16>* source_list,
- std::u16string* sources) {
- DCHECK(sources);
- DCHECK(sources->empty());
- DCHECK(source_list);
- DCHECK(source_list->empty());
- *sources = GetFileSystemSources(data);
- if (sources->empty()) {
- // Not a file system data.
- return;
- }
- // Split sources into a list.
- *source_list = base::SplitStringPiece(*sources, u"\n", base::TRIM_WHITESPACE,
- base::SPLIT_WANT_NONEMPTY);
- }
- size_t GetCountOfCopiedFiles(const ui::ClipboardData& data) {
- std::u16string sources;
- std::vector<base::StringPiece16> source_list;
- GetSplitFileSystemData(data, &source_list, &sources);
- if (sources.empty()) {
- // Not a file system data.
- return 0;
- }
- return source_list.size();
- }
- std::u16string GetFileSystemSources(const ui::ClipboardData& data) {
- // Outside of the Files app, file system sources are written as filenames.
- if (ContainsFormat(data, ui::ClipboardInternalFormat::kFilenames)) {
- std::vector<std::string> sources;
- for (const ui::FileInfo& filename : data.filenames())
- sources.push_back(filename.path.value());
- return base::UTF8ToUTF16(base::JoinString(sources, "\n"));
- }
- // Within the Files app, file system sources are written as custom data.
- if (!ContainsFormat(data, ui::ClipboardInternalFormat::kCustom))
- return std::u16string();
- // Attempt to read file system sources in the custom data.
- std::u16string sources;
- ui::ReadCustomDataForType(data.custom_data_data().c_str(),
- data.custom_data_data().size(),
- kFileSystemSourcesType, &sources);
- return sources;
- }
- bool IsSupported(const ui::ClipboardData& data) {
- const absl::optional<ui::ClipboardInternalFormat> format =
- CalculateMainFormat(data);
- // Empty `data` is not supported.
- if (!format.has_value())
- return false;
- // The only supported type of custom data is file system data.
- if (format.value() == ui::ClipboardInternalFormat::kCustom)
- return ContainsFileSystemData(data);
- return true;
- }
- bool IsEnabledInCurrentMode() {
- const auto* session_controller = Shell::Get()->session_controller();
- // The clipboard history menu is enabled only when a user has logged in and
- // login UI is hidden.
- if (session_controller->GetSessionState() !=
- session_manager::SessionState::ACTIVE) {
- return false;
- }
- switch (session_controller->login_status()) {
- case LoginStatus::NOT_LOGGED_IN:
- case LoginStatus::LOCKED:
- case LoginStatus::KIOSK_APP:
- case LoginStatus::PUBLIC:
- return false;
- case LoginStatus::USER:
- case LoginStatus::GUEST:
- case LoginStatus::CHILD:
- return true;
- }
- }
- gfx::ImageSkia GetIconForFileClipboardItem(const ClipboardHistoryItem& item,
- const std::string& file_name) {
- DCHECK_EQ(ClipboardHistoryDisplayFormat::kFile,
- CalculateDisplayFormat(item.data()));
- const int copied_files_count = GetCountOfCopiedFiles(item.data());
- if (copied_files_count == 0)
- return gfx::ImageSkia();
- if (copied_files_count == 1) {
- return chromeos::GetIconForPath(
- base::FilePath(file_name),
- ash::DarkLightModeControllerImpl::Get()->IsDarkModeEnabled());
- }
- constexpr std::array<const gfx::VectorIcon*, 9> icons = {
- &kTwoFilesIcon, &kThreeFilesIcon, &kFourFilesIcon,
- &kFiveFilesIcon, &kSixFilesIcon, &kSevenFilesIcon,
- &kEightFilesIcon, &kNineFilesIcon, &kMoreThanNineFilesIcon};
- int icon_index = std::min(copied_files_count - 2, (int)icons.size() - 1);
- const SkColor icon_color = ash::AshColorProvider::Get()->GetContentLayerColor(
- AshColorProvider::ContentLayerType::kIconColorPrimary);
- return CreateVectorIcon(*icons[icon_index], icon_color);
- }
- } // namespace ClipboardHistoryUtil
- } // namespace ash
|