Home | History | Annotate | Download | only in service
      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:
     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.
     64   Profile* profile() const { return profile_; }
     65 
     66   // Return true if this object is connected to the service.
     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 
    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