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/ui/webui/task_manager/task_manager_dialog.h" 6 7 #include <algorithm> 8 #include <string> 9 #include <vector> 10 11 #include "base/bind.h" 12 #include "base/command_line.h" 13 #include "base/memory/singleton.h" 14 #include "base/prefs/pref_service.h" 15 #include "base/strings/utf_string_conversions.h" 16 #include "chrome/browser/browser_process.h" 17 #include "chrome/browser/defaults.h" 18 #include "chrome/browser/platform_util.h" 19 #include "chrome/browser/prefs/scoped_user_pref_update.h" 20 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/profiles/profile_manager.h" 22 #include "chrome/browser/ui/browser_dialogs.h" 23 #include "chrome/common/chrome_switches.h" 24 #include "chrome/common/pref_names.h" 25 #include "chrome/common/url_constants.h" 26 #include "content/public/browser/browser_thread.h" 27 #include "grit/google_chrome_strings.h" 28 #include "ui/base/l10n/l10n_util.h" 29 #include "ui/gfx/size.h" 30 #include "ui/web_dialogs/web_dialog_delegate.h" 31 32 #if defined(OS_CHROMEOS) 33 #include "ui/views/widget/widget.h" 34 #endif 35 36 namespace { 37 38 // The minimum size of task manager window in px. 39 const int kMinimumTaskManagerWidth = 640; 40 const int kMinimumTaskManagerHeight = 480; 41 42 } // namespace 43 44 using content::BrowserThread; 45 using content::WebContents; 46 using content::WebUIMessageHandler; 47 using ui::WebDialogDelegate; 48 49 class TaskManagerDialogImpl : public WebDialogDelegate { 50 public: 51 TaskManagerDialogImpl(); 52 53 static void Show(bool is_background_page_mode); 54 static TaskManagerDialogImpl* GetInstance(); 55 56 protected: 57 friend struct DefaultSingletonTraits<TaskManagerDialogImpl>; 58 virtual ~TaskManagerDialogImpl(); 59 60 void OnCloseDialog(); 61 62 // Overridden from WebDialogDelegate: 63 virtual ui::ModalType GetDialogModalType() const OVERRIDE { 64 return ui::MODAL_TYPE_NONE; 65 } 66 virtual string16 GetDialogTitle() const OVERRIDE { 67 return l10n_util::GetStringUTF16(IDS_TASK_MANAGER_TITLE); 68 } 69 virtual std::string GetDialogName() const OVERRIDE { 70 return prefs::kTaskManagerWindowPlacement; 71 } 72 virtual GURL GetDialogContentURL() const OVERRIDE { 73 std::string url_string(chrome::kChromeUITaskManagerURL); 74 url_string += "?"; 75 if (browser_defaults::kShowCancelButtonInTaskManager) 76 url_string += "showclose=1&"; 77 if (is_background_page_mode_) 78 url_string += "background=1"; 79 return GURL(url_string); 80 } 81 virtual void GetWebUIMessageHandlers( 82 std::vector<WebUIMessageHandler*>* handlers) const OVERRIDE { 83 } 84 virtual void GetDialogSize(gfx::Size* size) const OVERRIDE { 85 #if !defined(TOOLKIT_VIEWS) 86 // If dialog's bounds are previously saved, use them. 87 if (g_browser_process->local_state()) { 88 const DictionaryValue* placement_pref = 89 g_browser_process->local_state()->GetDictionary( 90 prefs::kTaskManagerWindowPlacement); 91 int width, height; 92 if (placement_pref && 93 placement_pref->GetInteger("width", &width) && 94 placement_pref->GetInteger("height", &height)) { 95 size->SetSize(std::max(1, width), std::max(1, height)); 96 return; 97 } 98 } 99 100 // Otherwise set default size. 101 size->SetSize(kMinimumTaskManagerWidth, kMinimumTaskManagerHeight); 102 #endif 103 } 104 virtual void GetMinimumDialogSize(gfx::Size* size) const OVERRIDE { 105 size->SetSize(kMinimumTaskManagerWidth, kMinimumTaskManagerHeight); 106 } 107 virtual std::string GetDialogArgs() const OVERRIDE { 108 return std::string(); 109 } 110 virtual void OnDialogClosed(const std::string& json_retval) OVERRIDE { 111 OnCloseDialog(); 112 } 113 virtual void OnCloseContents(WebContents* source, bool* out_close_dialog) 114 OVERRIDE { 115 *out_close_dialog = true; 116 } 117 virtual bool ShouldShowDialogTitle() const OVERRIDE { 118 return true; 119 } 120 virtual bool HandleContextMenu( 121 const content::ContextMenuParams& params) OVERRIDE { 122 return true; 123 } 124 #if !defined(TOOLKIT_VIEWS) 125 virtual void StoreDialogSize(const gfx::Size& dialog_size) OVERRIDE { 126 // Store the dialog's bounds so that it can be restored with the same bounds 127 // the next time it's opened. 128 if (g_browser_process->local_state()) { 129 DictionaryPrefUpdate update(g_browser_process->local_state(), 130 prefs::kTaskManagerWindowPlacement); 131 DictionaryValue* placement_pref = update.Get(); 132 placement_pref->SetInteger("width", dialog_size.width()); 133 placement_pref->SetInteger("height", dialog_size.height()); 134 } 135 } 136 #endif 137 138 private: 139 void ShowDialog(bool is_background_page_mode); 140 void OpenWebDialog(); 141 142 int show_count_; 143 144 gfx::NativeWindow window_; 145 bool is_background_page_mode_; 146 147 DISALLOW_COPY_AND_ASSIGN(TaskManagerDialogImpl); 148 }; 149 150 // **************************************************** 151 152 // static 153 TaskManagerDialogImpl* TaskManagerDialogImpl::GetInstance() { 154 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); 155 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::FILE)); 156 return Singleton<TaskManagerDialogImpl>::get(); 157 } 158 159 TaskManagerDialogImpl::TaskManagerDialogImpl() 160 : show_count_(0), 161 window_(NULL), 162 is_background_page_mode_(false) { 163 } 164 165 TaskManagerDialogImpl::~TaskManagerDialogImpl() { 166 } 167 168 // static 169 void TaskManagerDialogImpl::Show(bool is_background_page_mode) { 170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 171 TaskManagerDialogImpl* dialog = TaskManagerDialogImpl::GetInstance(); 172 dialog->ShowDialog(is_background_page_mode); 173 } 174 175 void TaskManagerDialogImpl::ShowDialog(bool is_background_page_mode) { 176 if (show_count_ > 0) { 177 #if defined(OS_CHROMEOS) 178 // Closes current TaskManager and Opens new one. 179 views::Widget::GetWidgetForNativeWindow(window_)->Close(); 180 #else 181 // TODO(yoshiki): Supports the other platforms. 182 platform_util::ActivateWindow(window_); 183 return; 184 #endif 185 } 186 is_background_page_mode_ = is_background_page_mode; 187 OpenWebDialog(); 188 ++show_count_; 189 } 190 191 void TaskManagerDialogImpl::OnCloseDialog() { 192 if (show_count_ > 0) 193 --show_count_; 194 } 195 196 void TaskManagerDialogImpl::OpenWebDialog() { 197 window_ = chrome::ShowWebDialog(NULL, 198 ProfileManager::GetLastUsedProfile(), 199 this); 200 } 201 202 // static 203 void TaskManagerDialog::Show() { 204 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 205 base::Bind(&TaskManagerDialogImpl::Show, false)); 206 } 207 208 // static 209 void TaskManagerDialog::ShowBackgroundPages() { 210 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 211 base::Bind(&TaskManagerDialogImpl::Show, true)); 212 } 213