1 // Copyright 2014 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/extensions/api/gcd_private/gcd_private_api.h" 6 7 #include "base/lazy_instance.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "chrome/browser/local_discovery/cloud_device_list.h" 10 #include "chrome/browser/local_discovery/cloud_print_printer_list.h" 11 #include "chrome/browser/local_discovery/gcd_constants.h" 12 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 14 #include "chrome/browser/signin/signin_manager_factory.h" 15 #include "components/signin/core/browser/profile_oauth2_token_service.h" 16 #include "components/signin/core/browser/signin_manager.h" 17 #include "components/signin/core/browser/signin_manager_base.h" 18 19 namespace extensions { 20 21 using extensions::api::gcd_private::GCDDevice; 22 23 namespace { 24 25 const int kNumRequestsNeeded = 2; 26 27 const char kIDPrefixCloudPrinter[] = "cloudprint:"; 28 const char kIDPrefixGcd[] = "gcd:"; 29 30 GcdPrivateAPI::GCDApiFlowFactoryForTests* g_gcd_api_flow_factory = NULL; 31 32 base::LazyInstance<BrowserContextKeyedAPIFactory<GcdPrivateAPI> > g_factory = 33 LAZY_INSTANCE_INITIALIZER; 34 35 scoped_ptr<local_discovery::GCDApiFlow> MakeGCDApiFlow(Profile* profile) { 36 if (g_gcd_api_flow_factory) { 37 return g_gcd_api_flow_factory->CreateGCDApiFlow(); 38 } 39 40 ProfileOAuth2TokenService* token_service = 41 ProfileOAuth2TokenServiceFactory::GetForProfile(profile); 42 if (!token_service) 43 return scoped_ptr<local_discovery::GCDApiFlow>(); 44 SigninManagerBase* signin_manager = 45 SigninManagerFactory::GetInstance()->GetForProfile(profile); 46 if (!signin_manager) 47 return scoped_ptr<local_discovery::GCDApiFlow>(); 48 return local_discovery::GCDApiFlow::Create( 49 profile->GetRequestContext(), 50 token_service, 51 signin_manager->GetAuthenticatedAccountId()); 52 } 53 54 } // namespace 55 56 GcdPrivateAPI::GcdPrivateAPI(content::BrowserContext* context) 57 : browser_context_(context) { 58 } 59 60 GcdPrivateAPI::~GcdPrivateAPI() { 61 } 62 63 // static 64 BrowserContextKeyedAPIFactory<GcdPrivateAPI>* 65 GcdPrivateAPI::GetFactoryInstance() { 66 return g_factory.Pointer(); 67 } 68 69 // static 70 void GcdPrivateAPI::SetGCDApiFlowFactoryForTests( 71 GCDApiFlowFactoryForTests* factory) { 72 g_gcd_api_flow_factory = factory; 73 } 74 75 GcdPrivateGetCloudDeviceListFunction::GcdPrivateGetCloudDeviceListFunction() { 76 } 77 GcdPrivateGetCloudDeviceListFunction::~GcdPrivateGetCloudDeviceListFunction() { 78 } 79 80 bool GcdPrivateGetCloudDeviceListFunction::RunAsync() { 81 requests_succeeded_ = 0; 82 requests_failed_ = 0; 83 84 printer_list_ = MakeGCDApiFlow(GetProfile()); 85 device_list_ = MakeGCDApiFlow(GetProfile()); 86 87 if (!printer_list_ || !device_list_) 88 return false; 89 90 // Balanced in CheckListingDone() 91 AddRef(); 92 93 printer_list_->Start(make_scoped_ptr<local_discovery::GCDApiFlow::Request>( 94 new local_discovery::CloudPrintPrinterList(this))); 95 device_list_->Start(make_scoped_ptr<local_discovery::GCDApiFlow::Request>( 96 new local_discovery::CloudDeviceList(this))); 97 98 return true; 99 } 100 101 void GcdPrivateGetCloudDeviceListFunction::OnDeviceListReady( 102 const DeviceList& devices) { 103 requests_succeeded_++; 104 105 devices_.insert(devices_.end(), devices.begin(), devices.end()); 106 107 CheckListingDone(); 108 } 109 110 void GcdPrivateGetCloudDeviceListFunction::OnDeviceListUnavailable() { 111 requests_failed_++; 112 113 CheckListingDone(); 114 } 115 116 void GcdPrivateGetCloudDeviceListFunction::CheckListingDone() { 117 if (requests_failed_ + requests_succeeded_ != kNumRequestsNeeded) 118 return; 119 120 if (requests_succeeded_ == 0) { 121 SendResponse(false); 122 return; 123 } 124 125 std::vector<linked_ptr<GCDDevice> > devices; 126 127 for (DeviceList::iterator i = devices_.begin(); i != devices_.end(); i++) { 128 linked_ptr<GCDDevice> device(new GCDDevice); 129 device->setup_type = extensions::api::gcd_private::SETUP_TYPE_CLOUD; 130 if (i->type == local_discovery::kGCDTypePrinter) { 131 device->id_string = kIDPrefixCloudPrinter + i->id; 132 } else { 133 device->id_string = kIDPrefixGcd + i->id; 134 } 135 136 device->cloud_id.reset(new std::string(i->id)); 137 device->device_type = i->type; 138 device->device_name = i->display_name; 139 device->device_description = i->description; 140 141 devices.push_back(device); 142 } 143 144 results_ = extensions::api::gcd_private::GetCloudDeviceList::Results::Create( 145 devices); 146 147 SendResponse(true); 148 Release(); 149 } 150 151 } // namespace extensions 152