• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
TokenExpiredNotificationDelegate(CloudPrintProxyService * cloud_print_service)33   explicit TokenExpiredNotificationDelegate(
34       CloudPrintProxyService* cloud_print_service)
35           : cloud_print_service_(cloud_print_service) {
36   }
Display()37   void Display() {}
Error()38   void Error() {
39     cloud_print_service_->OnTokenExpiredNotificationError();
40   }
Close(bool by_user)41   void Close(bool by_user) {
42     cloud_print_service_->OnTokenExpiredNotificationClosed(by_user);
43   }
Click()44   void Click() {
45     cloud_print_service_->OnTokenExpiredNotificationClick();
46   }
id() const47   std::string id() const { return "cloudprint.tokenexpired"; }
48 
49  private:
50   CloudPrintProxyService* cloud_print_service_;
51   DISALLOW_COPY_AND_ASSIGN(TokenExpiredNotificationDelegate);
52 };
53 
CloudPrintProxyService(Profile * profile)54 CloudPrintProxyService::CloudPrintProxyService(Profile* profile)
55     : profile_(profile), token_expired_delegate_(NULL) {
56 }
57 
~CloudPrintProxyService()58 CloudPrintProxyService::~CloudPrintProxyService() {
59 }
60 
Initialize()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 
RefreshStatusFromService()70 void CloudPrintProxyService::RefreshStatusFromService() {
71   InvokeServiceTask(
72       NewRunnableMethod(
73           this, &CloudPrintProxyService::RefreshCloudPrintProxyStatus));
74 }
75 
EnableForUser(const std::string & lsid,const std::string & email)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 
DisableForUser()83 void CloudPrintProxyService::DisableForUser() {
84   InvokeServiceTask(
85       NewRunnableMethod(
86           this, &CloudPrintProxyService::DisableCloudPrintProxy));
87 }
88 
ShowTokenExpiredNotification()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 
OnTokenExpiredNotificationError()111 void CloudPrintProxyService::OnTokenExpiredNotificationError() {
112   TokenExpiredNotificationDone(false);
113 }
114 
OnTokenExpiredNotificationClosed(bool by_user)115 void CloudPrintProxyService::OnTokenExpiredNotificationClosed(bool by_user) {
116   TokenExpiredNotificationDone(false);
117 }
118 
OnTokenExpiredNotificationClick()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 
TokenExpiredNotificationDone(bool keep_alive)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 
OnCloudPrintSetupClosed()139 void CloudPrintProxyService::OnCloudPrintSetupClosed() {
140   MessageLoop::current()->PostTask(
141       FROM_HERE, NewRunnableFunction(&BrowserList::EndKeepAlive));
142 }
143 
RefreshCloudPrintProxyStatus()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 
EnableCloudPrintProxy(const std::string & lsid,const std::string & email)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 
DisableCloudPrintProxy()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 
StatusCallback(bool enabled,std::string email)174 void CloudPrintProxyService::StatusCallback(bool enabled, std::string email) {
175   profile_->GetPrefs()->SetString(prefs::kCloudPrintEmail,
176                                   enabled ? email : std::string());
177 }
178 
InvokeServiceTask(Task * task)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