12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cloud_print/service/win/service_listener.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_writer.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/installer/launcher_support/chrome_launcher_support.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cloud_print/service/win/service_utils.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cloud_print/service/win/setup_listener.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_channel.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "printing/backend/print_backend.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "printing/backend/win_helper.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string GetEnvironment(const base::FilePath& user_data_dir) { 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<printing::PrintBackend> backend( 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) printing::PrintBackend::CreateInstance(NULL)); 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) printing::PrinterList printer_list; 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) backend->EnumeratePrinters(&printer_list); 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::ListValue> printers(new base::ListValue()); 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < printer_list.size(); ++i) { 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) printers->AppendString(printer_list[i].printer_name); 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue environment; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) environment.Set(SetupListener::kPrintersJsonValueName, printers.release()); 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) environment.SetBoolean(SetupListener::kXpsAvailableJsonValueName, 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) printing::XPSModule::Init()); 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) environment.SetString(SetupListener::kUserNameJsonValueName, 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetCurrentUserName()); 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) environment.SetString(SetupListener::kChromePathJsonValueName, 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome_launcher_support::GetAnyChromePath().value()); 40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (base::CreateDirectory(user_data_dir)) { 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath temp_file; 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (base::CreateTemporaryFileInDir(user_data_dir, &temp_file)) { 437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(base::PathExists(temp_file)); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) environment.SetString(SetupListener::kUserDataDirJsonValueName, 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) user_data_dir.value()); 467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::DeleteFile(temp_file, false); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string result; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::JSONWriter::Write(&environment, &result); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ServiceListener::ServiceListener(const base::FilePath& user_data_dir) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : ipc_thread_(new base::Thread("ipc_thread")), 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) user_data_dir_(user_data_dir) { 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ipc_thread_->StartWithOptions( 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ipc_thread_->message_loop()->PostTask( 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, base::Bind(&ServiceListener::Connect, base::Unretained(this))); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ServiceListener::~ServiceListener() { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ipc_thread_->message_loop()->PostTask(FROM_HERE, 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ServiceListener::Disconnect, 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ipc_thread_->Stop(); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ServiceListener::OnMessageReceived(const IPC::Message& msg) { 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ServiceListener::OnChannelConnected(int32 peer_pid) { 780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) IPC::Message* message = new IPC::Message(0, 0, IPC::Message::PRIORITY_NORMAL); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message->WriteString(GetEnvironment(user_data_dir_)); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->Send(message); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ServiceListener::Disconnect() { 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_.reset(); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ServiceListener::Connect() { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::win::ScopedHandle handle( 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ::CreateFile(SetupListener::kSetupPipeName, GENERIC_READ | GENERIC_WRITE, 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0, NULL, OPEN_EXISTING, 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION | 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FILE_FLAG_OVERLAPPED, NULL)); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (handle.IsValid()) { 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci channel_ = IPC::Channel::CreateClient(IPC::ChannelHandle(handle.Get()), 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->Connect(); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ipc_thread_->message_loop()->PostDelayedTask( 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ServiceListener::Connect, base::Unretained(this)), 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds(500)); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 105