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