// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/ash/settings/pages/files/files_section.h"
#include "ash/constants/ash_features.h"
#include "base/functional/callback_helpers.h"
#include "base/no_destructor.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ash/drive/file_system_util.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/browser/chromeos/upload_office_to_cloud/upload_office_to_cloud.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_util.h"
#include "chrome/browser/ui/webui/ash/settings/search/search_tag_registry.h"
#include "chrome/browser/ui/webui/ash/smb_shares/smb_handler.h"
#include "chrome/browser/ui/webui/ash/smb_shares/smb_shares_localized_strings_provider.h"
#include "chrome/browser/ui/webui/webui_util.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "components/user_manager/user.h"
#include "content/public/browser/web_ui_data_source.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/webui/web_ui_util.h"
namespace ash::settings {
namespace mojom {
using ::chromeos::settings::mojom::kFilesSectionPath;
using ::chromeos::settings::mojom::kGoogleDriveSubpagePath;
using ::chromeos::settings::mojom::kNetworkFileSharesSubpagePath;
using ::chromeos::settings::mojom::kOfficeFilesSubpagePath;
using ::chromeos::settings::mojom::kOneDriveSubpagePath;
using ::chromeos::settings::mojom::kSystemPreferencesSectionPath;
using ::chromeos::settings::mojom::Section;
using ::chromeos::settings::mojom::Setting;
using ::chromeos::settings::mojom::Subpage;
} // namespace mojom
namespace {
const std::vector<SearchConcept>& GetDefaultSearchConcepts(
mojom::Section section,
const char* section_path) {
static const base::NoDestructor<std::vector<SearchConcept>> tags({
{IDS_OS_SETTINGS_TAG_FILES,
section_path,
mojom::SearchResultIcon::kFolder,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSection,
{.section = section}},
{IDS_OS_SETTINGS_TAG_FILES_NETWORK_FILE_SHARES,
mojom::kNetworkFileSharesSubpagePath,
mojom::SearchResultIcon::kFolderShared,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kNetworkFileShares},
{IDS_OS_SETTINGS_TAG_FILES_NETWORK_FILE_SHARES_ALT1,
SearchConcept::kAltTagEnd}},
});
return *tags;
}
const std::vector<SearchConcept>& GetFilesMicrosoft365SearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags(
{{IDS_OS_SETTINGS_TAG_FILES_MICROSOFT_365,
mojom::kOfficeFilesSubpagePath,
mojom::SearchResultIcon::kFolder,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kOfficeFiles},
{IDS_OS_SETTINGS_TAG_FILES_MICROSOFT_365_ALT1,
SearchConcept::kAltTagEnd}}});
return *tags;
}
const std::vector<SearchConcept>& GetFilesOneDriveSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags(
{{IDS_OS_SETTINGS_TAG_FILES_ONEDRIVE,
mojom::kOneDriveSubpagePath,
mojom::SearchResultIcon::kOneDrive,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kOneDrive}}});
return *tags;
}
// Returns specific search terms to surface the "File sync" feature.
const std::vector<SearchConcept>& GetFilesGoogleDriveFileSyncSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags(
{{IDS_OS_SETTINGS_TAG_FILES_GOOGLE_DRIVE_FILE_SYNC,
mojom::kGoogleDriveSubpagePath,
mojom::SearchResultIcon::kGoogleDrive,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.setting = mojom::Setting::kGoogleDriveFileSync},
{IDS_OS_SETTINGS_TAG_FILES_GOOGLE_DRIVE_FILE_SYNC_ALT1,
SearchConcept::kAltTagEnd}}});
return *tags;
}
// Returns search terms to navigate to the Google Drive subpage when the feature
// is enabled.
const std::vector<SearchConcept>& GetFilesGoogleDriveSubpageSearchConcepts() {
static const base::NoDestructor<std::vector<SearchConcept>> tags(
{{IDS_OS_SETTINGS_TAG_FILES_GOOGLE_DRIVE,
mojom::kGoogleDriveSubpagePath,
mojom::SearchResultIcon::kGoogleDrive,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSubpage,
{.subpage = mojom::Subpage::kGoogleDrive}},
{IDS_OS_SETTINGS_TAG_FILES_REMOVE_GOOGLE_DRIVE_ACCESS,
mojom::kGoogleDriveSubpagePath,
mojom::SearchResultIcon::kGoogleDrive,
mojom::SearchResultDefaultRank::kMedium,
mojom::SearchResultType::kSetting,
{.setting = mojom::Setting::kGoogleDriveRemoveAccess}}});
return *tags;
}
} // namespace
FilesSection::FilesSection(Profile* profile,
SearchTagRegistry* search_tag_registry)
: OsSettingsSection(profile, search_tag_registry) {
SearchTagRegistry::ScopedTagUpdater updater = registry()->StartUpdate();
updater.AddSearchTags(
GetDefaultSearchConcepts(GetSection(), GetSectionPath()));
if (chromeos::IsEligibleAndEnabledUploadOfficeToCloud(profile)) {
updater.AddSearchTags(GetFilesMicrosoft365SearchConcepts());
updater.AddSearchTags(GetFilesOneDriveSearchConcepts());
}
if (drive::util::IsDriveFsBulkPinningAvailable(profile)) {
updater.AddSearchTags(GetFilesGoogleDriveFileSyncSearchConcepts());
}
updater.AddSearchTags(GetFilesGoogleDriveSubpageSearchConcepts());
}
FilesSection::~FilesSection() = default;
void FilesSection::AddLoadTimeData(content::WebUIDataSource* html_source) {
static constexpr webui::LocalizedString kLocalizedStrings[] = {
{"disconnectGoogleDriveAccount", IDS_SETTINGS_DISCONNECT_GOOGLE_DRIVE},
{"googleDriveLabel", IDS_SETTINGS_GOOGLE_DRIVE},
{"googleDriveConnectLabel", IDS_SETTINGS_GOOGLE_DRIVE_CONNECT},
{"googleDriveRemoveAccessDialogTitle",
IDS_SETTINGS_GOOGLE_DRIVE_REMOVE_ACCESS_DIALOG_TITLE},
{"googleDriveRemoveAccessDialogBody",
IDS_SETTINGS_GOOGLE_DRIVE_REMOVE_ACCESS_DIALOG_BODY},
{"googleDriveRemoveButtonText",
IDS_SETTINGS_GOOGLE_DRIVE_REMOVE_BUTTON_TEXT},
{"googleDriveRemoveDriveAccessButtonText",
IDS_SETTINGS_GOOGLE_DRIVE_REMOVE_ACCESS_BUTTON_LABEL},
{"googleDriveFileSyncTitle", IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_TITLE},
{"googleDriveFileSyncSubtitleWithStorage",
IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_SUBTITLE_WITH_STORAGE},
{"googleDriveFileSyncSubtitleWithoutStorage",
IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_SUBTITLE_WITHOUT_STORAGE},
{"googleDriveOfflineStorageTitle",
IDS_SETTINGS_GOOGLE_DRIVE_OFFLINE_STORAGE_TITLE},
{"googleDriveOfflineStorageSpaceTaken",
IDS_SETTINGS_GOOGLE_DRIVE_OFFLINE_STORAGE_SPACE_TAKEN},
{"googleDriveOfflineClearCalculatingSubtitle",
IDS_SETTINGS_GOOGLE_DRIVE_OFFLINE_CLEAR_CALCULATING_SUBTITLE},
{"googleDriveOfflineClearErrorSubtitle",
IDS_SETTINGS_GOOGLE_DRIVE_OFFLINE_CLEAR_ERROR_SUBTITLE},
{"googleDriveCleanUpStorageAction",
IDS_SETTINGS_GOOGLE_DRIVE_CLEAN_UP_STORAGE_ACTION},
{"googleDriveOfflineCleanStorageDialogTitle",
IDS_SETTINGS_GOOGLE_DRIVE_OFFLINE_CLEAN_UP_STORAGE_TITLE},
{"googleDriveOfflineCleanStorageDialogBody",
IDS_SETTINGS_GOOGLE_DRIVE_OFFLINE_CLEAN_UP_STORAGE_BODY},
{"googleDriveCleanUpStorageDisabledFileSyncTooltip",
IDS_SETTINGS_GOOGLE_DRIVE_OFFLINE_CLEAN_UP_STORAGE_DISABLED_FILE_SYNC_TOOLTIP},
{"googleDriveCleanUpStorageDisabledTooltip",
IDS_SETTINGS_GOOGLE_DRIVE_OFFLINE_CLEAN_UP_STORAGE_DISABLED_TOOLTIP},
{"googleDriveCleanUpStorageDisabledUnknownStorageTooltip",
IDS_SETTINGS_GOOGLE_DRIVE_OFFLINE_CLEAN_UP_STORAGE_DISABLED_UNKNOWN_STORAGE_TOOLTIP},
{"googleDriveTurnOffLabel",
IDS_SETTINGS_GOOGLE_DRIVE_TURN_OFF_BUTTON_LABEL},
{"googleDriveFileSyncTurnOffTitle",
IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_TURN_OFF_TITLE_TEXT},
{"googleDriveFileSyncTurnOffBody",
IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_TURN_OFF_BODY_TEXT},
{"googleDriveFileSyncListingFilesTitle",
IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_TITLE_TEXT},
{"googleDriveFileSyncListingFilesItemsFoundBody",
IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_LISTING_FILES_ITEMS_FOUND_BODY_TEXT},
{"googleDriveNotEnoughSpaceTitle",
IDS_SETTINGS_GOOGLE_DRIVE_BULK_PINNING_NOT_ENOUGH_SPACE_TITLE_TEXT},
{"googleDriveNotEnoughSpaceBody",
IDS_SETTINGS_GOOGLE_DRIVE_BULK_PINNING_NOT_ENOUGH_SPACE_BODY_TEXT},
{"googleDriveFileSyncUnexpectedErrorTitle",
IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_UNEXPECTED_ERROR_TITLE_TEXT},
{"googleDriveFileSyncUnexpectedErrorBody",
IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_UNEXPECTED_ERROR_BODY_TEXT},
{"googleDriveFileSyncOfflineErrorTitle",
IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_OFFLINE_ERROR_TITLE_TEXT},
{"googleDriveFileSyncOfflineErrorBody",
IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_OFFLINE_ERROR_BODY_TEXT},
{"googleDriveDismissButtonText",
IDS_SETTINGS_GOOGLE_DRIVE_DISMISS_BUTTON_TEXT},
{"googleDriveOkButtonText", IDS_SETTINGS_GOOGLE_DRIVE_OK_BUTTON_TEXT},
{"googleDriveNotSignedInSublabel",
IDS_SETTINGS_GOOGLE_DRIVE_NOT_SIGNED_IN_SUBLABEL},
{"googleDriveFileSyncOnSublabel",
IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_ON_SUBLABEL},
{"googleDriveEnabledOnMeteredNetworkLabel",
IDS_SETTINGS_GOOGLE_DRIVE_ENABLED_ON_METERED_NETWORK_LABEL},
{"filesPageTitle", IDS_OS_SETTINGS_FILES},
{"smbSharesTitle", IDS_SETTINGS_DOWNLOADS_SMB_SHARES},
{"smbSharesLearnMoreLabel",
IDS_SETTINGS_DOWNLOADS_SMB_SHARES_LEARN_MORE_LABEL},
{"addSmbShare", IDS_SETTINGS_DOWNLOADS_SMB_SHARES_ADD_SHARE},
{"smbShareAddedSuccessfulMessage",
IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_SUCCESS_MESSAGE},
{"smbShareAddedErrorMessage",
IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_ERROR_MESSAGE},
{"smbShareAddedAuthFailedMessage",
IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_AUTH_FAILED_MESSAGE},
{"smbShareAddedNotFoundMessage",
IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_NOT_FOUND_MESSAGE},
{"smbShareAddedUnsupportedDeviceMessage",
IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_UNSUPPORTED_DEVICE_MESSAGE},
{"smbShareAddedMountExistsMessage",
IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_EXISTS_MESSAGE},
{"smbShareAddedTooManyMountsMessage",
IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_TOO_MANY_MOUNTS_MESSAGE},
{"smbShareAddedInvalidURLMessage",
IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_INVALID_URL_MESSAGE},
{"smbShareAddedInvalidSSOURLMessage",
IDS_SETTINGS_DOWNLOADS_SHARE_ADDED_MOUNT_INVALID_SSO_URL_MESSAGE},
{"oneDriveLabel", IDS_SETTINGS_ONE_DRIVE_LABEL},
{"oneDriveSignedInAs", IDS_SETTINGS_ONE_DRIVE_SIGNED_IN_AS},
{"oneDriveDisconnected", IDS_SETTINGS_ONE_DRIVE_DISCONNECTED},
{"oneDriveLoading", IDS_OS_SETTINGS_ONE_DRIVE_LOADING},
{"oneDriveConnect", IDS_SETTINGS_ONE_DRIVE_CONNECT},
{"oneDriveDisconnect", IDS_SETTINGS_ONE_DRIVE_DISCONNECT},
{"openOneDriveFolder", IDS_SETTINGS_OPEN_ONE_DRIVE_FOLDER},
{"officeLabel", IDS_SETTINGS_OFFICE_LABEL},
{"officeSublabel", IDS_SETTINGS_OFFICE_SUBLABEL},
{"officeSubpageTitle", IDS_SETTINGS_OFFICE_SUBPAGE_TITLE},
{"alwaysMoveToDrivePreferenceLabel",
IDS_SETTINGS_ALWAYS_MOVE_OFFICE_TO_DRIVE_PREFERENCE_LABEL},
{"alwaysMoveToOneDrivePreferenceLabel",
IDS_SETTINGS_ALWAYS_MOVE_OFFICE_TO_ONEDRIVE_PREFERENCE_LABEL},
{"smbSharesTitleDescription",
IDS_OS_SETTINGS_REVAMP_DOWNLOADS_SMB_SHARES_DESCRIPTION},
{"googleDriveFileSyncSectionTitle",
IDS_SETTINGS_GOOGLE_DRIVE_FILE_SYNC_SECTION_TITLE},
{"googleDriveMirrorSyncLabel",
IDS_SETTINGS_GOOGLE_DRIVE_MIRROR_SYNC_TOGGLE_LABEL},
{"googleDriveMirrorSyncDescription",
IDS_SETTINGS_GOOGLE_DRIVE_MIRROR_SYNC_TOGGLE_DESCRIPTION}};
html_source->AddLocalizedStrings(kLocalizedStrings);
smb_dialog::AddLocalizedStrings(html_source);
html_source->AddString("smbSharesLearnMoreURL",
GetHelpUrlWithBoard(chrome::kSmbSharesLearnMoreURL));
html_source->AddString(
"googleDriveCleanUpStorageLearnMoreLink",
GetHelpUrlWithBoard(chrome::kGoogleDriveCleanUpStorageLearnMoreURL));
html_source->AddString(
"googleDriveFileSyncLearnMoreLink",
GetHelpUrlWithBoard(chrome::kGoogleDriveOfflineLearnMoreURL));
html_source->AddBoolean(
"showOneDriveSettings",
ash::cloud_upload::
IsMicrosoftOfficeOneDriveIntegrationAllowedAndOdfsInstalled(
profile()));
html_source->AddBoolean(
"showOfficeSettings",
chromeos::cloud_upload::IsMicrosoftOfficeCloudUploadAllowed(profile()));
const user_manager::User* user =
ProfileHelper::Get()->GetUserByProfile(profile());
if (user && user->GetAccountId().is_valid()) {
html_source->AddString(
"googleDriveSignedInAs",
l10n_util::GetStringFUTF16(IDS_SETTINGS_GOOGLE_DRIVE_SIGNED_IN_AS,
base::ASCIIToUTF16(user->display_email())));
html_source->AddString(
"googleDriveReconnectAs",
l10n_util::GetStringFUTF16(IDS_SETTINGS_GOOGLE_DRIVE_RECONNECT_AS,
base::ASCIIToUTF16(user->display_email())));
}
html_source->AddBoolean(
"enableDriveFsBulkPinning",
drive::util::IsDriveFsBulkPinningAvailable(profile()));
html_source->AddBoolean(
"enableSkyVault",
base::FeatureList::IsEnabled(::features::kSkyVault) &&
base::FeatureList::IsEnabled(::features::kSkyVaultV2));
html_source->AddBoolean("enableDriveFsMirrorSync",
drive::util::IsDriveFsMirrorSyncAvailable(profile()));
}
void FilesSection::AddHandlers(content::WebUI* web_ui) {
web_ui->AddMessageHandler(
std::make_unique<smb_dialog::SmbHandler>(profile(), base::DoNothing()));
}
int FilesSection::GetSectionNameMessageId() const {
return IDS_OS_SETTINGS_FILES;
}
mojom::Section FilesSection::GetSection() const {
return ash::features::IsOsSettingsRevampWayfindingEnabled()
? mojom::Section::kSystemPreferences
: mojom::Section::kFiles;
}
mojom::SearchResultIcon FilesSection::GetSectionIcon() const {
return mojom::SearchResultIcon::kFolder;
}
const char* FilesSection::GetSectionPath() const {
return ash::features::IsOsSettingsRevampWayfindingEnabled()
? mojom::kSystemPreferencesSectionPath
: mojom::kFilesSectionPath;
}
bool FilesSection::LogMetric(mojom::Setting setting, base::Value& value) const {
// No metrics are logged.
return false;
}
void FilesSection::RegisterHierarchy(HierarchyGenerator* generator) const {
generator->RegisterTopLevelSetting(mojom::Setting::kGoogleDriveConnection);
generator->RegisterTopLevelSetting(mojom::Setting::kGoogleDriveFileSync);
generator->RegisterTopLevelSetting(mojom::Setting::kGoogleDriveRemoveAccess);
// Network file shares.
generator->RegisterTopLevelSubpage(IDS_SETTINGS_DOWNLOADS_SMB_SHARES,
mojom::Subpage::kNetworkFileShares,
mojom::SearchResultIcon::kFolderShared,
mojom::SearchResultDefaultRank::kMedium,
mojom::kNetworkFileSharesSubpagePath);
// MS Office.
generator->RegisterTopLevelSubpage(
IDS_SETTINGS_OFFICE_LABEL, mojom::Subpage::kOfficeFiles,
mojom::SearchResultIcon::kFolder, mojom::SearchResultDefaultRank::kMedium,
mojom::kNetworkFileSharesSubpagePath);
// Google Drive.
generator->RegisterTopLevelSubpage(
IDS_SETTINGS_GOOGLE_DRIVE, mojom::Subpage::kGoogleDrive,
mojom::SearchResultIcon::kGoogleDrive,
mojom::SearchResultDefaultRank::kMedium, mojom::kGoogleDriveSubpagePath);
// One Drive
generator->RegisterTopLevelSubpage(
IDS_SETTINGS_ONE_DRIVE_LABEL, mojom::Subpage::kOneDrive,
mojom::SearchResultIcon::kOneDrive,
mojom::SearchResultDefaultRank::kMedium, mojom::kOneDriveSubpagePath);
}
} // namespace ash::settings