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