[M120 Migration]Fix for crash during chrome exit
[platform/framework/web/chromium-efl.git] / chrome / browser / command_updater_impl.cc
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.
4
5 #include "chrome/browser/command_updater_impl.h"
6
7 #include <algorithm>
8
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"
14
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;
19 };
20
21 CommandUpdaterImpl::CommandUpdaterImpl(CommandUpdaterDelegate* delegate)
22     : delegate_(delegate) {
23 }
24
25 CommandUpdaterImpl::~CommandUpdaterImpl() {
26 }
27
28 bool CommandUpdaterImpl::SupportsCommand(int id) const {
29   return commands_.find(id) != commands_.end();
30 }
31
32 bool CommandUpdaterImpl::IsCommandEnabled(int id) const {
33   auto command = commands_.find(id);
34   if (command == commands_.end() || command->second->enabled == absl::nullopt)
35     return false;
36   return *command->second->enabled;
37 }
38
39 bool CommandUpdaterImpl::ExecuteCommand(int id, base::TimeTicks time_stamp) {
40   return ExecuteCommandWithDisposition(id, WindowOpenDisposition::CURRENT_TAB,
41                                        time_stamp);
42 }
43
44 bool CommandUpdaterImpl::ExecuteCommandWithDisposition(
45     int id,
46     WindowOpenDisposition disposition,
47     base::TimeTicks time_stamp) {
48   if (SupportsCommand(id) && IsCommandEnabled(id)) {
49     delegate_->ExecuteCommandWithDisposition(id, disposition);
50     return true;
51   }
52   return false;
53 }
54
55 void CommandUpdaterImpl::AddCommandObserver(int id, CommandObserver* observer) {
56   GetCommand(id, true)->observers.AddObserver(observer);
57 }
58
59 void CommandUpdaterImpl::RemoveCommandObserver(
60     int id, CommandObserver* observer) {
61   GetCommand(id, false)->observers.RemoveObserver(observer);
62 }
63
64 void CommandUpdaterImpl::RemoveCommandObserver(CommandObserver* observer) {
65   for (const auto& command_pair : commands_) {
66     Command* command = command_pair.second.get();
67     if (command)
68       command->observers.RemoveObserver(observer);
69   }
70 }
71
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);
79   return true;
80 }
81
82 void CommandUpdaterImpl::DisableAllCommands() {
83   for (const auto& command_pair : commands_)
84     UpdateCommandEnabled(command_pair.first, false);
85 }
86
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);
91   return result;
92 }
93
94 CommandUpdaterImpl::Command*
95 CommandUpdaterImpl::GetCommand(int id, bool create) {
96   bool supported = SupportsCommand(id);
97   if (supported)
98     return commands_[id].get();
99
100   DCHECK(create);
101   std::unique_ptr<Command>& entry = commands_[id];
102   entry = std::make_unique<Command>();
103   return entry.get();
104 }