#include "ash/webui/file_manager/file_manager_ui.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/webui/common/trusted_types_util.h"
#include "ash/webui/file_manager/file_manager_page_handler.h"
#include "ash/webui/file_manager/resource_loader.h"
#include "ash/webui/file_manager/resources/grit/file_manager_swa_resources.h"
#include "ash/webui/file_manager/resources/grit/file_manager_swa_resources_map.h"
#include "ash/webui/file_manager/url_constants.h"
#include "base/check_op.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "components/user_manager/user_type.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/common/url_constants.h"
#include "services/network/public/mojom/content_security_policy.mojom.h"
#include "ui/file_manager/grit/file_manager_gen_resources.h"
#include "ui/file_manager/grit/file_manager_gen_resources_map.h"
#include "ui/file_manager/grit/file_manager_resources_map.h"
namespace ash::file_manager {
namespace {
bool IsKioskSession() {
auto* session_controller = Shell::Get()->session_controller();
auto account_id = session_controller->GetActiveAccountId();
auto* session = session_controller->GetUserSessionByAccountId(account_id);
if (!session) {
return false;
}
const auto user_type = session->user_info.type;
switch (user_type) {
case user_manager::UserType::kRegular:
case user_manager::UserType::kChild:
case user_manager::UserType::kGuest:
case user_manager::UserType::kPublicAccount:
return false;
case user_manager::UserType::kKioskChromeApp:
case user_manager::UserType::kKioskWebApp:
case user_manager::UserType::kKioskIWA:
case user_manager::UserType::kKioskArcvmApp:
return true;
}
}
}
FileManagerUIConfig::FileManagerUIConfig(
SystemWebAppUIConfig::CreateWebUIControllerFunc create_controller_func)
: SystemWebAppUIConfig(ash::file_manager::kChromeUIFileManagerHost,
SystemWebAppType::FILE_MANAGER,
create_controller_func) {}
bool FileManagerUIConfig::IsWebUIEnabled(
content::BrowserContext* browser_context) {
return SystemWebAppUIConfig::IsWebUIEnabled(browser_context) ||
IsKioskSession();
}
FileManagerUI::FileManagerUI(content::WebUI* web_ui,
std::unique_ptr<FileManagerUIDelegate> delegate)
: MojoWebDialogUI(web_ui), delegate_(std::move(delegate)) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
++instance_count_;
DCHECK_GT(instance_count_, 0);
DLOG(WARNING) << "Starting FileManagerUI. Open windows: " << instance_count_;
++window_counter_;
delegate_->ShouldPollDriveHostedPinStates(true);
CreateAndAddTrustedAppDataSource(web_ui, window_counter_);
web_ui->AddRequestableScheme(content::kChromeUIUntrustedScheme);
web_ui->AddMessageHandler(delegate_->GetPluralStringHandler());
}
void FileManagerUI::CreateAndAddTrustedAppDataSource(content::WebUI* web_ui,
int window_number) {
content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd(
web_ui->GetWebContents()->GetBrowserContext(), kChromeUIFileManagerHost);
source->AddResourcePath("", IDR_FILE_MANAGER_MAIN_HTML);
source->AddResourcePaths(kFileManagerSwaResources);
AddFilesAppResources(source, kFileManagerResources);
AddFilesAppResources(source, kFileManagerGenResources);
source->EnableReplaceI18nInJS();
base::Value::Dict dict = delegate_->GetLoadTimeData();
dict.Set("WINDOW_NUMBER", window_number);
source->AddLocalizedStrings(dict);
source->UseStringsJs();
source->OverrideContentSecurityPolicy(
network::mojom::CSPDirectiveName::ScriptSrc,
"script-src chrome-extension://pmfjbimdmchhbnneeidfognadeopoehp "
"chrome://resources "
"'self' ;");
source->OverrideContentSecurityPolicy(
network::mojom::CSPDirectiveName::WorkerSrc, "worker-src 'self' ;");
source->OverrideContentSecurityPolicy(
network::mojom::CSPDirectiveName::FrameSrc,
"frame-src chrome-untrusted://file-manager "
"'self';");
ash::EnableTrustedTypesCSP(source);
}
int FileManagerUI::GetNumInstances() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
return instance_count_;
}
FileManagerUI::~FileManagerUI() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK_GT(instance_count_, 0);
--instance_count_;
DLOG(WARNING) << "Stopping FileManagerUI. Open windows: " << instance_count_;
if (!instance_count_) {
delegate_->ProgressPausedTasks();
delegate_->ShouldPollDriveHostedPinStates(false);
delegate_->ShowPolicyNotifications();
}
}
void FileManagerUI::BindInterface(
mojo::PendingReceiver<mojom::PageHandlerFactory> pending_receiver) {
if (page_factory_receiver_.is_bound())
page_factory_receiver_.reset();
page_factory_receiver_.Bind(std::move(pending_receiver));
}
void FileManagerUI::CreatePageHandler(
mojo::PendingRemote<mojom::Page> pending_page,
mojo::PendingReceiver<mojom::PageHandler> pending_page_handler) {
DCHECK(pending_page.is_valid());
page_handler_ = std::make_unique<FileManagerPageHandler>(
this, std::move(pending_page_handler), std::move(pending_page));
}
WEB_UI_CONTROLLER_TYPE_IMPL(FileManagerUI)
}