| // Copyright 2013 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/extension_commands_global_registry.h" |
| |
| #include "base/lazy_instance.h" |
| #include "base/uuid.h" |
| #include "chrome/browser/extensions/commands/command_service.h" |
| #include "chrome/browser/extensions/extension_keybinding_registry.h" |
| #include "components/prefs/pref_service.h" |
| #include "content/public/browser/browser_context.h" |
| #include "extensions/browser/pref_names.h" |
| #include "extensions/common/extension.h" |
| #include "ui/base/accelerators/command.h" |
| #include "ui/base/accelerators/global_accelerator_listener/global_accelerator_listener.h" |
| |
| namespace extensions { |
| |
| ExtensionCommandsGlobalRegistry::ExtensionCommandsGlobalRegistry( |
| content::BrowserContext* context) |
| : ExtensionKeybindingRegistry(context, |
| ExtensionKeybindingRegistry::ALL_EXTENSIONS, |
| nullptr), |
| browser_context_(context), |
| registry_for_active_window_(nullptr) { |
| Init(); |
| } |
| |
| ExtensionCommandsGlobalRegistry::~ExtensionCommandsGlobalRegistry() { |
| if (!IsEventTargetsEmpty()) { |
| ui::GlobalAcceleratorListener* global_shortcut_listener = |
| ui::GlobalAcceleratorListener::GetInstance(); |
| if (!global_shortcut_listener) { |
| return; |
| } |
| |
| // Resume GlobalShortcutListener before we clean up if the shortcut handling |
| // is currently suspended. |
| if (global_shortcut_listener->IsShortcutHandlingSuspended()) { |
| global_shortcut_listener->SetShortcutHandlingSuspended(false); |
| } |
| |
| global_shortcut_listener->UnregisterAccelerators(this); |
| } |
| } |
| |
| static base::LazyInstance<BrowserContextKeyedAPIFactory< |
| ExtensionCommandsGlobalRegistry>>::DestructorAtExit |
| g_extension_commands_global_registry_factory = LAZY_INSTANCE_INITIALIZER; |
| |
| // static |
| BrowserContextKeyedAPIFactory<ExtensionCommandsGlobalRegistry>* |
| ExtensionCommandsGlobalRegistry::GetFactoryInstance() { |
| return g_extension_commands_global_registry_factory.Pointer(); |
| } |
| |
| // static |
| ExtensionCommandsGlobalRegistry* ExtensionCommandsGlobalRegistry::Get( |
| content::BrowserContext* context) { |
| return BrowserContextKeyedAPIFactory<ExtensionCommandsGlobalRegistry>::Get( |
| context); |
| } |
| |
| bool ExtensionCommandsGlobalRegistry::IsRegistered( |
| const ui::Accelerator& accelerator) { |
| return (registry_for_active_window() && |
| registry_for_active_window()->IsAcceleratorRegistered(accelerator)) || |
| IsAcceleratorRegistered(accelerator); |
| } |
| |
| bool ExtensionCommandsGlobalRegistry::PopulateCommands( |
| const Extension* extension, |
| ui::CommandMap* commands) { |
| auto* instance = ui::GlobalAcceleratorListener::GetInstance(); |
| if (!instance) { |
| return false; |
| } |
| |
| extensions::CommandService* command_service = |
| extensions::CommandService::Get(browser_context_); |
| if (instance->IsRegistrationHandledExternally()) { |
| if (!command_service->GetNamedCommands( |
| extension->id(), extensions::CommandService::ALL, |
| extensions::CommandService::ANY_SCOPE, commands)) { |
| return false; |
| } |
| PrefService* prefs = |
| ExtensionsBrowserClient::Get()->GetPrefServiceForContext( |
| browser_context_); |
| std::string profile_id = prefs->GetString(pref_names::kGlobalShortcutsUuid); |
| if (profile_id.empty()) { |
| auto uuid = base::Uuid::GenerateRandomV4(); |
| profile_id = uuid.AsLowercaseString(); |
| prefs->SetString(pref_names::kGlobalShortcutsUuid, profile_id); |
| } |
| instance->OnCommandsChanged(extension->id(), profile_id, *commands, this); |
| } |
| |
| // Add all the active global keybindings, if any. |
| if (!command_service->GetNamedCommands( |
| extension->id(), extensions::CommandService::ACTIVE, |
| extensions::CommandService::GLOBAL, commands)) { |
| return false; |
| } |
| return true; |
| } |
| |
| bool ExtensionCommandsGlobalRegistry::RegisterAccelerator( |
| const ui::Accelerator& accelerator, |
| const ExtensionId& extension_id, |
| const std::string& command_name) { |
| auto* instance = ui::GlobalAcceleratorListener::GetInstance(); |
| if (!instance) { |
| return false; |
| } |
| return instance->RegisterAccelerator(accelerator, this); |
| } |
| |
| void ExtensionCommandsGlobalRegistry::UnregisterAccelerator( |
| const ui::Accelerator& accelerator) { |
| auto* instance = ui::GlobalAcceleratorListener::GetInstance(); |
| if (!instance) { |
| return; |
| } |
| instance->UnregisterAccelerator(accelerator, this); |
| } |
| |
| void ExtensionCommandsGlobalRegistry::OnShortcutHandlingSuspended( |
| bool suspended) { |
| auto* instance = ui::GlobalAcceleratorListener::GetInstance(); |
| if (!instance) { |
| return; |
| } |
| instance->SetShortcutHandlingSuspended(suspended); |
| if (registry_for_active_window()) { |
| registry_for_active_window()->SetShortcutHandlingSuspended(suspended); |
| } |
| } |
| |
| void ExtensionCommandsGlobalRegistry::OnKeyPressed( |
| const ui::Accelerator& accelerator) { |
| ExtensionKeybindingRegistry::NotifyEventTargets(accelerator); |
| } |
| |
| void ExtensionCommandsGlobalRegistry::ExecuteCommand( |
| const ExtensionId& extension_id, |
| const std::string& command_id) { |
| CommandExecuted(extension_id, command_id); |
| } |
| |
| } // namespace extensions |