Home | History | Annotate | Download | only in local_discovery
      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