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_tabstrip.h" 17 #include "chrome/browser/ui/browser_window.h" 18 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.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 if (!ActivateAndGetBrowserForUrl(url)) { 76 chrome::ScopedTabbedBrowserDisplayer displayer( 77 profile, chrome::HOST_DESKTOP_TYPE_ASH); 78 UMA_HISTOGRAM_ENUMERATION("PrinterService.PrinterServiceEvent", 79 PAGE_DISPLAYED, PRINTER_SERVICE_EVENT_MAX); 80 chrome::AddSelectedTabWithURL(displayer.browser(), url, 81 content::PAGE_TRANSITION_LINK); 82 } 83 } 84 85 } // namespace 86 87 namespace chromeos { 88 89 PrinterServiceProvider::PrinterServiceProvider() 90 : weak_ptr_factory_(this) { 91 } 92 93 PrinterServiceProvider::~PrinterServiceProvider() { 94 } 95 96 void PrinterServiceProvider::Start( 97 scoped_refptr<dbus::ExportedObject> exported_object) { 98 99 exported_object_ = exported_object; 100 DVLOG(1) << "PrinterServiceProvider started"; 101 exported_object_->ExportMethod( 102 kLibCrosServiceInterface, 103 kPrinterAdded, 104 base::Bind(&PrinterServiceProvider::PrinterAdded, 105 weak_ptr_factory_.GetWeakPtr()), 106 base::Bind(&PrinterServiceProvider::OnExported, 107 weak_ptr_factory_.GetWeakPtr())); 108 } 109 110 void PrinterServiceProvider::OnExported( 111 const std::string& interface_name, 112 const std::string& method_name, 113 bool success) { 114 if (!success) { 115 LOG(ERROR) << "Failed to export " << interface_name << "." 116 << method_name; 117 } 118 DVLOG(1) << "Method exported: " << interface_name << "." << method_name; 119 } 120 121 void PrinterServiceProvider::ShowCloudPrintHelp(const std::string& vendor, 122 const std::string& product) { 123 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 124 base::Bind(&FindOrOpenCloudPrintPage, vendor, 125 product)); 126 } 127 128 void PrinterServiceProvider::PrinterAdded( 129 dbus::MethodCall* method_call, 130 dbus::ExportedObject::ResponseSender response_sender) { 131 DVLOG(1) << "PrinterAdded " << method_call->ToString(); 132 133 dbus::MessageReader reader(method_call); 134 std::string vendor; 135 std::string product; 136 // Don't check for error, parameters are optional. If some string is empty 137 // web server will show generic help page. 138 reader.PopString(&vendor); 139 reader.PopString(&product); 140 ShowCloudPrintHelp(vendor, product); 141 142 // Send an empty response. 143 response_sender.Run(dbus::Response::FromMethodCall(method_call)); 144 } 145 146 } // namespace chromeos 147 148