Browse Source

fix: navigator.keyboard.lock() not working (#31621)

Co-authored-by: Shelley Vohr <[email protected]>
trop[bot] 3 years ago
parent
commit
5735cb3cb0

+ 17 - 0
chromium_src/BUILD.gn

@@ -15,6 +15,8 @@ static_library("chrome") {
   sources = [
     "//chrome/browser/accessibility/accessibility_ui.cc",
     "//chrome/browser/accessibility/accessibility_ui.h",
+    "//chrome/browser/app_mode/app_mode_utils.cc",
+    "//chrome/browser/app_mode/app_mode_utils.h",
     "//chrome/browser/browser_process.cc",
     "//chrome/browser/browser_process.h",
     "//chrome/browser/devtools/devtools_contents_resizing_strategy.cc",
@@ -51,6 +53,20 @@ static_library("chrome") {
     "//chrome/browser/process_singleton.h",
     "//chrome/browser/ui/browser_dialogs.cc",
     "//chrome/browser/ui/browser_dialogs.h",
+    "//chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.cc",
+    "//chrome/browser/ui/exclusive_access/exclusive_access_bubble_type.h",
+    "//chrome/browser/ui/exclusive_access/exclusive_access_controller_base.cc",
+    "//chrome/browser/ui/exclusive_access/exclusive_access_controller_base.h",
+    "//chrome/browser/ui/exclusive_access/exclusive_access_manager.cc",
+    "//chrome/browser/ui/exclusive_access/exclusive_access_manager.h",
+    "//chrome/browser/ui/exclusive_access/fullscreen_controller.cc",
+    "//chrome/browser/ui/exclusive_access/fullscreen_controller.h",
+    "//chrome/browser/ui/exclusive_access/fullscreen_within_tab_helper.cc",
+    "//chrome/browser/ui/exclusive_access/fullscreen_within_tab_helper.h",
+    "//chrome/browser/ui/exclusive_access/keyboard_lock_controller.cc",
+    "//chrome/browser/ui/exclusive_access/keyboard_lock_controller.h",
+    "//chrome/browser/ui/exclusive_access/mouse_lock_controller.cc",
+    "//chrome/browser/ui/exclusive_access/mouse_lock_controller.h",
     "//chrome/browser/ui/views/autofill/autofill_popup_view_utils.cc",
     "//chrome/browser/ui/views/autofill/autofill_popup_view_utils.h",
     "//chrome/browser/ui/views/eye_dropper/eye_dropper.cc",
@@ -114,6 +130,7 @@ static_library("chrome") {
     "//components/keyed_service/content",
     "//components/paint_preview/buildflags",
     "//components/proxy_config",
+    "//components/services/language_detection/public/mojom",
     "//content/public/browser",
     "//services/strings",
   ]

+ 1 - 0
patches/chromium/.patches

@@ -109,3 +109,4 @@ fix_expose_decrementcapturercount_in_web_contents_impl.patch
 feat_add_data_parameter_to_processsingleton.patch
 mas_gate_private_enterprise_APIs
 load_v8_snapshot_in_browser_process.patch
+fix_patch_out_permissions_checks_in_exclusive_access.patch

+ 51 - 0
patches/chromium/fix_patch_out_permissions_checks_in_exclusive_access.patch

@@ -0,0 +1,51 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Shelley Vohr <[email protected]>
+Date: Mon, 25 Oct 2021 21:45:57 +0200
+Subject: fix: patch out permissions checks in exclusive_access
+
+This patch is necessary in order to properly enable
+navigator.keyboard.{(un)?lock}() functionality. We don't have a concept
+of PermissionManager nor of a Profile, so this would not affect usage of
+the API.
+
+We might consider potentially using our own permissions handler,
+but it's not strictly necessary for this API to work to spec.
+
+Profile check has been upstreamed at https://chromium-review.googlesource.com/c/chromium/src/+/3247196
+
+diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
+index e9c8a4a4bb7334682ceeec05b3a3e872de0192ab..861307591f3721c398c454126cb5a9be9a5e9764 100644
+--- a/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
++++ b/chrome/browser/ui/exclusive_access/fullscreen_controller.cc
+@@ -368,13 +368,9 @@ void FullscreenController::EnterFullscreenModeInternal(
+   // Do not enter fullscreen mode if disallowed by pref. This prevents the user
+   // from manually entering fullscreen mode and also disables kiosk mode on
+   // desktop platforms.
+-  if (!exclusive_access_manager()
+-           ->context()
+-           ->GetProfile()
+-           ->GetPrefs()
+-           ->GetBoolean(prefs::kFullscreenAllowed)) {
++  auto* profile = exclusive_access_manager()->context()->GetProfile();
++  if (!profile || !profile->GetPrefs()->GetBoolean(prefs::kFullscreenAllowed))
+     return;
+-  }
+ #endif
+ 
+   toggled_into_fullscreen_ = true;
+@@ -387,6 +383,7 @@ void FullscreenController::EnterFullscreenModeInternal(
+       url = extension_caused_fullscreen_;
+   }
+ 
++#if 0
+   if (display_id != display::kInvalidDisplayId) {
+     // Check, but do not prompt, for permission to request a specific screen.
+     // Sites generally need permission to get the display id in the first place.
+@@ -400,6 +397,7 @@ void FullscreenController::EnterFullscreenModeInternal(
+       display_id = display::kInvalidDisplayId;
+     }
+   }
++#endif
+ 
+   if (option == BROWSER)
+     base::RecordAction(base::UserMetricsAction("ToggleFullscreen"));

+ 55 - 0
shell/browser/api/electron_api_web_contents.cc

@@ -26,6 +26,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/values.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
 #include "chrome/browser/ui/views/eye_dropper/eye_dropper.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
@@ -628,6 +629,7 @@ WebContents::WebContents(v8::Isolate* isolate,
       id_(GetAllWebContents().Add(this)),
       devtools_file_system_indexer_(
           base::MakeRefCounted<DevToolsFileSystemIndexer>()),
+      exclusive_access_manager_(std::make_unique<ExclusiveAccessManager>(this)),
       file_task_runner_(
           base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}))
 #if BUILDFLAG(ENABLE_PRINTING)
@@ -666,6 +668,7 @@ WebContents::WebContents(v8::Isolate* isolate,
       id_(GetAllWebContents().Add(this)),
       devtools_file_system_indexer_(
           base::MakeRefCounted<DevToolsFileSystemIndexer>()),
+      exclusive_access_manager_(std::make_unique<ExclusiveAccessManager>(this)),
       file_task_runner_(
           base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}))
 #if BUILDFLAG(ENABLE_PRINTING)
@@ -686,6 +689,7 @@ WebContents::WebContents(v8::Isolate* isolate,
     : id_(GetAllWebContents().Add(this)),
       devtools_file_system_indexer_(
           base::MakeRefCounted<DevToolsFileSystemIndexer>()),
+      exclusive_access_manager_(std::make_unique<ExclusiveAccessManager>(this)),
       file_task_runner_(
           base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}))
 #if BUILDFLAG(ENABLE_PRINTING)
@@ -1250,6 +1254,40 @@ void WebContents::ContentsZoomChange(bool zoom_in) {
   Emit("zoom-changed", zoom_in ? "in" : "out");
 }
 
+Profile* WebContents::GetProfile() {
+  return nullptr;
+}
+
+bool WebContents::IsFullscreen() const {
+  return owner_window_ && owner_window_->IsFullscreen();
+}
+
+void WebContents::EnterFullscreen(const GURL& url,
+                                  ExclusiveAccessBubbleType bubble_type,
+                                  const int64_t display_id) {}
+
+void WebContents::ExitFullscreen() {}
+
+void WebContents::UpdateExclusiveAccessExitBubbleContent(
+    const GURL& url,
+    ExclusiveAccessBubbleType bubble_type,
+    ExclusiveAccessBubbleHideCallback bubble_first_hide_callback,
+    bool force_update) {}
+
+void WebContents::OnExclusiveAccessUserInput() {}
+
+content::WebContents* WebContents::GetActiveWebContents() {
+  return web_contents();
+}
+
+bool WebContents::CanUserExitFullscreen() const {
+  return true;
+}
+
+bool WebContents::IsExclusiveAccessBubbleDisplayed() const {
+  return false;
+}
+
 void WebContents::EnterFullscreenModeForTab(
     content::RenderFrameHost* requesting_frame,
     const blink::mojom::FullscreenOptions& options) {
@@ -1260,6 +1298,8 @@ void WebContents::EnterFullscreenModeForTab(
       base::BindRepeating(&WebContents::OnEnterFullscreenModeForTab,
                           base::Unretained(this), requesting_frame, options);
   permission_helper->RequestFullscreenPermission(callback);
+  exclusive_access_manager_->fullscreen_controller()->EnterFullscreenModeForTab(
+      requesting_frame, options.display_id);
 }
 
 void WebContents::OnEnterFullscreenModeForTab(
@@ -1296,6 +1336,9 @@ void WebContents::ExitFullscreenModeForTab(content::WebContents* source) {
     // `chrome/browser/ui/exclusive_access/fullscreen_controller.cc`.
     source->GetRenderViewHost()->GetWidget()->SynchronizeVisualProperties();
   }
+
+  exclusive_access_manager_->fullscreen_controller()->ExitFullscreenModeForTab(
+      source);
 }
 
 void WebContents::RendererUnresponsive(
@@ -1344,6 +1387,18 @@ void WebContents::FindReply(content::WebContents* web_contents,
   Emit("found-in-page", result.GetHandle());
 }
 
+void WebContents::RequestKeyboardLock(content::WebContents* web_contents,
+                                      bool esc_key_locked) {
+  exclusive_access_manager_->keyboard_lock_controller()->RequestKeyboardLock(
+      web_contents, esc_key_locked);
+}
+
+void WebContents::CancelKeyboardLockRequest(
+    content::WebContents* web_contents) {
+  exclusive_access_manager_->keyboard_lock_controller()
+      ->CancelKeyboardLockRequest(web_contents);
+}
+
 bool WebContents::CheckMediaAccessPermission(
     content::RenderFrameHost* render_frame_host,
     const GURL& security_origin,

+ 28 - 1
shell/browser/api/electron_api_web_contents.h

@@ -16,6 +16,7 @@
 #include "base/observer_list_types.h"
 #include "chrome/browser/devtools/devtools_eye_dropper.h"
 #include "chrome/browser/devtools/devtools_file_system_indexer.h"
+#include "chrome/browser/ui/exclusive_access/exclusive_access_context.h"  // nogncheck
 #include "content/common/cursors/webcursor.h"
 #include "content/common/frame.mojom.h"
 #include "content/public/browser/devtools_agent_host.h"
@@ -74,6 +75,8 @@ namespace gin {
 class Arguments;
 }
 
+class ExclusiveAccessManager;
+
 namespace electron {
 
 class ElectronBrowserContext;
@@ -98,7 +101,8 @@ using DevicePermissionMap = std::map<
              std::map<url::Origin, std::vector<std::unique_ptr<base::Value>>>>>;
 
 // Wrapper around the content::WebContents.
-class WebContents : public gin::Wrappable<WebContents>,
+class WebContents : public ExclusiveAccessContext,
+                    public gin::Wrappable<WebContents>,
                     public gin_helper::EventEmitterMixin<WebContents>,
                     public gin_helper::Constructible<WebContents>,
                     public gin_helper::Pinnable<WebContents>,
@@ -548,6 +552,9 @@ class WebContents : public gin::Wrappable<WebContents>,
                  const gfx::Rect& selection_rect,
                  int active_match_ordinal,
                  bool final_update) override;
+  void RequestKeyboardLock(content::WebContents* web_contents,
+                           bool esc_key_locked) override;
+  void CancelKeyboardLockRequest(content::WebContents* web_contents) override;
   bool CheckMediaAccessPermission(content::RenderFrameHost* render_frame_host,
                                   const GURL& security_origin,
                                   blink::mojom::MediaStreamType type) override;
@@ -646,6 +653,24 @@ class WebContents : public gin::Wrappable<WebContents>,
   void EnumerateDirectory(content::WebContents* web_contents,
                           scoped_refptr<content::FileSelectListener> listener,
                           const base::FilePath& path) override;
+
+  // ExclusiveAccessContext:
+  Profile* GetProfile() override;
+  bool IsFullscreen() const override;
+  void EnterFullscreen(const GURL& url,
+                       ExclusiveAccessBubbleType bubble_type,
+                       const int64_t display_id) override;
+  void ExitFullscreen() override;
+  void UpdateExclusiveAccessExitBubbleContent(
+      const GURL& url,
+      ExclusiveAccessBubbleType bubble_type,
+      ExclusiveAccessBubbleHideCallback bubble_first_hide_callback,
+      bool force_update) override;
+  void OnExclusiveAccessUserInput() override;
+  content::WebContents* GetActiveWebContents() override;
+  bool CanUserExitFullscreen() const override;
+  bool IsExclusiveAccessBubbleDisplayed() const override;
+
   bool IsFullscreenForTabOrPending(const content::WebContents* source) override;
   blink::SecurityStyle GetSecurityStyle(
       content::WebContents* web_contents,
@@ -759,6 +784,8 @@ class WebContents : public gin::Wrappable<WebContents>,
 
   scoped_refptr<DevToolsFileSystemIndexer> devtools_file_system_indexer_;
 
+  std::unique_ptr<ExclusiveAccessManager> exclusive_access_manager_;
+
   std::unique_ptr<DevToolsEyeDropper> eye_dropper_;
 
   ElectronBrowserContext* browser_context_;

+ 3 - 0
shell/browser/electron_browser_client.cc

@@ -31,6 +31,7 @@
 #include "chrome/common/chrome_version.h"
 #include "components/net_log/chrome_net_log.h"
 #include "components/network_hints/common/network_hints.mojom.h"
+#include "content/browser/keyboard_lock/keyboard_lock_service_impl.h"  // nogncheck
 #include "content/browser/site_instance_impl.h"  // nogncheck
 #include "content/public/browser/browser_main_runner.h"
 #include "content/public/browser/browser_ppapi_host.h"
@@ -1572,6 +1573,8 @@ void ElectronBrowserClient::RegisterBrowserInterfaceBindersForFrame(
       base::BindRepeating(&badging::BadgeManager::BindFrameReceiver));
   map->Add<electron::mojom::ElectronBrowser>(
       base::BindRepeating(&BindElectronBrowser));
+  map->Add<blink::mojom::KeyboardLockService>(base::BindRepeating(
+      &content::KeyboardLockServiceImpl::CreateMojoService));
 #if BUILDFLAG(ENABLE_ELECTRON_EXTENSIONS)
   map->Add<extensions::mime_handler::MimeHandlerService>(
       base::BindRepeating(&BindMimeHandlerService));