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