From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shelley Vohr <shelley.vohr@gmail.com>
Date: Mon, 16 Aug 2021 17:55:32 +0200
Subject: fix: media key usage with globalShortcuts

This patch enables media keys to work properly with Electron's globalShortcut
module. Chromium's default usage of RemoteCommandCenterDelegate on macOS falls
down into MPRemoteCommandCenter, which makes it such that an app will not
receive remote control events until it begins playing audio. This runs
counter to the design of globalShortcuts, and so we need to instead
use `ui::MediaKeysListener`.

diff --git a/chrome/browser/extensions/global_shortcut_listener.cc b/chrome/browser/extensions/global_shortcut_listener.cc
index bc009606d01469125052e68a9cdc82aaa697c764..ff18043cb07d748a49adea9874517fb29e3e7f9f 100644
--- a/chrome/browser/extensions/global_shortcut_listener.cc
+++ b/chrome/browser/extensions/global_shortcut_listener.cc
@@ -7,6 +7,7 @@
 #include "base/check.h"
 #include "base/notreached.h"
 #include "content/public/browser/browser_thread.h"
+#include "content/public/browser/media_keys_listener_manager.h"
 #include "ui/base/accelerators/accelerator.h"
 
 using content::BrowserThread;
@@ -66,6 +67,22 @@ void GlobalShortcutListener::UnregisterAccelerator(
     StopListening();
 }
 
+// static
+void GlobalShortcutListener::SetShouldUseInternalMediaKeyHandling(bool should_use) {
+  if (content::MediaKeysListenerManager::
+            IsMediaKeysListenerManagerEnabled()) {
+    content::MediaKeysListenerManager* media_keys_listener_manager =
+        content::MediaKeysListenerManager::GetInstance();
+    DCHECK(media_keys_listener_manager);
+
+    if (should_use) {
+      media_keys_listener_manager->EnableInternalMediaKeyHandling();
+    } else {
+      media_keys_listener_manager->DisableInternalMediaKeyHandling();
+    }
+  }
+}
+
 void GlobalShortcutListener::UnregisterAccelerators(Observer* observer) {
   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   if (IsShortcutHandlingSuspended())
diff --git a/chrome/browser/extensions/global_shortcut_listener.h b/chrome/browser/extensions/global_shortcut_listener.h
index 9aec54a3263d24491d24013a80b719dfc834ecd4..001a6cb2a5eb701351fa924109b43fab6f30748d 100644
--- a/chrome/browser/extensions/global_shortcut_listener.h
+++ b/chrome/browser/extensions/global_shortcut_listener.h
@@ -31,6 +31,8 @@ class GlobalShortcutListener {
 
   static GlobalShortcutListener* GetInstance();
 
+  static void SetShouldUseInternalMediaKeyHandling(bool should_use);
+
   // Register an observer for when a certain |accelerator| is struck. Returns
   // true if register successfully, or false if 1) the specificied |accelerator|
   // has been registered by another caller or other native applications, or
diff --git a/content/browser/media/media_keys_listener_manager_impl.cc b/content/browser/media/media_keys_listener_manager_impl.cc
index 5938f75742b793868638e693a9a8c8dc686dfc46..7f30f3fdd2c63612232e31c331b26b17ad729efb 100644
--- a/content/browser/media/media_keys_listener_manager_impl.cc
+++ b/content/browser/media/media_keys_listener_manager_impl.cc
@@ -55,7 +55,12 @@ bool MediaKeysListenerManagerImpl::StartWatchingMediaKey(
                                CanActiveMediaSessionControllerReceiveEvents();
 
   // Tell the underlying MediaKeysListener to listen for the key.
-  if (should_start_watching && media_keys_listener_ &&
+  if (
+#if defined(OS_MAC)
+      !media_key_handling_enabled_ &&
+#endif  // defined(OS_MAC)
+      should_start_watching &&
+      media_keys_listener_ &&
       !media_keys_listener_->StartWatchingMediaKey(key_code)) {
     return false;
   }
@@ -232,18 +237,18 @@ void MediaKeysListenerManagerImpl::StartListeningForMediaKeysIfNecessary() {
 #endif
 
   if (system_media_controls_) {
+    // This is required for proper functioning of MediaMetadata.
     system_media_controls_->AddObserver(this);
     system_media_controls_notifier_ =
         std::make_unique<SystemMediaControlsNotifier>(
             system_media_controls_.get());
-  } else {
-    // If we can't access system media controls, then directly listen for media
-    // key keypresses instead.
-    media_keys_listener_ = ui::MediaKeysListener::Create(
-        this, ui::MediaKeysListener::Scope::kGlobal);
-    DCHECK(media_keys_listener_);
   }
 
+  // Directly listen for media key keypresses when using GlobalShortcuts.
+  media_keys_listener_ = ui::MediaKeysListener::Create(
+    this, ui::MediaKeysListener::Scope::kGlobal);
+  DCHECK(media_keys_listener_);
+
   EnsureAuxiliaryServices();
 }
 
