diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index a816fdfbcbe7c..d0a02e08fa9e7 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -10461,6 +10461,16 @@ Please help our engineers fix this problem. Tell us what happened right before y + + + + Open $1.txt, .csv, .md files + + + , ''' + + + diff --git a/chrome/app/generated_resources_grd/IDS_WEB_APP_FILE_HANDLING_EXTENSION_LIST_SEPARATOR.png.sha1 b/chrome/app/generated_resources_grd/IDS_WEB_APP_FILE_HANDLING_EXTENSION_LIST_SEPARATOR.png.sha1 new file mode 100644 index 0000000000000..6ee6d61a3e4af --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_WEB_APP_FILE_HANDLING_EXTENSION_LIST_SEPARATOR.png.sha1 @@ -0,0 +1 @@ +aa286efbaee111ce1a8e37854ff384fa397f929e \ No newline at end of file diff --git a/chrome/app/generated_resources_grd/IDS_WEB_APP_FILE_HANDLING_PERMISSION_TEXT.png.sha1 b/chrome/app/generated_resources_grd/IDS_WEB_APP_FILE_HANDLING_PERMISSION_TEXT.png.sha1 new file mode 100644 index 0000000000000..6ee6d61a3e4af --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_WEB_APP_FILE_HANDLING_PERMISSION_TEXT.png.sha1 @@ -0,0 +1 @@ +aa286efbaee111ce1a8e37854ff384fa397f929e \ No newline at end of file diff --git a/chrome/browser/permissions/permission_manager_factory.cc b/chrome/browser/permissions/permission_manager_factory.cc index 4012e39323ee3..3811b0d846c91 100644 --- a/chrome/browser/permissions/permission_manager_factory.cc +++ b/chrome/browser/permissions/permission_manager_factory.cc @@ -32,7 +32,6 @@ #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/permissions/contexts/clipboard_read_write_permission_context.h" #include "components/permissions/contexts/clipboard_sanitized_write_permission_context.h" -#include "components/permissions/contexts/file_handling_permission_context.h" #include "components/permissions/contexts/font_access_permission_context.h" #include "components/permissions/contexts/midi_permission_context.h" #include "components/permissions/contexts/midi_sysex_permission_context.h" @@ -51,6 +50,7 @@ #include "components/permissions/contexts/nfc_permission_context_android.h" #else #include "chrome/browser/geolocation/geolocation_permission_context_delegate.h" +#include "chrome/browser/web_applications/components/file_handling_permission_context.h" #include "components/permissions/contexts/geolocation_permission_context.h" #include "components/permissions/contexts/nfc_permission_context.h" #endif @@ -141,8 +141,10 @@ permissions::PermissionManager::PermissionContextMap CreatePermissionContexts( std::make_unique(profile); permission_contexts[ContentSettingsType::DISPLAY_CAPTURE] = std::make_unique(profile); +#if !defined(OS_ANDROID) // File Handling is not available on Android. permission_contexts[ContentSettingsType::FILE_HANDLING] = std::make_unique(profile); +#endif // !defined(OS_ANDROID) return permission_contexts; } } // namespace diff --git a/chrome/browser/web_applications/components/BUILD.gn b/chrome/browser/web_applications/components/BUILD.gn index f4326094e0980..bbf26dcd6e8f3 100644 --- a/chrome/browser/web_applications/components/BUILD.gn +++ b/chrome/browser/web_applications/components/BUILD.gn @@ -24,6 +24,10 @@ source_set("components") { "externally_managed_app_manager.h", "file_handler_manager.cc", "file_handler_manager.h", + "file_handling_permission_context.cc", + "file_handling_permission_context.h", + "file_handling_permission_request_impl.cc", + "file_handling_permission_request_impl.h", "install_bounce_metric.cc", "install_bounce_metric.h", "install_finalizer.cc", @@ -181,6 +185,7 @@ source_set("components") { "//chrome/common", "//components/crx_file", "//components/keyed_service/content", + "//components/permissions:permissions", "//components/pref_registry", "//components/services/app_service/public/cpp:protocol_handling", "//components/services/app_service/public/mojom", diff --git a/chrome/browser/web_applications/components/file_handling_permission_context.cc b/chrome/browser/web_applications/components/file_handling_permission_context.cc new file mode 100644 index 0000000000000..1d344b77e402b --- /dev/null +++ b/chrome/browser/web_applications/components/file_handling_permission_context.cc @@ -0,0 +1,40 @@ +// Copyright 2021 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 "chrome/browser/web_applications/components/file_handling_permission_context.h" + +#include + +#include "chrome/browser/web_applications/components/file_handling_permission_request_impl.h" +#include "components/content_settings/core/common/content_settings_types.h" +#include "components/permissions/permission_context_base.h" +#include "content/public/browser/web_contents.h" +#include "third_party/blink/public/mojom/permissions_policy/permissions_policy.mojom.h" + +FileHandlingPermissionContext::FileHandlingPermissionContext( + content::BrowserContext* browser_context) + : PermissionContextBase(browser_context, + ContentSettingsType::FILE_HANDLING, + blink::mojom::PermissionsPolicyFeature::kNotFound) { +} + +FileHandlingPermissionContext::~FileHandlingPermissionContext() = default; + +bool FileHandlingPermissionContext::IsRestrictedToSecureOrigins() const { + return true; +} + +std::unique_ptr +FileHandlingPermissionContext::CreatePermissionRequest( + const GURL& request_origin, + ContentSettingsType content_settings_type, + bool has_gesture, + content::WebContents* web_contents, + permissions::PermissionRequestImpl::PermissionDecidedCallback + permission_decided_callback, + base::OnceClosure delete_callback) const { + return std::make_unique( + request_origin, content_settings_type, has_gesture, web_contents, + std::move(permission_decided_callback), std::move(delete_callback)); +} diff --git a/components/permissions/contexts/file_handling_permission_context.h b/chrome/browser/web_applications/components/file_handling_permission_context.h similarity index 50% rename from components/permissions/contexts/file_handling_permission_context.h rename to chrome/browser/web_applications/components/file_handling_permission_context.h index 16442e7903178..6c65928c94044 100644 --- a/components/permissions/contexts/file_handling_permission_context.h +++ b/chrome/browser/web_applications/components/file_handling_permission_context.h @@ -2,11 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_PERMISSIONS_CONTEXTS_FILE_HANDLING_PERMISSION_CONTEXT_H_ -#define COMPONENTS_PERMISSIONS_CONTEXTS_FILE_HANDLING_PERMISSION_CONTEXT_H_ +#ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_FILE_HANDLING_PERMISSION_CONTEXT_H_ +#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_FILE_HANDLING_PERMISSION_CONTEXT_H_ #include "components/permissions/permission_context_base.h" +namespace content { +class WebContents; +} // namespace content + class FileHandlingPermissionContext : public permissions::PermissionContextBase { public: @@ -21,6 +25,14 @@ class FileHandlingPermissionContext protected: // PermissionContextBase: bool IsRestrictedToSecureOrigins() const override; + std::unique_ptr CreatePermissionRequest( + const GURL& request_origin, + ContentSettingsType content_settings_type, + bool has_gesture, + content::WebContents* web_contents, + permissions::PermissionRequestImpl::PermissionDecidedCallback + permission_decided_callback, + base::OnceClosure delete_callback) const override; }; -#endif // COMPONENTS_PERMISSIONS_CONTEXTS_FILE_HANDLING_PERMISSION_CONTEXT_H_ +#endif // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_FILE_HANDLING_PERMISSION_CONTEXT_H_ diff --git a/chrome/browser/web_applications/components/file_handling_permission_request_impl.cc b/chrome/browser/web_applications/components/file_handling_permission_request_impl.cc new file mode 100644 index 0000000000000..c47de69c44b23 --- /dev/null +++ b/chrome/browser/web_applications/components/file_handling_permission_request_impl.cc @@ -0,0 +1,51 @@ +// Copyright 2021 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 "chrome/browser/web_applications/components/file_handling_permission_request_impl.h" + +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/web_applications/components/web_app_utils.h" +#include "chrome/grit/generated_resources.h" +#include "components/strings/grit/components_strings.h" +#include "content/public/browser/web_contents.h" +#include "ui/base/l10n/l10n_util.h" + +namespace permissions { + +FileHandlingPermissionRequestImpl::FileHandlingPermissionRequestImpl( + const GURL& request_origin, + ContentSettingsType content_settings_type, + bool has_gesture, + content::WebContents* web_contents, + PermissionDecidedCallback permission_decided_callback, + base::OnceClosure delete_callback) + : PermissionRequestImpl(request_origin, + content_settings_type, + has_gesture, + std::move(permission_decided_callback), + std::move(delete_callback)) { + auto* browser = web_contents->GetBrowserContext(); + if (!browser) { + return; + } + Profile* profile = Profile::FromBrowserContext(browser); + DCHECK(profile); + + std::u16string extensions_list = + web_app::GetFileExtensionsHandledByWebAppDisplayedAsList( + profile, web_contents->GetLastCommittedURL()); + message_text_fragment_ = l10n_util::GetStringFUTF16( + IDS_WEB_APP_FILE_HANDLING_PERMISSION_TEXT, extensions_list); +} + +FileHandlingPermissionRequestImpl::~FileHandlingPermissionRequestImpl() = + default; + +std::u16string FileHandlingPermissionRequestImpl::GetMessageTextFragment() + const { + return message_text_fragment_; +} + +} // namespace permissions diff --git a/chrome/browser/web_applications/components/file_handling_permission_request_impl.h b/chrome/browser/web_applications/components/file_handling_permission_request_impl.h new file mode 100644 index 0000000000000..c1287e2ae4b01 --- /dev/null +++ b/chrome/browser/web_applications/components/file_handling_permission_request_impl.h @@ -0,0 +1,36 @@ +// Copyright 2021 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. + +#ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_FILE_HANDLING_PERMISSION_REQUEST_IMPL_H_ +#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_FILE_HANDLING_PERMISSION_REQUEST_IMPL_H_ + +#include +#include "components/permissions/permission_request_impl.h" + +namespace content { +class WebContents; +} + +namespace permissions { + +// Provides a custom message text fragment that differs based on file handlers +// requested by a web app. +class FileHandlingPermissionRequestImpl : public PermissionRequestImpl { + public: + FileHandlingPermissionRequestImpl( + const GURL& request_origin, + ContentSettingsType content_settings_type, + bool has_gesture, + content::WebContents* web_contents, + PermissionDecidedCallback permission_decided_callback, + base::OnceClosure delete_callback); + ~FileHandlingPermissionRequestImpl() override; + + private: + std::u16string GetMessageTextFragment() const override; + std::u16string message_text_fragment_; +}; +} // namespace permissions + +#endif // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_FILE_HANDLING_PERMISSION_REQUEST_IMPL_H_ diff --git a/chrome/browser/web_applications/components/web_app_utils.cc b/chrome/browser/web_applications/components/web_app_utils.cc index 5f91d23f48556..dde204bb82ca2 100644 --- a/chrome/browser/web_applications/components/web_app_utils.cc +++ b/chrome/browser/web_applications/components/web_app_utils.cc @@ -5,10 +5,18 @@ #include "chrome/browser/web_applications/components/web_app_utils.h" #include "base/files/file_path.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/web_applications/components/app_registrar.h" +#include "chrome/browser/web_applications/components/web_app_provider_base.h" #include "chrome/common/chrome_constants.h" +#include "chrome/grit/generated_resources.h" +#include "components/services/app_service/public/cpp/file_handler.h" #include "components/site_engagement/content/site_engagement_service.h" +#include "ui/base/l10n/l10n_util.h" +#include "url/gurl.h" #if BUILDFLAG(IS_CHROMEOS_ASH) #include "base/feature_list.h" @@ -131,4 +139,25 @@ bool IsChromeOs() { #endif } +std::vector GetFileExtensionsHandledByWebApp(Profile* profile, + const GURL& url) { + auto* provider = WebAppProviderBase::GetProviderBase(profile); + const AppRegistrar& registrar = provider->registrar(); + const apps::FileHandlers* handlers = + registrar.GetAppFileHandlers(*registrar.FindAppWithUrlInScope(url)); + DCHECK(handlers); + std::set extensions = + apps::GetFileExtensionsFromFileHandlers(*handlers); + return std::vector(extensions.begin(), extensions.end()); +} + +std::u16string GetFileExtensionsHandledByWebAppDisplayedAsList( + Profile* profile, + const GURL& url) { + return base::UTF8ToUTF16(base::JoinString( + GetFileExtensionsHandledByWebApp(profile, url), + l10n_util::GetStringUTF8( + IDS_WEB_APP_FILE_HANDLING_EXTENSION_LIST_SEPARATOR))); +} + } // namespace web_app diff --git a/chrome/browser/web_applications/components/web_app_utils.h b/chrome/browser/web_applications/components/web_app_utils.h index 6955d1b0f13fb..a083f0f1f9dd9 100644 --- a/chrome/browser/web_applications/components/web_app_utils.h +++ b/chrome/browser/web_applications/components/web_app_utils.h @@ -6,9 +6,11 @@ #define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_UTILS_H_ #include +#include #include "chrome/browser/web_applications/components/web_app_id.h" +class GURL; class Profile; namespace base { @@ -69,6 +71,18 @@ std::string GetProfileCategoryForLogging(Profile* profile); // Returns true if the WebApp should have `web_app::WebAppChromeOsData()`. bool IsChromeOs(); +// Returns a vector of file extensions of the form ".csv" which are handled by +// the app for `url`. It is an error to call this with a URL that doesn't +// correspond to an app in `profile`. +std::vector GetFileExtensionsHandledByWebApp(Profile* profile, + const GURL& url); + +// Returns a display-ready string that holds all the file extensions handled by +// the app for `url`. It is an error to call this with a URL that doesn't +// correspond to an app in `profile`. +std::u16string GetFileExtensionsHandledByWebAppDisplayedAsList(Profile* profile, + const GURL& url); + } // namespace web_app #endif // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_UTILS_H_ diff --git a/components/permissions/BUILD.gn b/components/permissions/BUILD.gn index 44a59ca4e57f3..7639bb137b6bc 100644 --- a/components/permissions/BUILD.gn +++ b/components/permissions/BUILD.gn @@ -21,8 +21,6 @@ source_set("permissions") { "contexts/clipboard_read_write_permission_context.h", "contexts/clipboard_sanitized_write_permission_context.cc", "contexts/clipboard_sanitized_write_permission_context.h", - "contexts/file_handling_permission_context.cc", - "contexts/file_handling_permission_context.h", "contexts/font_access_permission_context.cc", "contexts/font_access_permission_context.h", "contexts/geolocation_permission_context.cc", diff --git a/components/permissions/contexts/file_handling_permission_context.cc b/components/permissions/contexts/file_handling_permission_context.cc deleted file mode 100644 index c1f7d2bac795b..0000000000000 --- a/components/permissions/contexts/file_handling_permission_context.cc +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2021 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 "components/permissions/contexts/file_handling_permission_context.h" - -#include "components/content_settings/core/common/content_settings_types.h" -#include "third_party/blink/public/mojom/permissions_policy/permissions_policy.mojom.h" - -FileHandlingPermissionContext::FileHandlingPermissionContext( - content::BrowserContext* browser_context) - : PermissionContextBase(browser_context, - ContentSettingsType::FILE_HANDLING, - blink::mojom::PermissionsPolicyFeature::kNotFound) { -} - -FileHandlingPermissionContext::~FileHandlingPermissionContext() = default; - -bool FileHandlingPermissionContext::IsRestrictedToSecureOrigins() const { - return true; -} diff --git a/components/permissions/permission_context_base.cc b/components/permissions/permission_context_base.cc index 2d8b6a5f3cec1..d98bac37cb4d0 100644 --- a/components/permissions/permission_context_base.cc +++ b/components/permissions/permission_context_base.cc @@ -219,6 +219,20 @@ void PermissionContextBase::UserMadePermissionDecision( const GURL& embedding_origin, ContentSetting content_setting) {} +std::unique_ptr +PermissionContextBase::CreatePermissionRequest( + const GURL& request_origin, + ContentSettingsType content_settings_type, + bool has_gesture, + content::WebContents* web_contents, + PermissionRequestImpl::PermissionDecidedCallback + permission_decided_callback, + base::OnceClosure delete_callback) const { + return std::make_unique( + request_origin, content_settings_type, has_gesture, + std::move(permission_decided_callback), std::move(delete_callback)); +} + PermissionResult PermissionContextBase::GetPermissionStatus( content::RenderFrameHost* render_frame_host, const GURL& requesting_origin, @@ -373,14 +387,13 @@ void PermissionContextBase::DecidePermission( if (!permission_request_manager) return; - std::unique_ptr request_ptr = - std::make_unique( - requesting_origin, content_settings_type_, user_gesture, - base::BindOnce(&PermissionContextBase::PermissionDecided, - weak_factory_.GetWeakPtr(), id, requesting_origin, - embedding_origin, std::move(callback)), - base::BindOnce(&PermissionContextBase::CleanUpRequest, - weak_factory_.GetWeakPtr(), id)); + std::unique_ptr request_ptr = CreatePermissionRequest( + requesting_origin, content_settings_type_, user_gesture, web_contents, + base::BindOnce(&PermissionContextBase::PermissionDecided, + weak_factory_.GetWeakPtr(), id, requesting_origin, + embedding_origin, std::move(callback)), + base::BindOnce(&PermissionContextBase::CleanUpRequest, + weak_factory_.GetWeakPtr(), id)); PermissionRequest* request = request_ptr.get(); bool inserted = diff --git a/components/permissions/permission_context_base.h b/components/permissions/permission_context_base.h index d310912d82380..93b981d2c3878 100644 --- a/components/permissions/permission_context_base.h +++ b/components/permissions/permission_context_base.h @@ -17,6 +17,7 @@ #include "components/content_settings/core/common/content_settings_types.h" #include "components/keyed_service/core/keyed_service.h" #include "components/permissions/permission_request.h" +#include "components/permissions/permission_request_impl.h" #include "components/permissions/permission_result.h" #include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-forward.h" @@ -183,6 +184,17 @@ class PermissionContextBase : public KeyedService, const ContentSettingsPattern& secondary_pattern, ContentSettingsType content_type) override; + // Implementors can override this method to use a different PermissionRequest + // implementation. + virtual std::unique_ptr CreatePermissionRequest( + const GURL& request_origin, + ContentSettingsType content_settings_type, + bool has_gesture, + content::WebContents* web_contents, + PermissionRequestImpl::PermissionDecidedCallback + permission_decided_callback, + base::OnceClosure delete_callback) const; + ContentSettingsType content_settings_type() const { return content_settings_type_; } diff --git a/components/permissions/permission_request_impl.cc b/components/permissions/permission_request_impl.cc index 918449e614212..843d29159f322 100644 --- a/components/permissions/permission_request_impl.cc +++ b/components/permissions/permission_request_impl.cc @@ -186,9 +186,6 @@ std::u16string PermissionRequestImpl::GetMessageTextFragment() const { case ContentSettingsType::IDLE_DETECTION: message_id = IDS_IDLE_DETECTION_PERMISSION_FRAGMENT; break; - case ContentSettingsType::FILE_HANDLING: - message_id = IDS_FILE_HANDLING_PERMISSION_FRAGMENT; - break; default: NOTREACHED(); return std::u16string(); diff --git a/components/permissions/permission_request_impl.h b/components/permissions/permission_request_impl.h index 2195d6f9f30fb..8f8645cdec357 100644 --- a/components/permissions/permission_request_impl.h +++ b/components/permissions/permission_request_impl.h @@ -35,14 +35,18 @@ class PermissionRequestImpl : public PermissionRequest { ~PermissionRequestImpl() override; +// PermissionRequest: +#if !defined(OS_ANDROID) + // Implementors can override this method to customize the message text. + std::u16string GetMessageTextFragment() const override; +#endif + private: - // PermissionRequest: RequestType GetRequestType() const override; #if defined(OS_ANDROID) std::u16string GetMessageText() const override; #else base::Optional GetChipText() const override; - std::u16string GetMessageTextFragment() const override; #endif GURL GetOrigin() const override; void PermissionGranted(bool is_one_time) override; diff --git a/components/permissions_strings.grdp b/components/permissions_strings.grdp index c3d43fe4a04ec..847c24e04e706 100644 --- a/components/permissions_strings.grdp +++ b/components/permissions_strings.grdp @@ -140,10 +140,6 @@ This will otherwise be blocked by your privacy settings. This will allow the con Allow $1google.com to: - - Open files with file type associations. - - Use your location? diff --git a/components/permissions_strings_grdp/IDS_FILE_HANDLING_PERMISSION_FRAGMENT.png.sha1 b/components/permissions_strings_grdp/IDS_FILE_HANDLING_PERMISSION_FRAGMENT.png.sha1 deleted file mode 100644 index 72ab8b24a86c6..0000000000000 --- a/components/permissions_strings_grdp/IDS_FILE_HANDLING_PERMISSION_FRAGMENT.png.sha1 +++ /dev/null @@ -1 +0,0 @@ -55ddb345d69ee2187e402f22579fc4459b9563d1 \ No newline at end of file