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