// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/public/cpp/app_list/app_list_types.h"
#include <string>
#include <utility>
#include "ash/resources/vector_icons/vector_icons.h"
#include "base/check.h"
#include "base/files/file.h"
#include "base/functional/callback.h"
#include "build/branding_buildflags.h"
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
#include "chromeos/ash/resources/internal/icons/vector_icons.h"
#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING)
namespace ash {
namespace {
// Search control dictionary pref keys.
const char kLauncherAppSearchEnabled[] = "app_search_enabled";
const char kLauncherAppShortcutSearchEnabled[] = "app_shortcut_search_enabled";
const char kLauncherWebSearchEnabled[] = "web_search_enabled";
const char kLauncherFileSearchEnabled[] = "file_search_enabled";
const char kLauncherHelpSearchEnabled[] = "help_search_enabled";
const char kLauncherPlayStoreSearchEnabled[] = "play_store_search_enabled";
const char kLauncherGameSearchEnabled[] = "game_search_enabled";
const char kLauncherImageSearchEnabled[] = "image_search_enabled";
} // namespace
const char kOemFolderId[] = "ddb1da55-d478-4243-8642-56d3041f0263";
// In order to be compatible with sync folder id must match standard.
// Generated using crx_file::id_util::GenerateId("LinuxAppsFolder")
const char kCrostiniFolderId[] = "ddolnhmblagmcagkedkbfejapapdimlk";
// Generated using crx_file::id_util::GenerateId("BruschettaAppsFolder")
const char kBruschettaFolderId[] = "olojmkekngdacpmgcffeipkflkgohcja";
bool IsAppListSearchResultAnApp(AppListSearchResultType result_type) {
switch (result_type) {
case AppListSearchResultType::kInstalledApp:
case AppListSearchResultType::kInternalApp:
case AppListSearchResultType::kPlayStoreApp:
case AppListSearchResultType::kPlayStoreReinstallApp:
case AppListSearchResultType::kArcAppShortcut:
case AppListSearchResultType::kInstantApp:
case AppListSearchResultType::kGames:
case AppListSearchResultType::kZeroStateApp:
case AppListSearchResultType::kAppShortcutV2:
return true;
case AppListSearchResultType::kUnknown:
case AppListSearchResultType::kOmnibox:
case AppListSearchResultType::kLauncher:
case AppListSearchResultType::kAnswerCard:
case AppListSearchResultType::kZeroStateFile:
case AppListSearchResultType::kZeroStateDrive:
case AppListSearchResultType::kOsSettings:
case AppListSearchResultType::kInternalPrivacyInfo:
case AppListSearchResultType::kAssistantText:
case AppListSearchResultType::kHelpApp:
case AppListSearchResultType::kZeroStateHelpApp:
case AppListSearchResultType::kFileSearch:
case AppListSearchResultType::kDriveSearch:
case AppListSearchResultType::kKeyboardShortcut:
case AppListSearchResultType::kOpenTab:
case AppListSearchResultType::kPersonalization:
case AppListSearchResultType::kImageSearch:
case AppListSearchResultType::kSystemInfo:
case AppListSearchResultType::kDesksAdminTemplate:
return false;
}
}
bool IsZeroStateResultType(AppListSearchResultType result_type) {
switch (result_type) {
case AppListSearchResultType::kZeroStateFile:
case AppListSearchResultType::kZeroStateDrive:
case AppListSearchResultType::kZeroStateHelpApp:
case AppListSearchResultType::kZeroStateApp:
case AppListSearchResultType::kDesksAdminTemplate:
return true;
case AppListSearchResultType::kUnknown:
case AppListSearchResultType::kInstalledApp:
case AppListSearchResultType::kPlayStoreApp:
case AppListSearchResultType::kInstantApp:
case AppListSearchResultType::kInternalApp:
case AppListSearchResultType::kOmnibox:
case AppListSearchResultType::kLauncher:
case AppListSearchResultType::kAnswerCard:
case AppListSearchResultType::kPlayStoreReinstallApp:
case AppListSearchResultType::kArcAppShortcut:
case AppListSearchResultType::kOsSettings:
case AppListSearchResultType::kInternalPrivacyInfo:
case AppListSearchResultType::kAssistantText:
case AppListSearchResultType::kHelpApp:
case AppListSearchResultType::kFileSearch:
case AppListSearchResultType::kDriveSearch:
case AppListSearchResultType::kKeyboardShortcut:
case AppListSearchResultType::kOpenTab:
case AppListSearchResultType::kGames:
case AppListSearchResultType::kPersonalization:
case AppListSearchResultType::kImageSearch:
case AppListSearchResultType::kSystemInfo:
case AppListSearchResultType::kAppShortcutV2:
return false;
}
}
std::string GetAppListControlCategoryName(
AppListSearchControlCategory control_category) {
switch (control_category) {
// Non-toggleable category does not have a pref name is always enabled.
case AppListSearchControlCategory::kCannotToggle:
return std::string();
case AppListSearchControlCategory::kApps:
return kLauncherAppSearchEnabled;
case AppListSearchControlCategory::kAppShortcuts:
return kLauncherAppShortcutSearchEnabled;
case AppListSearchControlCategory::kWeb:
return kLauncherWebSearchEnabled;
case AppListSearchControlCategory::kFiles:
return kLauncherFileSearchEnabled;
case ash::AppListSearchControlCategory::kHelp:
return kLauncherHelpSearchEnabled;
case ash::AppListSearchControlCategory::kPlayStore:
return kLauncherPlayStoreSearchEnabled;
case ash::AppListSearchControlCategory::kGames:
return kLauncherGameSearchEnabled;
case ash::AppListSearchControlCategory::kImages:
return kLauncherImageSearchEnabled;
}
}
// IconColor -------------------------------------------------------------------
// static
constexpr int IconColor::kHueInvalid;
constexpr int IconColor::kHueMin;
constexpr int IconColor::kHueMax;
IconColor::IconColor() = default;
IconColor::IconColor(sync_pb::AppListSpecifics::ColorGroup background_color,
int hue)
: background_color_(background_color), hue_(hue) {}
IconColor::IconColor(const IconColor& rhs)
: background_color_(rhs.background_color()), hue_(rhs.hue()) {}
IconColor& IconColor::operator=(const IconColor& rhs) = default;
IconColor::~IconColor() = default;
bool IconColor::operator<(const IconColor& rhs) const {
// TODO(crbug.com/1270898): Add DCHECKs for checking IsValid() and
// rhs.IsValid(). Investigate and fix the case where IconColors are invalid.
// In the meantime invalid IconColors can still be sorted against other
// IconColors and are ordered to come before other icons in this case.
// Compare background colors first.
if (background_color_ != rhs.background_color())
return background_color_ < rhs.background_color();
return hue_ < rhs.hue();
}
bool IconColor::operator>(const IconColor& rhs) const {
// TODO(crbug.com/1270898): Investigate and add back DCHECKS for IsValid() and
// rhs.IsValid().
// Compare background colors first.
if (background_color_ != rhs.background_color())
return background_color_ > rhs.background_color();
return hue_ > rhs.hue();
}
bool IconColor::operator>=(const IconColor& rhs) const {
return !(*this < rhs);
}
bool IconColor::operator<=(const IconColor& rhs) const {
return !(*this > rhs);
}
bool IconColor::operator==(const IconColor& rhs) const {
return !(*this != rhs);
}
bool IconColor::operator!=(const IconColor& rhs) const {
// TODO(crbug.com/1270898): Investigate and add back DCHECKS for IsValid() and
// rhs.IsValid().
return *this < rhs || *this > rhs;
}
bool IconColor::IsValid() const {
const bool is_hue_valid = (hue_ >= kHueMin && hue_ <= kHueMax);
return background_color_ != sync_pb::AppListSpecifics::COLOR_EMPTY &&
is_hue_valid;
}
////////////////////////////////////////////////////////////////////////////////
// AppListItemMetadata:
AppListItemMetadata::AppListItemMetadata() = default;
AppListItemMetadata::AppListItemMetadata(const AppListItemMetadata& rhs) =
default;
AppListItemMetadata::~AppListItemMetadata() = default;
////////////////////////////////////////////////////////////////////////////////
std::ostream& operator<<(std::ostream& os, AppListState state) {
switch (state) {
case AppListState::kStateApps:
return os << "StateApps";
case AppListState::kStateSearchResults:
return os << "SearchResults";
case AppListState::kStateStart_DEPRECATED:
return os << "Start_DEPRECATED";
case AppListState::kStateEmbeddedAssistant:
return os << "EmbeddedAssistant";
case AppListState::kInvalidState:
return os << "InvalidState";
}
}
std::ostream& operator<<(std::ostream& os, AppListBubblePage page) {
switch (page) {
case AppListBubblePage::kNone:
return os << "None";
case AppListBubblePage::kApps:
return os << "Apps";
case AppListBubblePage::kAppsCollections:
return os << "AppsCollections";
case AppListBubblePage::kSearch:
return os << "Search";
case AppListBubblePage::kAssistant:
return os << "Assistant";
}
}
std::ostream& operator<<(std::ostream& os, AppListViewState state) {
switch (state) {
case AppListViewState::kClosed:
return os << "Closed";
case AppListViewState::kFullscreenAllApps:
return os << "FullscreenAllApps";
case AppListViewState::kFullscreenSearch:
return os << "FullscreenSearch";
}
}
////////////////////////////////////////////////////////////////////////////////
// SearchResultIconInfo:
SearchResultIconInfo::SearchResultIconInfo() = default;
SearchResultIconInfo::SearchResultIconInfo(ui::ImageModel icon, int dimension)
: icon(icon), dimension(dimension) {}
SearchResultIconInfo::SearchResultIconInfo(ui::ImageModel icon,
int dimension,
SearchResultIconShape shape,
bool is_placeholder)
: icon(icon),
dimension(dimension),
shape(shape),
is_placeholder(is_placeholder) {}
SearchResultIconInfo::SearchResultIconInfo(const SearchResultIconInfo& other)
: icon(other.icon),
dimension(other.dimension),
shape(other.shape),
is_placeholder(other.is_placeholder) {}
SearchResultIconInfo::~SearchResultIconInfo() = default;
////////////////////////////////////////////////////////////////////////////////
// SearchResultSystemInfoAnswerCardInfo:
SystemInfoAnswerCardData::SystemInfoAnswerCardData() = default;
SystemInfoAnswerCardData::SystemInfoAnswerCardData(
SystemInfoAnswerCardDisplayType display_type)
: display_type(display_type) {}
SystemInfoAnswerCardData::SystemInfoAnswerCardData(double bar_chart_percentage)
: display_type(SystemInfoAnswerCardDisplayType::kBarChart),
bar_chart_percentage(bar_chart_percentage) {}
SystemInfoAnswerCardData::~SystemInfoAnswerCardData() = default;
SystemInfoAnswerCardData::SystemInfoAnswerCardData(
const SystemInfoAnswerCardData& other) = default;
void SystemInfoAnswerCardData::SetExtraDetails(
const std::u16string& description_on_right) {
extra_details = description_on_right;
}
void SystemInfoAnswerCardData::SetUpperLimitForBarChart(double upper_limit) {
DCHECK(upper_limit <= 100 && upper_limit >= 0);
upper_warning_limit_bar_chart = upper_limit;
}
void SystemInfoAnswerCardData::SetLowerLimitForBarChart(double lower_limit) {
DCHECK(lower_limit <= 100 && lower_limit >= 0);
lower_warning_limit_bar_chart = lower_limit;
}
void SystemInfoAnswerCardData::UpdateBarChartPercentage(
double new_bar_chart_percentage) {
DCHECK(new_bar_chart_percentage <= 100 && new_bar_chart_percentage >= 0);
bar_chart_percentage = new_bar_chart_percentage;
}
////////////////////////////////////////////////////////////////////////////////
// FileMetadataLoader:
FileMetadataLoader::FileMetadataLoader() = default;
FileMetadataLoader::FileMetadataLoader(const FileMetadataLoader&) = default;
FileMetadataLoader& FileMetadataLoader::operator=(const FileMetadataLoader&) =
default;
FileMetadataLoader::~FileMetadataLoader() = default;
void FileMetadataLoader::RequestFileInfo(
OnMetadataLoadedCallback on_loaded_callback) {
// Return an empty base::File::Info if the loader callback is not set.
if (loader_callback_.is_null()) {
std::move(on_loaded_callback).Run(base::File::Info());
return;
}
base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_BLOCKING},
base::OnceCallback<base::File::Info()>(loader_callback_),
std::move(on_loaded_callback));
}
void FileMetadataLoader::SetLoaderCallback(MetadataLoaderCallback callback) {
loader_callback_ = std::move(callback);
}
////////////////////////////////////////////////////////////////////////////////
// SearchResultTag:
SearchResultTag::SearchResultTag() = default;
SearchResultTag::SearchResultTag(int styles, uint32_t start, uint32_t end)
: styles(styles), range(start, end) {}
////////////////////////////////////////////////////////////////////////////////
// SearchResultAction:
SearchResultAction::SearchResultAction() = default;
SearchResultAction::SearchResultAction(SearchResultActionType type,
const std::u16string& tooltip_text)
: type(type), tooltip_text(tooltip_text) {}
SearchResultAction::SearchResultAction(const SearchResultAction& other) =
default;
SearchResultAction::~SearchResultAction() = default;
////////////////////////////////////////////////////////////////////////////////
// SearchResultTextItem:
SearchResultTextItem::SearchResultTextItem(SearchResultTextItemType type) {
item_type_ = type;
}
SearchResultTextItem::SearchResultTextItem(const SearchResultTextItem& other) =
default;
SearchResultTextItem& SearchResultTextItem::operator=(
const SearchResultTextItem& other) = default;
SearchResultTextItem::~SearchResultTextItem() = default;
SearchResultTextItemType SearchResultTextItem::GetType() const {
return item_type_;
}
const std::u16string& SearchResultTextItem::GetText() const {
DCHECK(item_type_ == SearchResultTextItemType::kString ||
item_type_ == SearchResultTextItemType::kIconifiedText);
return raw_text_.value();
}
SearchResultTextItem& SearchResultTextItem::SetText(std::u16string text) {
DCHECK(item_type_ == SearchResultTextItemType::kString ||
item_type_ == SearchResultTextItemType::kIconifiedText);
raw_text_ = text;
return *this;
}
const SearchResultTags& SearchResultTextItem::GetTextTags() const {
DCHECK(item_type_ == SearchResultTextItemType::kString ||
item_type_ == SearchResultTextItemType::kIconifiedText);
return text_tags_.value();
}
SearchResultTags& SearchResultTextItem::GetTextTags() {
DCHECK(item_type_ == SearchResultTextItemType::kString ||
item_type_ == SearchResultTextItemType::kIconifiedText);
return text_tags_.value();
}
SearchResultTextItem& SearchResultTextItem::SetTextTags(SearchResultTags tags) {
DCHECK(item_type_ == SearchResultTextItemType::kString ||
item_type_ == SearchResultTextItemType::kIconifiedText);
text_tags_ = tags;
return *this;
}
const gfx::VectorIcon* SearchResultTextItem::GetIconFromCode() const {
DCHECK_EQ(item_type_, SearchResultTextItemType::kIconCode);
DCHECK(icon_code_.has_value());
switch (icon_code_.value()) {
// Browser.
case kKeyboardShortcutBrowserBack:
return &kKsvBrowserBackIcon;
case kKeyboardShortcutBrowserForward:
return &kKsvBrowserForwardIcon;
case kKeyboardShortcutBrowserRefresh:
return &kKsvReloadIcon;
case kKeyboardShortcutBrowserSearch:
return &kKsBrowserSearchIcon;
// Emoji picker.
case kKeyboardShortcutEmojiPicker:
return &kKsEmojiPickerIcon;
// Dictation.
case kKeyboardShortcutDictationToggle:
return &kKsDictationIcon;
// Zoom.
case kKeyboardShortcutZoom:
return &kKsvFullscreenIcon;
// Media.
case kKeyboardShortcutMediaLaunchApp1:
return &kKsvOverviewIcon;
case kKeyboardShortcutMediaLaunchApp1Refresh:
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
return &kOverviewRefreshIcon;
#else
return &kKsvOverviewIcon;
#endif
case kKeyboardShortcutMediaFastForward:
return &kKsMediaFastForwardIcon;
case kKeyboardShortcutMediaPause:
return &kKsMediaPauseIcon;
case kKeyboardShortcutMediaPlay:
return &kKsMediaPlayIcon;
case kKeyboardShortcutMediaPlayPause:
return &kKsMediaPlayPauseIcon;
case kKeyboardShortcutMediaTrackNext:
return &kKsMediaTrackNextIcon;
case kKeyboardShortcutMediaTrackPrevious:
return &kKsMediaTrackPreviousIcon;
// Brightness.
case kKeyboardShortcutBrightnessDown:
return &kKsvBrightnessDownIcon;
case kKeyboardShortcutBrightnessUp:
return &kKsvBrightnessUpIcon;
case kKeyboardShortcutBrightnessUpRefresh:
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
return &kBrightnessUpRefreshIcon;
#else
return &kKsvBrightnessUpIcon;
#endif
// Volume.
case kKeyboardShortcutVolumeMute:
return &kKsvMuteIcon;
case kKeyboardShortcutVolumeDown:
return &kKsvVolumeDownIcon;
case kKeyboardShortcutVolumeUp:
return &kKsvVolumeUpIcon;
// Arrows.
case kKeyboardShortcutUp:
return &kKsvArrowUpIcon;
case kKeyboardShortcutDown:
return &kKsvArrowDownIcon;
case kKeyboardShortcutLeft:
return &kKsvArrowLeftIcon;
case kKeyboardShortcutRight:
return &kKsvArrowRightIcon;
// Privacy.
case kKeyboardShortcutPrivacyScreenToggle:
return &kKsvPrivacyScreenToggleIcon;
// Settings.
case kKeyboardShortcutSettings:
return &kKsSettingsIcon;
// Snapshot.
case kKeyboardShortcutSnapshot:
return &kKsvSnapshotIcon;
// Launcher.
case kKeyboardShortcutLauncher:
return &kKsLauncherIcon;
case kKeyboardShortcutLauncherRefresh:
return &kCampbellHeroIcon;
// Search.
case kKeyboardShortcutSearch:
return &kKsSearchIcon;
// Apps.
case kKeyboardShortcutAssistant:
return &kKsAssistantIcon;
case kKeyboardShortcutAllApps:
return &kKsAllAppsIcon;
case kKeyboardShortcutCalculator:
return &kKsCalculatorIcon;
case kKeyboardShortcutInputModeChange:
return &kKsInputModeChangeIcon;
case kKeyboardShortcutMicrophone:
return &kKsMicrophoneIcon;
// Power.
case kKeyboardShortcutPower:
return &kKsPowerIcon;
// Keyboard brightness.
case kKeyboardShortcutKeyboardBrightnessDown:
return &kKsKeyboardBrightnessDownIcon;
case kKeyboardShortcutKeyboardBrightnessUp:
return &kKsKeyboardBrightnessUpIcon;
case kKeyboardShortcutKeyboardBacklightToggle:
return &kKsKeyboardBrightnessToggleIcon;
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
case kKeyboardShortcutKeyboardRightAlt:
return &kRightAltInternalIcon;
#endif
default:
return nullptr;
}
}
SearchResultTextItem& SearchResultTextItem::SetIconCode(IconCode code) {
DCHECK_EQ(item_type_, SearchResultTextItemType::kIconCode);
icon_code_ = code;
return *this;
}
gfx::ImageSkia SearchResultTextItem::GetImage() const {
DCHECK_EQ(item_type_, SearchResultTextItemType::kCustomImage);
return raw_image_.value();
}
SearchResultTextItem& SearchResultTextItem::SetImage(gfx::ImageSkia icon) {
DCHECK_EQ(item_type_, SearchResultTextItemType::kCustomImage);
raw_image_ = icon;
return *this;
}
SearchResultTextItem::OverflowBehavior
SearchResultTextItem::GetOverflowBehavior() const {
DCHECK_EQ(item_type_, SearchResultTextItemType::kString);
return overflow_behavior_;
}
SearchResultTextItem& SearchResultTextItem::SetOverflowBehavior(
SearchResultTextItem::OverflowBehavior overflow_behavior) {
DCHECK_EQ(item_type_, SearchResultTextItemType::kString);
overflow_behavior_ = overflow_behavior;
return *this;
}
bool SearchResultTextItem::GetAlternateIconAndTextStyling() const {
CHECK(item_type_ == SearchResultTextItemType::kIconifiedText ||
item_type_ == SearchResultTextItemType::kIconCode);
return alternate_icon_text_code_styling_;
}
SearchResultTextItem& SearchResultTextItem::SetAlternateIconAndTextStyling(
bool alternate_icon_text_code_styling) {
CHECK(item_type_ == SearchResultTextItemType::kIconifiedText ||
item_type_ == SearchResultTextItemType::kIconCode);
alternate_icon_text_code_styling_ = alternate_icon_text_code_styling;
return *this;
}
////////////////////////////////////////////////////////////////////////////////
// SearchResultMetadata:
SearchResultMetadata::SearchResultMetadata() = default;
SearchResultMetadata::SearchResultMetadata(const SearchResultMetadata& rhs) =
default;
SearchResultMetadata::~SearchResultMetadata() = default;
} // namespace ash