• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/id_map.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/process.h"
18 #include "base/task.h"
19 #include "content/common/notification_observer.h"
20 #include "content/common/notification_registrar.h"
21 #include "ipc/ipc_sync_channel.h"
22 
23 class Profile;
24 class CommandLine;
25 
26 namespace remoting {
27 struct ChromotingHostInfo;
28 }  // namespace remoting
29 
30 // A ServiceProcessControl works as a portal between the service process and
31 // the browser process.
32 //
33 // It is used to start and terminate the service process. It is also used
34 // to send and receive IPC messages from the service process.
35 //
36 // THREADING
37 //
38 // This class is accessed on the UI thread through some UI actions. It then
39 // talks to the IPC channel on the IO thread.
40 class ServiceProcessControl : public IPC::Channel::Sender,
41                               public IPC::Channel::Listener,
42                               public NotificationObserver {
43  public:
44   typedef IDMap<ServiceProcessControl>::iterator iterator;
45   typedef std::queue<IPC::Message> MessageQueue;
46   typedef Callback1<const remoting::ChromotingHostInfo&>::Type
47       RemotingHostStatusHandler;
48 
49   // An interface for handling messages received from the service process.
50   class MessageHandler {
51    public:
~MessageHandler()52     virtual ~MessageHandler() {}
53 
54     // Called when we receive reply to remoting host status request.
55     virtual void OnRemotingHostInfo(
56         const remoting::ChromotingHostInfo& host_info) = 0;
57   };
58 
59   // Construct a ServiceProcessControl with |profile|..
60   explicit ServiceProcessControl(Profile* profile);
61   virtual ~ServiceProcessControl();
62 
63   // Return the user profile associated with this service process.
profile()64   Profile* profile() const { return profile_; }
65 
66   // Return true if this object is connected to the service.
is_connected()67   bool is_connected() const { return channel_.get() != NULL; }
68 
69   // If no service process is currently running, creates a new service process
70   // and connects to it.
71   // If a service process is already running this method will try to connect
72   // to it.
73   // |success_task| is called when we have successfully launched the process
74   // and connected to it.
75   // |failure_task| is called when we failed to connect to the service process.
76   // It is OK to pass the same value for |success_task| and |failure_task|. In
77   // this case, the task is invoked on success or failure.
78   // Note that if we are already connected to service process then
79   // |success_task| can be invoked in the context of the Launch call.
80   // Takes ownership of |success_task| and |failure_task|.
81   void Launch(Task* success_task, Task* failure_task);
82 
83   // IPC::Channel::Listener implementation.
84   virtual bool OnMessageReceived(const IPC::Message& message);
85   virtual void OnChannelConnected(int32 peer_pid);
86   virtual void OnChannelError();
87 
88   // IPC::Channel::Sender implementation
89   virtual bool Send(IPC::Message* message);
90 
91   // NotificationObserver implementation.
92   virtual void Observe(NotificationType type,
93                        const NotificationSource& source,
94                        const NotificationDetails& details);
95 
96   // Message handlers
97   void OnCloudPrintProxyIsEnabled(bool enabled, std::string email);
98   void OnRemotingHostInfo(const remoting::ChromotingHostInfo& host_info);
99 
100   // Send a shutdown message to the service process. IPC channel will be
101   // destroyed after calling this method.
102   // Return true if the message was sent.
103   bool Shutdown();
104 
105   // Send request for cloud print proxy status and the registered
106   // email address. The callback gets the information when received.
107   bool GetCloudPrintProxyStatus(
108       Callback2<bool, std::string>::Type* cloud_print_status_callback);
109 
110   // Send a message to enable the remoting service in the service process.
111   // Return true if the message was sent.
112   bool SetRemotingHostCredentials(const std::string& user,
113                                   const std::string& auth_token);
114 
115   bool EnableRemotingHost();
116   bool DisableRemotingHost();
117 
118   // Send request for current status of the remoting service.
119   // MessageHandler::OnRemotingHostInfo() will be called when remoting host
120   // status is available.
121   bool RequestRemotingHostStatus();
122 
123   // Add a message handler for receiving messages from the service
124   // process.
125   void AddMessageHandler(MessageHandler* message_handler);
126 
127   // Remove a message handler from the list of message handlers. Must
128   // not be called from a message handler (i.e. while a message is
129   // being processed).
130   void RemoveMessageHandler(MessageHandler* message_handler);
131 
132  private:
133   // This class is responsible for launching the service process on the
134   // PROCESS_LAUNCHER thread.
135   class Launcher
136       : public base::RefCountedThreadSafe<ServiceProcessControl::Launcher> {
137    public:
138     Launcher(ServiceProcessControl* process, CommandLine* cmd_line);
139     // Execute the command line to start the process asynchronously.
140     // After the comamnd is executed |task| is called with the process handle on
141     // the UI thread.
142     void Run(Task* task);
143 
launched()144     bool launched() const { return launched_; }
145 
146    private:
147     friend class base::RefCountedThreadSafe<ServiceProcessControl::Launcher>;
148     virtual ~Launcher();
149 
150 #if !defined(OS_MACOSX)
151     void DoDetectLaunched();
152 #endif  // !OS_MACOSX
153 
154     void DoRun();
155     void Notify();
156     ServiceProcessControl* process_;
157     scoped_ptr<CommandLine> cmd_line_;
158     scoped_ptr<Task> notify_task_;
159     bool launched_;
160     uint32 retry_count_;
161   };
162 
163   typedef std::vector<Task*> TaskList;
164 
165   // Helper method to invoke all the callbacks based on success on failure.
166   void RunConnectDoneTasks();
167 
168   // Method called by Launcher when the service process is launched.
169   void OnProcessLaunched();
170 
171   // Used internally to connect to the service process.
172   void ConnectInternal();
173 
174   static void RunAllTasksHelper(TaskList* task_list);
175 
176   Profile* profile_;
177 
178   // IPC channel to the service process.
179   scoped_ptr<IPC::SyncChannel> channel_;
180 
181   // Service process launcher.
182   scoped_refptr<Launcher> launcher_;
183 
184   // Callbacks that get invoked when the channel is successfully connected or
185   // if there was a failure in connecting.
186   TaskList connect_done_tasks_;
187   // Callbacks that get invoked ONLY when the channel is successfully connected.
188   TaskList connect_success_tasks_;
189   // Callbacks that get invoked ONLY when there was a connection failure.
190   TaskList connect_failure_tasks_;
191 
192   // Callback that gets invoked when a status message is received from
193   // the cloud print proxy.
194   scoped_ptr<Callback2<bool, std::string>::Type> cloud_print_status_callback_;
195 
196   // Handler for messages from service process.
197   std::set<MessageHandler*> message_handlers_;
198 
199   NotificationRegistrar registrar_;
200 };
201 
202 #endif  // CHROME_BROWSER_SERVICE_SERVICE_PROCESS_CONTROL_H_
203