Home | History | Annotate | Download | only in cloud_print
      1 // Copyright (c) 2011 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/printing/cloud_print/cloud_print_proxy_service.h"
      6 
      7 #include <stack>
      8 #include <vector>
      9 
     10 #include "base/utf_string_conversions.h"
     11 #include "chrome/browser/browser_process.h"
     12 #include "chrome/browser/notifications/desktop_notification_service.h"
     13 #include "chrome/browser/notifications/notification.h"
     14 #include "chrome/browser/notifications/notification_ui_manager.h"
     15 #include "chrome/browser/prefs/pref_service.h"
     16 #include "chrome/browser/printing/cloud_print/cloud_print_setup_flow.h"
     17 #include "chrome/browser/profiles/profile.h"
     18 #include "chrome/browser/service/service_process_control.h"
     19 #include "chrome/browser/service/service_process_control_manager.h"
     20 #include "chrome/browser/ui/browser_list.h"
     21 #include "chrome/common/pref_names.h"
     22 #include "chrome/common/service_messages.h"
     23 #include "content/browser/browser_thread.h"
     24 #include "grit/generated_resources.h"
     25 #include "ui/base/l10n/l10n_util.h"
     26 
     27 // TODO(sanjeevr): Localize the product name?
     28 const char kCloudPrintProductName[] = "Google Cloud Print";
     29 
     30 class CloudPrintProxyService::TokenExpiredNotificationDelegate
     31     : public NotificationDelegate {
     32  public:
     33   explicit TokenExpiredNotificationDelegate(
     34       CloudPrintProxyService* cloud_print_service)
     35           : cloud_print_service_(cloud_print_service) {
     36   }
     37   void Display() {}
     38   void Error() {
     39     cloud_print_service_->OnTokenExpiredNotificationError();
     40   }
     41   void Close(bool by_user) {
     42     cloud_print_service_->OnTokenExpiredNotificationClosed(by_user);
     43   }
     44   void Click() {
     45     cloud_print_service_->OnTokenExpiredNotificationClick();
     46   }
     47   std::string id() const { return "cloudprint.tokenexpired"; }
     48 
     49  private:
     50   CloudPrintProxyService* cloud_print_service_;
     51   DISALLOW_COPY_AND_ASSIGN(TokenExpiredNotificationDelegate);
     52 };
     53 
     54 CloudPrintProxyService::CloudPrintProxyService(Profile* profile)
     55     : profile_(profile), token_expired_delegate_(NULL) {
     56 }
     57 
     58 CloudPrintProxyService::~CloudPrintProxyService() {
     59 }
     60 
     61 void CloudPrintProxyService::Initialize() {
     62   if (profile_->GetPrefs()->HasPrefPath(prefs::kCloudPrintEmail) &&
     63       !profile_->GetPrefs()->GetString(prefs::kCloudPrintEmail).empty()) {
     64     // If the cloud print proxy is enabled, establish a channel with the
     65     // service process and update the status.
     66     RefreshStatusFromService();
     67   }
     68 }
     69 
     70 void CloudPrintProxyService::RefreshStatusFromService() {
     71   InvokeServiceTask(
     72       NewRunnableMethod(
     73           this, &CloudPrintProxyService::RefreshCloudPrintProxyStatus));
     74 }
     75 
     76 void CloudPrintProxyService::EnableForUser(const std::string& lsid,
     77                                            const std::string& email) {
     78   InvokeServiceTask(
     79       NewRunnableMethod(
     80           this, &CloudPrintProxyService::EnableCloudPrintProxy, lsid, email));
     81 }
     82 
     83 void CloudPrintProxyService::DisableForUser() {
     84   InvokeServiceTask(
     85       NewRunnableMethod(
     86           this, &CloudPrintProxyService::DisableCloudPrintProxy));
     87 }
     88 
     89 bool CloudPrintProxyService::ShowTokenExpiredNotification() {
     90   // If we already have a pending notification, don't show another one.
     91   if (token_expired_delegate_.get())
     92     return false;
     93 
     94   // TODO(sanjeevr): Get icon for this notification.
     95   GURL icon_url;
     96 
     97   string16 title = UTF8ToUTF16(kCloudPrintProductName);
     98   string16 message =
     99       l10n_util::GetStringUTF16(IDS_CLOUD_PRINT_TOKEN_EXPIRED_MESSAGE);
    100   string16 content_url = DesktopNotificationService::CreateDataUrl(
    101       icon_url, title, message, WebKit::WebTextDirectionDefault);
    102   token_expired_delegate_ = new TokenExpiredNotificationDelegate(this);
    103   Notification notification(GURL(), GURL(content_url), string16(), string16(),
    104                             token_expired_delegate_.get());
    105   g_browser_process->notification_ui_manager()->Add(notification, profile_);
    106   // Keep the browser alive while we are showing the notification.
    107   BrowserList::StartKeepAlive();
    108   return true;
    109 }
    110 
    111 void CloudPrintProxyService::OnTokenExpiredNotificationError() {
    112   TokenExpiredNotificationDone(false);
    113 }
    114 
    115 void CloudPrintProxyService::OnTokenExpiredNotificationClosed(bool by_user) {
    116   TokenExpiredNotificationDone(false);
    117 }
    118 
    119 void CloudPrintProxyService::OnTokenExpiredNotificationClick() {
    120   TokenExpiredNotificationDone(true);
    121   // Clear the cached cloud print email pref so that the cloud print setup
    122   // flow happens.
    123   profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail, std::string());
    124   cloud_print_setup_handler_.reset(new CloudPrintSetupHandler(this));
    125   CloudPrintSetupFlow::OpenDialog(
    126       profile_, cloud_print_setup_handler_->AsWeakPtr(), NULL);
    127 }
    128 
    129 void CloudPrintProxyService::TokenExpiredNotificationDone(bool keep_alive) {
    130   if (token_expired_delegate_.get()) {
    131     g_browser_process->notification_ui_manager()->CancelById(
    132         token_expired_delegate_->id());
    133     token_expired_delegate_ = NULL;
    134     if (!keep_alive)
    135       BrowserList::EndKeepAlive();
    136   }
    137 }
    138 
    139 void CloudPrintProxyService::OnCloudPrintSetupClosed() {
    140   MessageLoop::current()->PostTask(
    141       FROM_HERE, NewRunnableFunction(&BrowserList::EndKeepAlive));
    142 }
    143 
    144 void CloudPrintProxyService::RefreshCloudPrintProxyStatus() {
    145   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    146   ServiceProcessControl* process_control =
    147       ServiceProcessControlManager::GetInstance()->GetProcessControl(profile_);
    148   DCHECK(process_control->is_connected());
    149   Callback2<bool, std::string>::Type* callback =
    150        NewCallback(this, &CloudPrintProxyService::StatusCallback);
    151   // GetCloudPrintProxyStatus takes ownership of callback.
    152   process_control->GetCloudPrintProxyStatus(callback);
    153 }
    154 
    155 void CloudPrintProxyService::EnableCloudPrintProxy(const std::string& lsid,
    156                                                    const std::string& email) {
    157   ServiceProcessControl* process_control =
    158       ServiceProcessControlManager::GetInstance()->GetProcessControl(profile_);
    159   DCHECK(process_control->is_connected());
    160   process_control->Send(new ServiceMsg_EnableCloudPrintProxy(lsid));
    161   // Assume the IPC worked.
    162   profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail, email);
    163 }
    164 
    165 void CloudPrintProxyService::DisableCloudPrintProxy() {
    166   ServiceProcessControl* process_control =
    167       ServiceProcessControlManager::GetInstance()->GetProcessControl(profile_);
    168   DCHECK(process_control->is_connected());
    169   process_control->Send(new ServiceMsg_DisableCloudPrintProxy);
    170   // Assume the IPC worked.
    171   profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail, std::string());
    172 }
    173 
    174 void CloudPrintProxyService::StatusCallback(bool enabled, std::string email) {
    175   profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail,
    176                                   enabled ? email : std::string());
    177 }
    178 
    179 bool CloudPrintProxyService::InvokeServiceTask(Task* task) {
    180   ServiceProcessControl* process_control =
    181       ServiceProcessControlManager::GetInstance()->GetProcessControl(profile_);
    182   DCHECK(process_control);
    183   if (process_control)
    184     process_control->Launch(task, NULL);
    185   return !!process_control;
    186 }
    187