1 // Copyright 2010-2018, Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 // A class handling the IPC connection for the session b/w server and clients. 31 32 #ifndef MOZC_CLIENT_CLIENT_H_ 33 #define MOZC_CLIENT_CLIENT_H_ 34 35 #include <memory> 36 #include <string> 37 #include <vector> 38 39 #include "base/port.h" 40 #include "client/client_interface.h" 41 #include "protocol/commands.pb.h" 42 #include "testing/base/public/gunit_prod.h" 43 // for FRIEND_TEST() 44 45 namespace mozc { 46 class IPCClientFactoryInterface; 47 48 namespace config { 49 class Config; 50 } // config 51 52 namespace client { 53 54 // default ServerLauncher implemntation. 55 // This class uses fork&exec (linux/mac) and CreateProcess() (Windows) 56 // to launch server process 57 class ServerLauncher : public ServerLauncherInterface { 58 public: 59 bool StartServer(ClientInterface *client); 60 61 bool ForceTerminateServer(const string &name); 62 63 bool WaitServer(uint32 pid); 64 65 void OnFatal(ServerLauncherInterface::ServerErrorType type); 66 67 // specify server program. On Mac, we need to specify the server path 68 // using this method. set_server_program(const string & server_program)69 void set_server_program(const string &server_program) { 70 server_program_ = server_program; 71 } 72 73 // return server program server_program()74 const string &server_program() const { 75 return server_program_; 76 } 77 set_restricted(bool restricted)78 void set_restricted(bool restricted) { 79 restricted_ = restricted; 80 } 81 82 // Sets the flag of error dialog suppression. set_suppress_error_dialog(bool suppress)83 void set_suppress_error_dialog(bool suppress) { 84 suppress_error_dialog_ = suppress; 85 } 86 87 ServerLauncher(); 88 virtual ~ServerLauncher(); 89 90 private: 91 string server_program_; 92 bool restricted_; 93 bool suppress_error_dialog_; 94 }; 95 96 class Client : public ClientInterface { 97 public: 98 Client(); 99 virtual ~Client(); 100 void SetIPCClientFactory(IPCClientFactoryInterface *client_factory); 101 102 // set ServerLauncher. 103 // ServerLauncher is used as default 104 // NOTE: Client class takes the owership of start_server_handler. 105 void SetServerLauncher(ServerLauncherInterface *server_launcher); 106 107 bool IsValidRunLevel() const; 108 109 bool EnsureConnection(); 110 111 bool EnsureSession(); 112 113 bool CheckVersionOrRestartServer(); 114 115 bool SendKeyWithContext(const commands::KeyEvent &key, 116 const commands::Context &context, 117 commands::Output *output); 118 bool TestSendKeyWithContext(const commands::KeyEvent &key, 119 const commands::Context &context, 120 commands::Output *output); 121 bool SendCommandWithContext(const commands::SessionCommand &command, 122 const commands::Context &context, 123 commands::Output *output); 124 125 bool GetConfig(config::Config *config); 126 bool SetConfig(const config::Config &config); 127 128 bool ClearUserHistory(); 129 bool ClearUserPrediction(); 130 bool ClearUnusedUserPrediction(); 131 bool Shutdown(); 132 bool SyncData(); 133 bool Reload(); 134 bool Cleanup(); 135 136 bool NoOperation(); 137 bool PingServer() const; 138 139 void Reset(); 140 141 void EnableCascadingWindow(bool enable); 142 143 void set_timeout(int timeout); 144 void set_restricted(bool restricted); 145 void set_server_program(const string &server_program); 146 void set_suppress_error_dialog(bool suppress); 147 void set_client_capability(const commands::Capability &capability); 148 149 bool LaunchTool(const string &mode, const string &arg); 150 bool LaunchToolWithProtoBuf(const commands::Output &output); 151 // Converts Output message from server to corresponding mozc_tool arguments 152 // If launch_tool_mode is not set or NO_TOOL is set or an invalid value is 153 // set, this function will return false and do nothing. 154 static bool TranslateProtoBufToMozcToolArg(const commands::Output &output, 155 string *mode); 156 157 bool OpenBrowser(const string &url); 158 159 private: 160 FRIEND_TEST(SessionPlaybackTest, PushAndResetHistoryWithNoModeTest); 161 FRIEND_TEST(SessionPlaybackTest, PushAndResetHistoryWithModeTest); 162 FRIEND_TEST(SessionPlaybackTest, PushAndResetHistoryWithDirectTest); 163 FRIEND_TEST(SessionPlaybackTest, PlaybackHistoryTest); 164 FRIEND_TEST(SessionPlaybackTest, SetModeInitializerTest); 165 FRIEND_TEST(SessionPlaybackTest, ConsumedTest); 166 167 enum ServerStatus { 168 SERVER_UNKNOWN, // initial status 169 SERVER_SHUTDOWN, // server is currently not working 170 SERVER_INVALID_SESSION, // current session is not available 171 SERVER_OK, // both server and session are health 172 SERVER_TIMEOUT, // server is blocked 173 SERVER_VERSION_MISMATCH, // server version is different 174 SERVER_BROKEN_MESSAGE, // server's message is broken 175 SERVER_FATAL // cannot start server (binary is broken/missing) 176 }; 177 178 // Dump the recent user inputs to specified file with label 179 // This is used for debugging 180 void DumpHistorySnapshot(const string &filename, 181 const string &label) const; 182 183 // Start server: 184 // return true if server is launched sucessfully or server is already running. 185 // return false if server cannot be launched. 186 // If server_program is empty, which is default setting, the path to 187 // GoogleJapaneseInputConverter is determined automatically. 188 // Windows: "C:\Program Files\Google\Google Japanese Input\" 189 // Linux/Mac: searching from default path 190 bool StartServer(); 191 192 // Displays a message box to notify the user of fatal error. 193 void OnFatal(ServerLauncherInterface::ServerErrorType type); 194 195 // Initialize input filling id and preferences. 196 void InitInput(commands::Input *input) const; 197 198 bool CreateSession(); 199 bool DeleteSession(); 200 bool CallCommand(commands::Input::CommandType type); 201 202 // This method automatically re-launch mozc_server and 203 // re-issue session id if it is not available. 204 bool EnsureCallCommand(commands::Input *input, 205 commands::Output *output); 206 207 // The most primitive Call method 208 // This method won't change the server_status_ even 209 // when version mismatch happens. In this case, 210 // just return false. 211 bool Call(const commands::Input &input, 212 commands::Output *output); 213 214 // first invoke Call() command and check the 215 // protocol_version. When protocol version mismatch, 216 // client goes to FATAL state 217 bool CallAndCheckVersion(const commands::Input &input, 218 commands::Output *output); 219 220 // Making a journal inputs to restore 221 // the current state even when mozc_server crashes 222 void PlaybackHistory(); 223 void PushHistory(const commands::Input &input, 224 const commands::Output &output); 225 void ResetHistory(); 226 227 // The alias of 228 // DumpHistorySnapshot("query_of_death.log", "QUERY OF DEATH"); 229 // and history_inputs_.clear(); 230 void DumpQueryOfDeath(); 231 232 // Execute |input| and check the version by seeing the 233 // initial response. If a new version is available, automatically 234 // restart the server and exectute the same input command again. 235 // If any errors happen inside the version up, shows an error dialog 236 // and returns false. 237 bool CheckVersionOrRestartServerInternal(const commands::Input &input, 238 commands::Output *output); 239 240 // for unittest 241 // copy the history inputs to |result|. 242 void GetHistoryInputs(std::vector<commands::Input> *result) const; 243 244 uint64 id_; 245 IPCClientFactoryInterface *client_factory_; 246 std::unique_ptr<ServerLauncherInterface> server_launcher_; 247 std::unique_ptr<char[]> result_; 248 std::unique_ptr<config::Config> preferences_; 249 int timeout_; 250 ServerStatus server_status_; 251 uint32 server_protocol_version_; 252 uint32 server_process_id_; 253 string server_product_version_; 254 std::vector<commands::Input> history_inputs_; 255 // Remember the composition mode of input session for playback. 256 commands::CompositionMode last_mode_; 257 commands::Capability client_capability_; 258 }; 259 260 } // namespace client 261 } // namespace mozc 262 #endif // MOZC_CLIENT_CLIENT_H_ 263