1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef ASH_IME_IME_CONTROLLER_IMPL_H_
6 #define ASH_IME_IME_CONTROLLER_IMPL_H_
7 
8 #include <memory>
9 #include <vector>
10 
11 #include "ash/ash_export.h"
12 #include "ash/public/cpp/cast_config_controller.h"
13 #include "ash/public/cpp/ime_controller.h"
14 #include "ash/public/cpp/ime_controller_client.h"
15 #include "ash/public/cpp/ime_info.h"
16 #include "base/macros.h"
17 #include "base/observer_list.h"
18 #include "mojo/public/cpp/bindings/pending_receiver.h"
19 #include "mojo/public/cpp/bindings/pending_remote.h"
20 #include "mojo/public/cpp/bindings/receiver_set.h"
21 #include "mojo/public/cpp/bindings/remote.h"
22 #include "ui/base/ime/chromeos/ime_keyset.h"
23 #include "ui/display/display_observer.h"
24 
25 namespace ui {
26 class Accelerator;
27 }
28 
29 namespace ash {
30 
31 class ModeIndicatorObserver;
32 
33 // Connects ash IME users (e.g. the system tray) to the IME implementation,
34 // which might live in Chrome browser or in a separate mojo service.
35 class ASH_EXPORT ImeControllerImpl : public ImeController,
36                                      public display::DisplayObserver,
37                                      public CastConfigController::Observer {
38  public:
39   class Observer {
40    public:
41     // Called when the caps lock state has changed.
42     virtual void OnCapsLockChanged(bool enabled) = 0;
43 
44     // Called when the keyboard layout name has changed.
45     virtual void OnKeyboardLayoutNameChanged(
46         const std::string& layout_name) = 0;
47   };
48 
49   ImeControllerImpl();
50   ~ImeControllerImpl() override;
51 
52   void AddObserver(Observer* observer);
53   void RemoveObserver(Observer* observer);
54 
current_ime()55   const ImeInfo& current_ime() const { return current_ime_; }
56 
available_imes()57   const std::vector<ImeInfo>& available_imes() const { return available_imes_; }
58 
is_extra_input_options_enabled()59   bool is_extra_input_options_enabled() const {
60     return is_extra_input_options_enabled_;
61   }
is_emoji_enabled()62   bool is_emoji_enabled() const { return is_emoji_enabled_; }
is_handwriting_enabled()63   bool is_handwriting_enabled() const { return is_handwriting_enabled_; }
is_voice_enabled()64   bool is_voice_enabled() const { return is_voice_enabled_; }
65 
managed_by_policy()66   bool managed_by_policy() const { return managed_by_policy_; }
is_menu_active()67   bool is_menu_active() const { return is_menu_active_; }
68 
current_ime_menu_items()69   const std::vector<ImeMenuItem>& current_ime_menu_items() const {
70     return current_ime_menu_items_;
71   }
72 
73   // Binds the mojo interface to this object.
74   void BindReceiver(mojo::PendingReceiver<ImeController> receiver);
75 
76   // Returns true if switching to next/previous IME is allowed.
77   bool CanSwitchIme() const;
78 
79   // Wrappers for ImeControllerClient methods.
80   void SwitchToNextIme();
81   void SwitchToLastUsedIme();
82   void SwitchImeById(const std::string& ime_id, bool show_message);
83   void ActivateImeMenuItem(const std::string& key);
84   void SetCapsLockEnabled(bool caps_enabled);
85   void OverrideKeyboardKeyset(chromeos::input_method::ImeKeyset keyset);
86   void OverrideKeyboardKeyset(
87       chromeos::input_method::ImeKeyset keyset,
88       ImeControllerClient::OverrideKeyboardKeysetCallback callback);
89 
90   // Returns true if the switch is allowed and the keystroke should be
91   // consumed.
92   bool CanSwitchImeWithAccelerator(const ui::Accelerator& accelerator) const;
93 
94   void SwitchImeWithAccelerator(const ui::Accelerator& accelerator);
95 
96   // ImeController:
97   void SetClient(ImeControllerClient* client) override;
98   void RefreshIme(const std::string& current_ime_id,
99                   std::vector<ImeInfo> available_imes,
100                   std::vector<ImeMenuItem> menu_items) override;
101   void SetImesManagedByPolicy(bool managed) override;
102   void ShowImeMenuOnShelf(bool show) override;
103   void UpdateCapsLockState(bool caps_enabled) override;
104   void OnKeyboardLayoutNameChanged(const std::string& layout_name) override;
105 
106   void SetExtraInputOptionsEnabledState(bool is_extra_input_options_enabled,
107                                         bool is_emoji_enabled,
108                                         bool is_handwriting_enabled,
109                                         bool is_voice_enabled) override;
110   // Show the mode indicator UI with the given text at the anchor bounds.
111   // The anchor bounds is in the universal screen coordinates in DIP.
112   void ShowModeIndicator(const gfx::Rect& anchor_bounds,
113                          const base::string16& ime_short_name) override;
114 
115   // display::DisplayObserver:
116   void OnDisplayMetricsChanged(const display::Display& display,
117                                uint32_t changed_metrics) override;
118 
119   // CastConfigController::Observer:
120   void OnDevicesUpdated(const std::vector<SinkAndRoute>& devices) override;
121 
122   // Synchronously returns the cached caps lock state.
123   bool IsCapsLockEnabled() const;
124 
125   // Synchronously returns the cached keyboard layout name
keyboard_layout_name()126   const std::string& keyboard_layout_name() const {
127     return keyboard_layout_name_;
128   }
129 
mode_indicator_observer()130   ModeIndicatorObserver* mode_indicator_observer() const {
131     return mode_indicator_observer_.get();
132   }
133 
134  private:
135   // Returns the IDs of the subset of input methods which are active and are
136   // associated with |accelerator|. For example, two Japanese IMEs can be
137   // returned for ui::VKEY_DBE_SBCSCHAR if both are active.
138   std::vector<std::string> GetCandidateImesForAccelerator(
139       const ui::Accelerator& accelerator) const;
140 
141   // Client interface back to IME code in chrome.
142   ImeControllerClient* client_ = nullptr;
143 
144   // Copy of the current IME so we can return it by reference.
145   ImeInfo current_ime_;
146 
147   // "Available" IMEs are both installed and enabled by the user in settings.
148   std::vector<ImeInfo> available_imes_;
149 
150   // True if the available IMEs are currently managed by enterprise policy.
151   // For example, can occur at the login screen with device-level policy.
152   bool managed_by_policy_ = false;
153 
154   // Additional menu items for properties of the currently selected IME.
155   std::vector<ImeMenuItem> current_ime_menu_items_;
156 
157   // A slightly delayed state value that is updated by asynchronously reported
158   // changes from the ImeControllerClient client (source of truth) which is in
159   // another process. This is required for synchronous method calls in ash.
160   bool is_caps_lock_enabled_ = false;
161 
162   // A slightly delayed state value that is updated by asynchronously reported
163   // changes from the ImeControllerClient client (source of truth) which is in
164   // another process. This is required for synchronous method calls in ash.
165   std::string keyboard_layout_name_;
166 
167   // True if the extended inputs should be available in general (emoji,
168   // handwriting, voice).
169   bool is_extra_input_options_enabled_ = false;
170 
171   // True if emoji input should be available from the IME menu.
172   bool is_emoji_enabled_ = false;
173 
174   // True if handwriting input should be available from the IME menu.
175   bool is_handwriting_enabled_ = false;
176 
177   // True if voice input should be available from the IME menu.
178   bool is_voice_enabled_ = false;
179 
180   // True if the IME menu is active. IME related items in system tray should be
181   // removed if |is_menu_active_| is true.
182   bool is_menu_active_ = false;
183 
184   base::ObserverList<Observer>::Unchecked observers_;
185 
186   std::unique_ptr<ModeIndicatorObserver> mode_indicator_observer_;
187 
188   DISALLOW_COPY_AND_ASSIGN(ImeControllerImpl);
189 };
190 
191 }  // namespace ash
192 
193 #endif  // ASH_IME_IME_CONTROLLER_H_
194