privet_local_printer_lister.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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 "chrome/browser/local_discovery/privet_local_printer_lister.h"
6
7#include <string>
8
9#include "chrome/browser/local_discovery/privet_constants.h"
10#include "chrome/browser/local_discovery/privet_device_lister_impl.h"
11#include "chrome/browser/local_discovery/privet_http_asynchronous_factory.h"
12
13namespace local_discovery {
14
15struct PrivetLocalPrinterLister::DeviceContext {
16 public:
17  DeviceContext() {
18  }
19
20  ~DeviceContext() {
21  }
22
23  scoped_ptr<PrivetHTTPResolution> privet_resolution;
24  scoped_ptr<PrivetHTTPClient> privet_client;
25  scoped_ptr<PrivetJSONOperation> info_operation;
26  DeviceDescription description;
27
28  bool has_local_printing;
29};
30
31PrivetLocalPrinterLister::PrivetLocalPrinterLister(
32    ServiceDiscoveryClient* service_discovery_client,
33    net::URLRequestContextGetter* request_context,
34    Delegate* delegate) : delegate_(delegate) {
35  privet_lister_.reset(new PrivetDeviceListerImpl(service_discovery_client,
36                                                  this,
37                                                  kPrivetSubtypePrinter));
38  privet_http_factory_ = PrivetHTTPAsynchronousFactory::CreateInstance(
39      service_discovery_client,
40      request_context);
41}
42
43PrivetLocalPrinterLister::~PrivetLocalPrinterLister() {
44}
45
46void PrivetLocalPrinterLister::Start() {
47  privet_lister_->Start();
48  privet_lister_->DiscoverNewDevices(false);
49}
50
51void PrivetLocalPrinterLister::Stop() {
52  privet_lister_.reset();
53}
54
55void PrivetLocalPrinterLister::DeviceChanged(
56    bool added,
57    const std::string& name,
58    const DeviceDescription& description) {
59  DeviceContextMap::iterator i = device_contexts_.find(name);
60
61  if (i != device_contexts_.end()) {
62    i->second->description = description;
63    delegate_->LocalPrinterChanged(added, name, i->second->has_local_printing,
64                                   description);
65  } else {
66    linked_ptr<DeviceContext> context(new DeviceContext);
67    context->has_local_printing = false;
68    context->description = description;
69    context->privet_resolution = privet_http_factory_->CreatePrivetHTTP(
70        name,
71        description.address,
72        base::Bind(&PrivetLocalPrinterLister::OnPrivetResolved,
73                   base::Unretained(this)));
74
75    device_contexts_[name] = context;
76    context->privet_resolution->Start();
77  }
78}
79
80void PrivetLocalPrinterLister::DeviceCacheFlushed() {
81  device_contexts_.clear();
82  delegate_->LocalPrinterCacheFlushed();
83}
84
85void PrivetLocalPrinterLister::OnPrivetResolved(
86    scoped_ptr<PrivetHTTPClient> http_client) {
87  DeviceContextMap::iterator i = device_contexts_.find(http_client->GetName());
88  DCHECK(i != device_contexts_.end());
89
90  i->second->info_operation = http_client->CreateInfoOperation(
91      base::Bind(&PrivetLocalPrinterLister::OnPrivetInfoDone,
92                 base::Unretained(this),
93                 i->second.get(),
94                 http_client->GetName()));
95  i->second->privet_client = http_client.Pass();
96  i->second->info_operation->Start();
97}
98
99void PrivetLocalPrinterLister::OnPrivetInfoDone(
100    DeviceContext* context,
101    std::string name,
102    const base::DictionaryValue* json_value) {
103  bool has_local_printing = false;
104  const base::ListValue* api_list = NULL;
105  if (json_value && json_value->GetList(kPrivetInfoKeyAPIList, &api_list)) {
106    for (size_t i = 0; i < api_list->GetSize(); i++) {
107      std::string api;
108      api_list->GetString(i, &api);
109      if (api == kPrivetSubmitdocPath) {
110        has_local_printing = true;
111      }
112    }
113  }
114
115  context->has_local_printing = has_local_printing;
116  delegate_->LocalPrinterChanged(true, name, has_local_printing,
117                                 context->description);
118}
119
120void PrivetLocalPrinterLister::DeviceRemoved(const std::string& device_name) {
121  DeviceContextMap::iterator i = device_contexts_.find(device_name);
122  if (i != device_contexts_.end()) {
123    device_contexts_.erase(i);
124    delegate_->LocalPrinterRemoved(device_name);
125  }
126}
127
128const DeviceDescription* PrivetLocalPrinterLister::GetDeviceDescription(
129    const std::string& name) {
130  DeviceContextMap::iterator i = device_contexts_.find(name);
131  if (i == device_contexts_.end()) return NULL;
132  return &i->second->description;
133}
134
135}  // namespace local_discovery
136