blob: 1bb2f067c63aabd346a90f9dc94abea9812bb6ec [file] [log] [blame]
// 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