1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/command_updater_impl.h"
9 #include "base/check.h"
10 #include "base/observer_list.h"
11 #include "chrome/browser/command_observer.h"
12 #include "chrome/browser/command_updater_delegate.h"
13 #include "third_party/abseil-cpp/absl/types/optional.h"
15 struct CommandUpdaterImpl::Command {
16 // Empty optional means not specified yet and thus implicitly disabled.
17 absl::optional<bool> enabled;
18 base::ObserverList<CommandObserver>::Unchecked observers;
21 CommandUpdaterImpl::CommandUpdaterImpl(CommandUpdaterDelegate* delegate)
22 : delegate_(delegate) {
25 CommandUpdaterImpl::~CommandUpdaterImpl() {
28 bool CommandUpdaterImpl::SupportsCommand(int id) const {
29 return commands_.find(id) != commands_.end();
32 bool CommandUpdaterImpl::IsCommandEnabled(int id) const {
33 auto command = commands_.find(id);
34 if (command == commands_.end() || command->second->enabled == absl::nullopt)
36 return *command->second->enabled;
39 bool CommandUpdaterImpl::ExecuteCommand(int id, base::TimeTicks time_stamp) {
40 return ExecuteCommandWithDisposition(id, WindowOpenDisposition::CURRENT_TAB,
44 bool CommandUpdaterImpl::ExecuteCommandWithDisposition(
46 WindowOpenDisposition disposition,
47 base::TimeTicks time_stamp) {
48 if (SupportsCommand(id) && IsCommandEnabled(id)) {
49 delegate_->ExecuteCommandWithDisposition(id, disposition);
55 void CommandUpdaterImpl::AddCommandObserver(int id, CommandObserver* observer) {
56 GetCommand(id, true)->observers.AddObserver(observer);
59 void CommandUpdaterImpl::RemoveCommandObserver(
60 int id, CommandObserver* observer) {
61 GetCommand(id, false)->observers.RemoveObserver(observer);
64 void CommandUpdaterImpl::RemoveCommandObserver(CommandObserver* observer) {
65 for (const auto& command_pair : commands_) {
66 Command* command = command_pair.second.get();
68 command->observers.RemoveObserver(observer);
72 bool CommandUpdaterImpl::UpdateCommandEnabled(int id, bool enabled) {
73 Command* command = GetCommand(id, true);
74 if (command->enabled.has_value() && *command->enabled == enabled)
75 return true; // Nothing to do.
76 command->enabled = enabled;
77 for (auto& observer : command->observers)
78 observer.EnabledStateChangedForCommand(id, enabled);
82 void CommandUpdaterImpl::DisableAllCommands() {
83 for (const auto& command_pair : commands_)
84 UpdateCommandEnabled(command_pair.first, false);
87 std::vector<int> CommandUpdaterImpl::GetAllIds() {
88 std::vector<int> result;
89 for (const auto& command_pair : commands_)
90 result.push_back(command_pair.first);
94 CommandUpdaterImpl::Command*
95 CommandUpdaterImpl::GetCommand(int id, bool create) {
96 bool supported = SupportsCommand(id);
98 return commands_[id].get();
101 std::unique_ptr<Command>& entry = commands_[id];
102 entry = std::make_unique<Command>();