- add sources.
[platform/framework/web/crosswalk.git] / src / cloud_print / service / win / service_listener.cc
1 // Copyright 2013 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 "cloud_print/service/win/service_listener.h"
6
7 #include "base/bind.h"
8 #include "base/file_util.h"
9 #include "base/files/file_path.h"
10 #include "base/json/json_writer.h"
11 #include "base/threading/thread.h"
12 #include "base/values.h"
13 #include "chrome/installer/launcher_support/chrome_launcher_support.h"
14 #include "cloud_print/service/win/service_utils.h"
15 #include "cloud_print/service/win/setup_listener.h"
16 #include "ipc/ipc_channel.h"
17 #include "printing/backend/print_backend.h"
18 #include "printing/backend/win_helper.h"
19
20 namespace {
21
22 std::string GetEnvironment(const base::FilePath& user_data_dir) {
23   scoped_refptr<printing::PrintBackend> backend(
24       printing::PrintBackend::CreateInstance(NULL));
25   printing::PrinterList printer_list;
26   backend->EnumeratePrinters(&printer_list);
27   scoped_ptr<base::ListValue> printers(new base::ListValue());
28   for (size_t i = 0; i < printer_list.size(); ++i) {
29     printers->AppendString(printer_list[i].printer_name);
30   }
31
32   base::DictionaryValue environment;
33   environment.Set(SetupListener::kPrintersJsonValueName, printers.release());
34   environment.SetBoolean(SetupListener::kXpsAvailableJsonValueName,
35                          printing::XPSModule::Init());
36   environment.SetString(SetupListener::kUserNameJsonValueName,
37                         GetCurrentUserName());
38   environment.SetString(SetupListener::kChromePathJsonValueName,
39                         chrome_launcher_support::GetAnyChromePath().value());
40   if (file_util::CreateDirectory(user_data_dir)) {
41     base::FilePath temp_file;
42     if (file_util::CreateTemporaryFileInDir(user_data_dir, &temp_file)) {
43       DCHECK(base::PathExists(temp_file));
44       environment.SetString(SetupListener::kUserDataDirJsonValueName,
45                             user_data_dir.value());
46       base::DeleteFile(temp_file, false);
47     }
48   }
49
50   std::string result;
51   base::JSONWriter::Write(&environment, &result);
52   return result;
53 }
54
55 }  // namespace
56
57 ServiceListener::ServiceListener(const base::FilePath& user_data_dir)
58     : ipc_thread_(new base::Thread("ipc_thread")),
59       user_data_dir_(user_data_dir) {
60   ipc_thread_->StartWithOptions(
61       base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
62   ipc_thread_->message_loop()->PostTask(
63       FROM_HERE, base::Bind(&ServiceListener::Connect, base::Unretained(this)));
64 }
65
66 ServiceListener::~ServiceListener() {
67   ipc_thread_->message_loop()->PostTask(FROM_HERE,
68                                         base::Bind(&ServiceListener::Disconnect,
69                                                    base::Unretained(this)));
70   ipc_thread_->Stop();
71 }
72
73 bool ServiceListener::OnMessageReceived(const IPC::Message& msg) {
74   return true;
75 }
76
77 void ServiceListener::OnChannelConnected(int32 peer_pid) {
78   IPC::Message* message = new IPC::Message(0, 0, IPC::Message::PRIORITY_NORMAL);
79   message->WriteString(GetEnvironment(user_data_dir_));
80   channel_->Send(message);
81 }
82
83 void ServiceListener::Disconnect() {
84   channel_.reset();
85 }
86
87 void ServiceListener::Connect() {
88   base::win::ScopedHandle handle(
89       ::CreateFile(SetupListener::kSetupPipeName, GENERIC_READ | GENERIC_WRITE,
90                    0, NULL, OPEN_EXISTING,
91                    SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION |
92                    FILE_FLAG_OVERLAPPED, NULL));
93   if (handle.IsValid()) {
94     channel_.reset(new IPC::Channel(IPC::ChannelHandle(handle),
95                                     IPC::Channel::MODE_CLIENT, this));
96     channel_->Connect();
97   } else {
98     ipc_thread_->message_loop()->PostDelayedTask(
99         FROM_HERE,
100         base::Bind(&ServiceListener::Connect, base::Unretained(this)),
101         base::TimeDelta::FromMilliseconds(500));
102   }
103 }
104