1 // Copyright 2018 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 CHROME_BROWSER_CHROMEOS_ARC_INPUT_METHOD_MANAGER_ARC_INPUT_METHOD_MANAGER_SERVICE_H_ 6 #define CHROME_BROWSER_CHROMEOS_ARC_INPUT_METHOD_MANAGER_ARC_INPUT_METHOD_MANAGER_SERVICE_H_ 7 8 #include <memory> 9 #include <set> 10 #include <string> 11 #include <vector> 12 13 #include "base/macros.h" 14 #include "base/observer_list_types.h" 15 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" 16 #include "chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_bridge.h" 17 #include "chrome/browser/chromeos/arc/input_method_manager/arc_input_method_state.h" 18 #include "chrome/browser/chromeos/arc/input_method_manager/input_connection_impl.h" 19 #include "chrome/browser/chromeos/input_method/input_method_engine.h" 20 #include "components/arc/mojom/input_method_manager.mojom-forward.h" 21 #include "components/keyed_service/content/browser_context_keyed_service_factory.h" 22 #include "components/keyed_service/core/keyed_service.h" 23 #include "ui/base/ime/chromeos/ime_bridge_observer.h" 24 #include "ui/base/ime/chromeos/input_method_manager.h" 25 26 namespace content { 27 class BrowserContext; 28 } // namespace content 29 30 namespace arc { 31 32 class ArcBridgeService; 33 34 class ArcInputMethodManagerService 35 : public KeyedService, 36 public ArcInputMethodManagerBridge::Delegate, 37 public chromeos::input_method::InputMethodManager::ImeMenuObserver, 38 public chromeos::input_method::InputMethodManager::Observer, 39 public ui::IMEBridgeObserver { 40 public: 41 class Observer : public base::CheckedObserver { 42 public: 43 virtual void OnAndroidVirtualKeyboardVisibilityChanged(bool visible) = 0; 44 }; 45 46 // Returns the instance for the given BrowserContext, or nullptr if the 47 // browser |context| is not allowed to use ARC. 48 static ArcInputMethodManagerService* GetForBrowserContext( 49 content::BrowserContext* context); 50 // Does the same as GetForBrowserContext() but for testing. Please refer to 51 // ArcBrowserContextKeyedServiceFactoryBase for the difference between them. 52 static ArcInputMethodManagerService* GetForBrowserContextForTesting( 53 content::BrowserContext* context); 54 55 static BrowserContextKeyedServiceFactory* GetFactory(); 56 57 ArcInputMethodManagerService(content::BrowserContext* context, 58 ArcBridgeService* bridge_service); 59 ~ArcInputMethodManagerService() override; 60 61 void SetInputMethodManagerBridgeForTesting( 62 std::unique_ptr<ArcInputMethodManagerBridge> test_bridge); 63 64 void AddObserver(Observer* observer); 65 void RemoveObserver(Observer* observer); 66 67 // KeyedService overrides: 68 void Shutdown() override; 69 70 // ArcInputMethodManagerBridge::Delegate overrides: 71 void OnActiveImeChanged(const std::string& ime_id) override; 72 void OnImeDisabled(const std::string& ime_id) override; 73 void OnImeInfoChanged(std::vector<mojom::ImeInfoPtr> ime_info_array) override; 74 void OnConnectionClosed() override; 75 76 // chromeos::input_method::InputMethodManager::ImeMenuObserver overrides: 77 void ImeMenuListChanged() override; ImeMenuActivationChanged(bool is_active)78 void ImeMenuActivationChanged(bool is_active) override {} ImeMenuItemsChanged(const std::string & engine_id,const std::vector<chromeos::input_method::InputMethodManager::MenuItem> & items)79 void ImeMenuItemsChanged( 80 const std::string& engine_id, 81 const std::vector<chromeos::input_method::InputMethodManager::MenuItem>& 82 items) override {} 83 84 // chromeos::input_method::InputMethodManager::Observer overrides: 85 void InputMethodChanged(chromeos::input_method::InputMethodManager* manager, 86 Profile* profile, 87 bool show_message) override; 88 89 // ui::IMEBridgeObserver overrides: OnRequestSwitchEngine()90 void OnRequestSwitchEngine() override {} 91 void OnInputContextHandlerChanged() override; 92 93 // Called when a11y keyboard option changed and disables ARC IME while a11y 94 // keyboard option is enabled. 95 void OnAccessibilityStatusChanged( 96 const chromeos::AccessibilityStatusEventDetails& event_details); 97 98 void OnArcInputMethodBoundsChanged(const gfx::Rect& bounds); 99 100 InputConnectionImpl* GetInputConnectionForTesting(); 101 102 private: 103 class ArcInputMethodBoundsObserver; 104 class InputMethodEngineObserver; 105 class InputMethodObserver; 106 class TabletModeObserver; 107 108 void EnableIme(const std::string& ime_id, bool enable); 109 void SwitchImeTo(const std::string& ime_id); 110 chromeos::input_method::InputMethodDescriptor BuildInputMethodDescriptor( 111 const mojom::ImeInfo* info); 112 void Focus(int input_context_id); 113 void Blur(); 114 void UpdateTextInputState(); 115 mojom::TextInputStatePtr GetTextInputState( 116 bool is_input_state_update_requested); 117 118 // Removes ARC IME from IME related prefs that are current active IME pref, 119 // previous active IME pref, enabled IME list pref and preloading IME list 120 // pref. 121 void RemoveArcIMEFromPrefs(); 122 void RemoveArcIMEFromPref(const char* pref_name); 123 124 void OnTabletModeToggled(bool enabled); 125 126 // Update the descriptors in IMM and the prefs according to 127 // |arc_ime_state_|. 128 void UpdateInputMethodEntryWithImeInfo(); 129 130 // Notifies InputMethodManager's observers of possible ARC IME state changes. 131 void NotifyInputMethodManagerObservers(bool is_tablet_mode); 132 133 bool IsVirtualKeyboardShown() const; 134 void SendShowVirtualKeyboard(); 135 void SendHideVirtualKeyboard(); 136 void NotifyVirtualKeyboardVisibilityChange(bool visible); 137 138 Profile* const profile_; 139 140 std::unique_ptr<ArcInputMethodManagerBridge> imm_bridge_; 141 std::set<std::string> active_arc_ime_ids_; 142 std::unique_ptr<ArcInputMethodState::Delegate> arc_ime_state_delegate_; 143 ArcInputMethodState arc_ime_state_; 144 bool is_virtual_keyboard_shown_; 145 // This flag is set to true while updating ARC IMEs entries in IMM to avoid 146 // exposing incomplete state. 147 bool is_updating_imm_entry_; 148 149 // ArcInputMethodManager installs a proxy IME to redirect IME related events 150 // from/to ARC IMEs in the container. The below two variables are for the 151 // proxy IME. 152 const std::string proxy_ime_extension_id_; 153 std::unique_ptr<chromeos::InputMethodEngine> proxy_ime_engine_; 154 155 // The currently active input method, observed for 156 // OnShowVirtualKeyboardIfEnabled. 157 ui::InputMethod* input_method_ = nullptr; 158 bool is_arc_ime_active_ = false; 159 160 std::unique_ptr<InputConnectionImpl> active_connection_; 161 162 std::unique_ptr<TabletModeObserver> tablet_mode_observer_; 163 164 std::unique_ptr<InputMethodObserver> input_method_observer_; 165 166 std::unique_ptr<ArcInputMethodBoundsObserver> input_method_bounds_observer_; 167 168 std::unique_ptr<chromeos::AccessibilityStatusSubscription> 169 accessibility_status_subscription_; 170 171 base::ObserverList<Observer> observers_; 172 173 DISALLOW_COPY_AND_ASSIGN(ArcInputMethodManagerService); 174 }; 175 176 } // namespace arc 177 178 #endif // CHROME_BROWSER_CHROMEOS_ARC_INPUT_METHOD_MANAGER_ARC_INPUT_METHOD_MANAGER_SERVICE_H_ 179