privet_local_printer_lister.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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(
36      new PrivetDeviceListerImpl(service_discovery_client, this));
37  privet_http_factory_ = PrivetHTTPAsynchronousFactory::CreateInstance(
38      service_discovery_client,
39      request_context);
40}
41
42PrivetLocalPrinterLister::~PrivetLocalPrinterLister() {
43}
44
45void PrivetLocalPrinterLister::Start() {
46  privet_lister_->Start();
47  privet_lister_->DiscoverNewDevices(false);
48}
49
50void PrivetLocalPrinterLister::Stop() {
51  privet_lister_.reset();
52}
53
54void PrivetLocalPrinterLister::DeviceChanged(
55    bool added,
56    const std::string& name,
57    const DeviceDescription& description) {
58  if (description.type != kPrivetTypePrinter)
59    return;
60
61  DeviceContextMap::iterator i = device_contexts_.find(name);
62
63  if (i != device_contexts_.end()) {
64    i->second->description = description;
65    delegate_->LocalPrinterChanged(added, name, i->second->has_local_printing,
66                                   description);
67  } else {
68    linked_ptr<DeviceContext> context(new DeviceContext);
69    context->has_local_printing = false;
70    context->description = description;
71    context->privet_resolution = privet_http_factory_->CreatePrivetHTTP(
72        name,
73        description.address,
74        base::Bind(&PrivetLocalPrinterLister::OnPrivetResolved,
75                   base::Unretained(this)));
76
77    device_contexts_[name] = context;
78    context->privet_resolution->Start();
79  }
80}
81
82void PrivetLocalPrinterLister::DeviceCacheFlushed() {
83  device_contexts_.clear();
84  delegate_->LocalPrinterCacheFlushed();
85}
86
87void PrivetLocalPrinterLister::OnPrivetResolved(
88    scoped_ptr<PrivetHTTPClient> http_client) {
89  DeviceContextMap::iterator i = device_contexts_.find(http_client->GetName());
90  DCHECK(i != device_contexts_.end());
91
92  i->second->info_operation = http_client->CreateInfoOperation(
93      base::Bind(&PrivetLocalPrinterLister::OnPrivetInfoDone,
94                 base::Unretained(this),
95                 i->second.get(),
96                 http_client->GetName()));
97  i->second->privet_client = http_client.Pass();
98  i->second->info_operation->Start();
99}
100
101void PrivetLocalPrinterLister::OnPrivetInfoDone(
102    DeviceContext* context,
103    std::string name,
104    const base::DictionaryValue* json_value) {
105  bool has_local_printing = false;
106  const base::ListValue* api_list = NULL;
107  if (json_value && json_value->GetList(kPrivetInfoKeyAPIList, &api_list)) {
108    for (size_t i = 0; i < api_list->GetSize(); i++) {
109      std::string api;
110      api_list->GetString(i, &api);
111      if (api == kPrivetSubmitdocPath) {
112        has_local_printing = true;
113      }
114    }
115  }
116
117  context->has_local_printing = has_local_printing;
118  delegate_->LocalPrinterChanged(true, name, has_local_printing,
119                                 context->description);
120}
121
122void PrivetLocalPrinterLister::DeviceRemoved(const std::string& device_name) {
123  DeviceContextMap::iterator i = device_contexts_.find(device_name);
124  if (i != device_contexts_.end()) {
125    device_contexts_.erase(i);
126    delegate_->LocalPrinterRemoved(device_name);
127  }
128}
129
130const DeviceDescription* PrivetLocalPrinterLister::GetDeviceDescription(
131    const std::string& name) {
132  DeviceContextMap::iterator i = device_contexts_.find(name);
133  if (i == device_contexts_.end()) return NULL;
134  return &i->second->description;
135}
136
137}  // namespace local_discovery
138