• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "chrome/service/service_ipc_server.h"
6 
7 #include "base/metrics/histogram_delta_serialization.h"
8 #include "chrome/common/service_messages.h"
9 #include "chrome/service/cloud_print/cloud_print_proxy.h"
10 #include "chrome/service/service_process.h"
11 #include "ipc/ipc_logging.h"
12 
ServiceIPCServer(const IPC::ChannelHandle & channel_handle)13 ServiceIPCServer::ServiceIPCServer(const IPC::ChannelHandle& channel_handle)
14     : channel_handle_(channel_handle), client_connected_(false) {
15 }
16 
Init()17 bool ServiceIPCServer::Init() {
18 #ifdef IPC_MESSAGE_LOG_ENABLED
19   IPC::Logging::GetInstance()->SetIPCSender(this);
20 #endif
21   sync_message_filter_ =
22       new IPC::SyncMessageFilter(g_service_process->shutdown_event());
23   CreateChannel();
24   return true;
25 }
26 
CreateChannel()27 void ServiceIPCServer::CreateChannel() {
28   channel_.reset(NULL); // Tear down the existing channel, if any.
29   channel_ = IPC::SyncChannel::Create(
30       channel_handle_,
31       IPC::Channel::MODE_NAMED_SERVER,
32       this,
33       g_service_process->io_thread()->message_loop_proxy().get(),
34       true,
35       g_service_process->shutdown_event());
36   DCHECK(sync_message_filter_.get());
37   channel_->AddFilter(sync_message_filter_.get());
38 }
39 
~ServiceIPCServer()40 ServiceIPCServer::~ServiceIPCServer() {
41 #ifdef IPC_MESSAGE_LOG_ENABLED
42   IPC::Logging::GetInstance()->SetIPCSender(NULL);
43 #endif
44 
45   channel_->RemoveFilter(sync_message_filter_.get());
46 }
47 
OnChannelConnected(int32 peer_pid)48 void ServiceIPCServer::OnChannelConnected(int32 peer_pid) {
49   DCHECK(!client_connected_);
50   client_connected_ = true;
51 }
52 
OnChannelError()53 void ServiceIPCServer::OnChannelError() {
54   // When a client (typically a browser process) disconnects, the pipe is
55   // closed and we get an OnChannelError. Since we want to keep servicing
56   // client requests, we will recreate the channel.
57   bool client_was_connected = client_connected_;
58   client_connected_ = false;
59   // TODO(sanjeevr): Instead of invoking the service process for such handlers,
60   // define a Client interface that the ServiceProcess can implement.
61   if (client_was_connected) {
62     if (g_service_process->HandleClientDisconnect()) {
63 #if defined(OS_WIN)
64       // On Windows, once an error on a named pipe occurs, the named pipe is no
65       // longer valid and must be re-created. This is not the case on Mac or
66       // Linux.
67       CreateChannel();
68 #endif
69     }
70   } else {
71     // If the client was never even connected we had an error connecting.
72     if (!client_connected_) {
73       LOG(ERROR) << "Unable to open service ipc channel "
74                  << "named: " << channel_handle_.name;
75     }
76   }
77 }
78 
Send(IPC::Message * msg)79 bool ServiceIPCServer::Send(IPC::Message* msg) {
80   if (!channel_.get()) {
81     delete msg;
82     return false;
83   }
84 
85   return channel_->Send(msg);
86 }
87 
OnMessageReceived(const IPC::Message & msg)88 bool ServiceIPCServer::OnMessageReceived(const IPC::Message& msg) {
89   bool handled = true;
90   // When we get a message, always mark the client as connected. The
91   // ChannelProxy::Context is only letting OnChannelConnected get called once,
92   // so on the Mac and Linux, we never would set client_connected_ to true
93   // again on subsequent connections.
94   client_connected_ = true;
95   IPC_BEGIN_MESSAGE_MAP(ServiceIPCServer, msg)
96     IPC_MESSAGE_HANDLER(ServiceMsg_EnableCloudPrintProxyWithRobot,
97                         OnEnableCloudPrintProxyWithRobot)
98     IPC_MESSAGE_HANDLER(ServiceMsg_DisableCloudPrintProxy,
99                         OnDisableCloudPrintProxy)
100     IPC_MESSAGE_HANDLER(ServiceMsg_GetCloudPrintProxyInfo,
101                         OnGetCloudPrintProxyInfo)
102     IPC_MESSAGE_HANDLER(ServiceMsg_GetHistograms, OnGetHistograms)
103     IPC_MESSAGE_HANDLER(ServiceMsg_GetPrinters, OnGetPrinters)
104     IPC_MESSAGE_HANDLER(ServiceMsg_Shutdown, OnShutdown);
105     IPC_MESSAGE_HANDLER(ServiceMsg_UpdateAvailable, OnUpdateAvailable);
106     IPC_MESSAGE_UNHANDLED(handled = false)
107   IPC_END_MESSAGE_MAP()
108   return handled;
109 }
110 
OnEnableCloudPrintProxyWithRobot(const std::string & robot_auth_code,const std::string & robot_email,const std::string & user_email,const base::DictionaryValue & user_settings)111 void ServiceIPCServer::OnEnableCloudPrintProxyWithRobot(
112     const std::string& robot_auth_code,
113     const std::string& robot_email,
114     const std::string& user_email,
115     const base::DictionaryValue& user_settings) {
116   g_service_process->GetCloudPrintProxy()->EnableForUserWithRobot(
117       robot_auth_code, robot_email, user_email, user_settings);
118 }
119 
OnGetCloudPrintProxyInfo()120 void ServiceIPCServer::OnGetCloudPrintProxyInfo() {
121   cloud_print::CloudPrintProxyInfo info;
122   g_service_process->GetCloudPrintProxy()->GetProxyInfo(&info);
123   channel_->Send(new ServiceHostMsg_CloudPrintProxy_Info(info));
124 }
125 
OnGetHistograms()126 void ServiceIPCServer::OnGetHistograms() {
127   if (!histogram_delta_serializer_) {
128     histogram_delta_serializer_.reset(
129         new base::HistogramDeltaSerialization("ServiceProcess"));
130   }
131   std::vector<std::string> deltas;
132   histogram_delta_serializer_->PrepareAndSerializeDeltas(&deltas);
133   channel_->Send(new ServiceHostMsg_Histograms(deltas));
134 }
135 
OnGetPrinters()136 void ServiceIPCServer::OnGetPrinters() {
137   std::vector<std::string> printers;
138   g_service_process->GetCloudPrintProxy()->GetPrinters(&printers);
139   channel_->Send(new ServiceHostMsg_Printers(printers));
140 }
141 
OnDisableCloudPrintProxy()142 void ServiceIPCServer::OnDisableCloudPrintProxy() {
143   // User disabled CloudPrint proxy explicitly. Delete printers
144   // registered from this proxy and disable proxy.
145   g_service_process->GetCloudPrintProxy()->
146       UnregisterPrintersAndDisableForUser();
147 }
148 
OnShutdown()149 void ServiceIPCServer::OnShutdown() {
150   g_service_process->Shutdown();
151 }
152 
OnUpdateAvailable()153 void ServiceIPCServer::OnUpdateAvailable() {
154   g_service_process->SetUpdateAvailable();
155 }
156 
157