Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / service_process / service_process_control.h
1 // Copyright (c) 2012 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_SERVICE_PROCESS_SERVICE_PROCESS_CONTROL_H_
6 #define CHROME_BROWSER_SERVICE_PROCESS_SERVICE_PROCESS_CONTROL_H_
7
8 #include <queue>
9 #include <set>
10 #include <string>
11 #include <vector>
12
13 #include "base/basictypes.h"
14 #include "base/callback.h"
15 #include "base/cancelable_callback.h"
16 #include "base/id_map.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/memory/singleton.h"
19 #include "base/process/process.h"
20 #include "content/public/browser/notification_observer.h"
21 #include "content/public/browser/notification_registrar.h"
22 #include "ipc/ipc_channel_proxy.h"
23 #include "ipc/ipc_listener.h"
24 #include "ipc/ipc_sender.h"
25
26 namespace base {
27 class CommandLine;
28 }
29
30 namespace cloud_print {
31 struct CloudPrintProxyInfo;
32 }  // namespace cloud_print
33
34 // A ServiceProcessControl works as a portal between the service process and
35 // the browser process.
36 //
37 // It is used to start and terminate the service process. It is also used
38 // to send and receive IPC messages from the service process.
39 //
40 // THREADING
41 //
42 // This class is accessed on the UI thread through some UI actions. It then
43 // talks to the IPC channel on the IO thread.
44 class ServiceProcessControl : public IPC::Sender,
45                               public IPC::Listener,
46                               public content::NotificationObserver {
47  public:
48   enum ServiceProcessEvent {
49     SERVICE_EVENT_INITIALIZE,
50     SERVICE_EVENT_ENABLED_ON_LAUNCH,
51     SERVICE_EVENT_ENABLE,
52     SERVICE_EVENT_DISABLE,
53     SERVICE_EVENT_DISABLE_BY_POLICY,
54     SERVICE_EVENT_LAUNCH,
55     SERVICE_EVENT_LAUNCHED,
56     SERVICE_EVENT_LAUNCH_FAILED,
57     SERVICE_EVENT_CHANNEL_CONNECTED,
58     SERVICE_EVENT_CHANNEL_ERROR,
59     SERVICE_EVENT_INFO_REQUEST,
60     SERVICE_EVENT_INFO_REPLY,
61     SERVICE_EVENT_HISTOGRAMS_REQUEST,
62     SERVICE_EVENT_HISTOGRAMS_REPLY,
63     SERVICE_PRINTERS_REQUEST,
64     SERVICE_PRINTERS_REPLY,
65     SERVICE_EVENT_MAX,
66   };
67
68   typedef IDMap<ServiceProcessControl>::iterator iterator;
69   typedef std::queue<IPC::Message> MessageQueue;
70   typedef base::Callback<void(const cloud_print::CloudPrintProxyInfo&)>
71       CloudPrintProxyInfoCallback;
72   typedef base::Callback<void(const std::vector<std::string>&)>
73       PrintersCallback;
74
75   // Returns the singleton instance of this class.
76   static ServiceProcessControl* GetInstance();
77
78   // Return true if this object is connected to the service.
79   // Virtual for testing.
80   virtual bool IsConnected() const;
81
82   // If no service process is currently running, creates a new service process
83   // and connects to it. If a service process is already running this method
84   // will try to connect to it.
85   // |success_task| is called when we have successfully launched the process
86   // and connected to it.
87   // |failure_task| is called when we failed to connect to the service process.
88   // It is OK to pass the same value for |success_task| and |failure_task|. In
89   // this case, the task is invoked on success or failure.
90   // Note that if we are already connected to service process then
91   // |success_task| can be invoked in the context of the Launch call.
92   // Virtual for testing.
93   virtual void Launch(const base::Closure& success_task,
94                       const base::Closure& failure_task);
95
96   // Disconnect the IPC channel from the service process.
97   // Virtual for testing.
98   virtual void Disconnect();
99
100   // IPC::Listener implementation.
101   bool OnMessageReceived(const IPC::Message& message) override;
102   void OnChannelConnected(int32 peer_pid) override;
103   void OnChannelError() override;
104
105   // IPC::Sender implementation
106   bool Send(IPC::Message* message) override;
107
108   // content::NotificationObserver implementation.
109   void Observe(int type,
110                const content::NotificationSource& source,
111                const content::NotificationDetails& details) override;
112
113   // Send a shutdown message to the service process. IPC channel will be
114   // destroyed after calling this method.
115   // Return true if the message was sent.
116   // Virtual for testing.
117   virtual bool Shutdown();
118
119   // Send request for cloud print proxy info (enabled state, email, proxy id).
120   // The callback gets the information when received.
121   // Returns true if request was sent. Callback will be called only in case of
122   // reply from service. The method resets any previous callback.
123   // This call starts service if needed.
124   bool GetCloudPrintProxyInfo(
125       const CloudPrintProxyInfoCallback& cloud_print_status_callback);
126
127   // Send request for histograms collected in service process.
128   // Returns true if request was sent, and callback will be called in case of
129   // success or timeout. The method resets any previous callback.
130   // Returns false if service is not running or other failure, callback will not
131   // be called in this case.
132   bool GetHistograms(const base::Closure& cloud_print_status_callback,
133                      const base::TimeDelta& timeout);
134
135   // Send request for printers available for cloud print proxy.
136   // The callback gets the information when received.
137   // Returns true if request was sent. Callback will be called only in case of
138   // reply from service. The method resets any previous callback.
139   // This call starts service if needed.
140   bool GetPrinters(const PrintersCallback& enumerate_printers_callback);
141
142  private:
143   // This class is responsible for launching the service process on the
144   // PROCESS_LAUNCHER thread.
145   class Launcher
146       : public base::RefCountedThreadSafe<ServiceProcessControl::Launcher> {
147    public:
148     Launcher(ServiceProcessControl* process,
149              scoped_ptr<base::CommandLine> cmd_line);
150     // Execute the command line to start the process asynchronously. After the
151     // command is executed |task| is called with the process handle on the UI
152     // thread.
153     void Run(const base::Closure& task);
154
155     bool launched() const { return launched_; }
156
157    private:
158     friend class base::RefCountedThreadSafe<ServiceProcessControl::Launcher>;
159     virtual ~Launcher();
160
161 #if !defined(OS_MACOSX)
162     void DoDetectLaunched();
163 #endif  // !OS_MACOSX
164
165     void DoRun();
166     void Notify();
167     void CloseProcessHandle();
168     ServiceProcessControl* process_;
169     scoped_ptr<base::CommandLine> cmd_line_;
170     base::Closure notify_task_;
171     bool launched_;
172     uint32 retry_count_;
173     base::ProcessHandle process_handle_;
174   };
175
176   friend class MockServiceProcessControl;
177   friend class CloudPrintProxyPolicyStartupTest;
178
179   ServiceProcessControl();
180   ~ServiceProcessControl() override;
181
182   friend struct DefaultSingletonTraits<ServiceProcessControl>;
183
184   typedef std::vector<base::Closure> TaskList;
185
186   // Message handlers
187   void OnCloudPrintProxyInfo(
188       const cloud_print::CloudPrintProxyInfo& proxy_info);
189   void OnHistograms(const std::vector<std::string>& pickled_histograms);
190   void OnPrinters(const std::vector<std::string>& printers);
191
192   // Runs callback provided in |GetHistograms()|.
193   void RunHistogramsCallback();
194
195   // Helper method to invoke all the callbacks based on success or failure.
196   void RunConnectDoneTasks();
197
198   // Method called by Launcher when the service process is launched.
199   void OnProcessLaunched();
200
201   // Used internally to connect to the service process.
202   void ConnectInternal();
203
204   // Takes ownership of the pointer. Split out for testing.
205   void SetChannel(scoped_ptr<IPC::ChannelProxy> channel);
206
207   static void RunAllTasksHelper(TaskList* task_list);
208
209   // IPC channel to the service process.
210   scoped_ptr<IPC::ChannelProxy> channel_;
211
212   // Service process launcher.
213   scoped_refptr<Launcher> launcher_;
214
215   // Callbacks that get invoked when the channel is successfully connected.
216   TaskList connect_success_tasks_;
217   // Callbacks that get invoked when there was a connection failure.
218   TaskList connect_failure_tasks_;
219
220   // Callback that gets invoked when a printers is received from
221   // the cloud print proxy.
222   PrintersCallback printers_callback_;
223
224   // Callback that gets invoked when a status message is received from
225   // the cloud print proxy.
226   CloudPrintProxyInfoCallback cloud_print_info_callback_;
227
228   // Callback that gets invoked when a message with histograms is received from
229   // the service process.
230   base::Closure histograms_callback_;
231
232   content::NotificationRegistrar registrar_;
233
234   // Callback that gets invoked if service didn't reply in time.
235   base::CancelableClosure histograms_timeout_callback_;
236 };
237
238 #endif  // CHROME_BROWSER_SERVICE_PROCESS_SERVICE_PROCESS_CONTROL_H_