blob: 04cf7e69012c43330efbda4047982503207bac6c [file] [log] [blame]
// 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/session/session_controller_impl.h"
#include "ash/shell.h"
#include "base/strings/utf_string_conversions.h"
#include "chromeos/constants/chromeos_features.h"
#include "ui/base/clipboard/clipboard_data.h"
#include "ui/base/clipboard/custom_data_helper.h"
namespace ash {
namespace ClipboardHistoryUtil {
namespace {
constexpr char kFileSystemSourcesType[] = "fs/sources";
// The array of formats in order of decreasing priority.
constexpr ui::ClipboardInternalFormat kPrioritizedFormats[] = {
ui::ClipboardInternalFormat::kBitmap, ui::ClipboardInternalFormat::kHtml,
ui::ClipboardInternalFormat::kText, ui::ClipboardInternalFormat::kRtf,
ui::ClipboardInternalFormat::kBookmark, ui::ClipboardInternalFormat::kWeb,
ui::ClipboardInternalFormat::kCustom};
} // namespace
base::Optional<ui::ClipboardInternalFormat> CalculateMainFormat(
const ui::ClipboardData& data) {
for (const auto& format : kPrioritizedFormats) {
if (ContainsFormat(data, format)) {
return format;
}
}
return base::nullopt;
}
ClipboardHistoryDisplayFormat CalculateDisplayFormat(
const ui::ClipboardData& data) {
switch (CalculateMainFormat(data).value()) {
case ui::ClipboardInternalFormat::kBitmap:
return ClipboardHistoryDisplayFormat::kBitmap;
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::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();
}
base::string16 GetFileSystemSources(const ui::ClipboardData& data) {
if (!ContainsFormat(data, ui::ClipboardInternalFormat::kCustom))
return base::string16();
// Attempt to read file system sources in the custom data.
base::string16 sources;
ui::ReadCustomDataForType(
data.custom_data_data().c_str(), data.custom_data_data().size(),
base::UTF8ToUTF16(kFileSystemSourcesType), &sources);
return sources;
}
bool IsSupported(const ui::ClipboardData& data) {
const base::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() {
switch (Shell::Get()->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::SUPERVISED:
return true;
}
}
} // namespace ClipboardHistoryUtil
} // namespace ash