[go: nahoru, domu]

blob: 115b9112f04ba07a6c1d36df85b3c0708ba5c531 [file] [log] [blame]
// Copyright 2017 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/extensions/api/file_system/chrome_file_system_delegate.h"
#include <string>
#include <utility>
#include "apps/saved_files_service.h"
#include "base/check.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/notreached.h"
#include "base/path_service.h"
#include "chrome/browser/download/chrome_download_manager_delegate.h"
#include "chrome/browser/download/download_core_service.h"
#include "chrome/browser/download/download_core_service_factory.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/extensions/api/file_system/file_entry_picker.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/apps/directory_access_confirmation_dialog.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/grit/generated_resources.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/api/file_system/saved_files_service_interface.h"
#include "extensions/browser/app_window/app_window.h"
#include "extensions/browser/app_window/app_window_registry.h"
#include "extensions/common/extension.h"
#include "storage/common/file_system/file_system_util.h"
#if BUILDFLAG(IS_MAC)
#include <CoreFoundation/CoreFoundation.h>
#include "base/apple/foundation_util.h"
#endif
#if BUILDFLAG(IS_CHROMEOS)
#include "extensions/browser/event_router.h"
#endif // BUILDFLAG(IS_CHROMEOS)
namespace extensions {
namespace file_system = api::file_system;
#if BUILDFLAG(IS_CHROMEOS)
namespace file_system_api {
const char kConsentImpossible[] =
"Impossible to ask for user consent as there is no app window visible.";
const char kNotSupportedOnNonKioskSessionError[] =
"Operation only supported for kiosk apps running in a kiosk session.";
const char kRequiresFileSystemWriteError[] =
"Operation requires fileSystem.write permission";
const char kSecurityError[] = "Security error.";
const char kVolumeNotFoundError[] = "Volume not found.";
// Returns error message, or null if none.
const char* ConsentResultToError(ConsentProvider::Consent result) {
switch (result) {
case ConsentProvider::CONSENT_REJECTED:
return kSecurityError;
case ConsentProvider::CONSENT_IMPOSSIBLE:
return kConsentImpossible;
case ConsentProvider::CONSENT_GRANTED:
return nullptr;
}
NOTREACHED();
}
} // namespace file_system_api
#endif // BUILDFLAG(IS_CHROMEOS)
/******** ChromeFileSystemDelegate ********/
ChromeFileSystemDelegate::ChromeFileSystemDelegate() = default;
ChromeFileSystemDelegate::~ChromeFileSystemDelegate() = default;
base::FilePath ChromeFileSystemDelegate::GetDefaultDirectory() {
base::FilePath documents_dir;
base::PathService::Get(chrome::DIR_USER_DOCUMENTS, &documents_dir);
return documents_dir;
}
base::FilePath ChromeFileSystemDelegate::GetManagedSaveAsDirectory(
content::BrowserContext* browser_context,
const Extension& extension) {
if (extension.id() != extension_misc::kPdfExtensionId)
return base::FilePath();
ChromeDownloadManagerDelegate* download_manager =
DownloadCoreServiceFactory::GetForBrowserContext(browser_context)
->GetDownloadManagerDelegate();
DownloadPrefs* download_prefs = download_manager->download_prefs();
if (!download_prefs->IsDownloadPathManaged())
return base::FilePath();
return download_prefs->DownloadPath();
}
bool ChromeFileSystemDelegate::ShowSelectFileDialog(
scoped_refptr<ExtensionFunction> extension_function,
ui::SelectFileDialog::Type type,
const base::FilePath& default_path,
const ui::SelectFileDialog::FileTypeInfo* file_types,
FileSystemDelegate::FilesSelectedCallback files_selected_callback,
base::OnceClosure file_selection_canceled_callback) {
const Extension* extension = extension_function->extension();
content::WebContents* web_contents =
extension_function->GetSenderWebContents();
if (!web_contents)
return false;
// TODO(asargent/benwells) - As a short term remediation for
// crbug.com/179010 we're adding the ability for a allowlisted extension to
// use this API since chrome.fileBrowserHandler.selectFile is ChromeOS-only.
// Eventually we'd like a better solution and likely this code will go back
// to being platform-app only.
// Make sure there is an app window associated with the web contents, so that
// platform apps cannot open the file picker from a background page.
// TODO(michaelpg): As a workaround for https://crbug.com/736930, allow this
// to work from a background page for non-platform apps (which, in practice,
// is restricted to allowlisted extensions).
if (extension->is_platform_app() &&
!AppWindowRegistry::Get(extension_function->browser_context())
->GetAppWindowForWebContents(web_contents)) {
return false;
}
// The file picker will hold a reference to the ExtensionFunction
// instance, preventing its destruction (and subsequent sending of the
// function response) until the user has selected a file or cancelled the
// picker. At that point, the picker will delete itself, which will also free
// the function instance.
new FileEntryPicker(web_contents, default_path, *file_types, type,
std::move(files_selected_callback),
std::move(file_selection_canceled_callback));
return true;
}
void ChromeFileSystemDelegate::ConfirmSensitiveDirectoryAccess(
bool has_write_permission,
const std::u16string& app_name,
content::WebContents* web_contents,
base::OnceClosure on_accept,
base::OnceClosure on_cancel) {
CreateDirectoryAccessConfirmationDialog(has_write_permission, app_name,
web_contents, std::move(on_accept),
std::move(on_cancel));
}
int ChromeFileSystemDelegate::GetDescriptionIdForAcceptType(
const std::string& accept_type) {
if (accept_type == "image/*")
return IDS_IMAGE_FILES;
if (accept_type == "audio/*")
return IDS_AUDIO_FILES;
if (accept_type == "video/*")
return IDS_VIDEO_FILES;
return 0;
}
#if BUILDFLAG(IS_CHROMEOS)
void ChromeFileSystemDelegate::RequestFileSystem(
content::BrowserContext* browser_context,
scoped_refptr<ExtensionFunction> requester,
ConsentProvider* consent_provider,
const Extension& extension,
std::string volume_id,
bool writable,
FileSystemCallback success_callback,
ErrorCallback error_callback) {}
void ChromeFileSystemDelegate::GetVolumeList(
content::BrowserContext* browser_context,
VolumeListCallback success_callback,
ErrorCallback error_callback) {}
#endif // BUILDFLAG(IS_CHROMEOS)
SavedFilesServiceInterface* ChromeFileSystemDelegate::GetSavedFilesService(
content::BrowserContext* browser_context) {
return apps::SavedFilesService::Get(browser_context);
}
} // namespace extensions