1 // Copyright (c) 2012 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/chromeos/dbus/printer_service_provider.h" 6 7 #include "ash/session_state_delegate.h" 8 #include "ash/shell.h" 9 #include "ash/wm/window_util.h" 10 #include "base/bind.h" 11 #include "base/bind_helpers.h" 12 #include "base/metrics/histogram.h" 13 #include "base/strings/stringprintf.h" 14 #include "chrome/browser/profiles/profile_manager.h" 15 #include "chrome/browser/ui/browser.h" 16 #include "chrome/browser/ui/browser_finder.h" 17 #include "chrome/browser/ui/browser_tabstrip.h" 18 #include "chrome/browser/ui/browser_window.h" 19 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 20 #include "chrome/browser/ui/tabs/tab_strip_model.h" 21 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/web_contents.h" 23 #include "dbus/bus.h" 24 #include "dbus/exported_object.h" 25 #include "dbus/message.h" 26 #include "net/base/escape.h" 27 #include "third_party/cros_system_api/dbus/service_constants.h" 28 #include "ui/aura/window.h" 29 30 namespace { 31 32 const char kPrinterAdded[] = "PrinterAdded"; 33 34 enum PrinterServiceEvent { 35 PRINTER_ADDED, 36 PAGE_DISPLAYED, 37 PRINTER_SERVICE_EVENT_MAX, 38 }; 39 40 // TODO(vitalybuka): update URL with more relevant information. 41 const char kCloudPrintLearnUrl[] = 42 "https://www.google.com/landing/cloudprint/index.html"; 43 44 void ActivateContents(Browser* browser, content::WebContents* contents) { 45 browser->tab_strip_model()->ActivateTabAt( 46 browser->tab_strip_model()->GetIndexOfWebContents(contents), false); 47 } 48 49 Browser* ActivateAndGetBrowserForUrl(GURL url) { 50 for (TabContentsIterator it; !it.done(); it.Next()) { 51 if (it->GetLastCommittedURL() == url) { 52 ActivateContents(it.browser(), *it); 53 return it.browser(); 54 } 55 } 56 return NULL; 57 } 58 59 void FindOrOpenCloudPrintPage(const std::string& /* vendor */, 60 const std::string& /* product */) { 61 UMA_HISTOGRAM_ENUMERATION("PrinterService.PrinterServiceEvent", PRINTER_ADDED, 62 PRINTER_SERVICE_EVENT_MAX); 63 if (!ash::Shell::GetInstance()->session_state_delegate()-> 64 IsActiveUserSessionStarted() || 65 ash::Shell::GetInstance()->session_state_delegate()->IsScreenLocked()) { 66 return; 67 } 68 69 Profile* profile = ProfileManager::GetLastUsedProfile(); 70 if (!profile) 71 return; 72 73 GURL url(kCloudPrintLearnUrl); 74 75 Browser* browser = ActivateAndGetBrowserForUrl(url); 76 if (!browser) { 77 browser = chrome::FindOrCreateTabbedBrowser(profile, 78 chrome::HOST_DESKTOP_TYPE_ASH); 79 if (!browser) 80 return; 81 UMA_HISTOGRAM_ENUMERATION("PrinterService.PrinterServiceEvent", 82 PAGE_DISPLAYED, PRINTER_SERVICE_EVENT_MAX); 83 chrome::AddSelectedTabWithURL(browser, url, 84 content::PAGE_TRANSITION_LINK); 85 } 86 aura::Window* window = browser->window()->GetNativeWindow(); 87 if (window) { 88 window->Show(); 89 ash::wm::ActivateWindow(window); 90 } 91 } 92 93 } // namespace 94 95 namespace chromeos { 96 97 PrinterServiceProvider::PrinterServiceProvider() 98 : weak_ptr_factory_(this) { 99 } 100 101 PrinterServiceProvider::~PrinterServiceProvider() { 102 } 103 104 void PrinterServiceProvider::Start( 105 scoped_refptr<dbus::ExportedObject> exported_object) { 106 107 exported_object_ = exported_object; 108 DVLOG(1) << "PrinterServiceProvider started"; 109 exported_object_->ExportMethod( 110 kLibCrosServiceInterface, 111 kPrinterAdded, 112 base::Bind(&PrinterServiceProvider::PrinterAdded, 113 weak_ptr_factory_.GetWeakPtr()), 114 base::Bind(&PrinterServiceProvider::OnExported, 115 weak_ptr_factory_.GetWeakPtr())); 116 } 117 118 void PrinterServiceProvider::OnExported( 119 const std::string& interface_name, 120 const std::string& method_name, 121 bool success) { 122 if (!success) { 123 LOG(ERROR) << "Failed to export " << interface_name << "." 124 << method_name; 125 } 126 DVLOG(1) << "Method exported: " << interface_name << "." << method_name; 127 } 128 129 void PrinterServiceProvider::ShowCloudPrintHelp(const std::string& vendor, 130 const std::string& product) { 131 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 132 base::Bind(&FindOrOpenCloudPrintPage, vendor, 133 product)); 134 } 135 136 void PrinterServiceProvider::PrinterAdded( 137 dbus::MethodCall* method_call, 138 dbus::ExportedObject::ResponseSender response_sender) { 139 DVLOG(1) << "PrinterAdded " << method_call->ToString(); 140 141 dbus::MessageReader reader(method_call); 142 std::string vendor; 143 std::string product; 144 // Don't check for error, parameters are optional. If some string is empty 145 // web server will show generic help page. 146 reader.PopString(&vendor); 147 reader.PopString(&product); 148 ShowCloudPrintHelp(vendor, product); 149 150 // Send an empty response. 151 response_sender.Run(dbus::Response::FromMethodCall(method_call)); 152 } 153 154 } // namespace chromeos 155 156