| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/extension_tabs_module.h" | 5 #include "chrome/browser/extensions/extension_tabs_module.h" |
| 6 | 6 |
| 7 #include "base/gfx/jpeg_codec.h" | 7 #include "base/gfx/jpeg_codec.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "chrome/browser/browser.h" | 9 #include "chrome/browser/browser.h" |
| 10 #include "chrome/browser/browser_list.h" | 10 #include "chrome/browser/browser_list.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 #include "chrome/common/extensions/extension_error_utils.h" | 23 #include "chrome/common/extensions/extension_error_utils.h" |
| 24 #include "net/base/base64.h" | 24 #include "net/base/base64.h" |
| 25 #include "skia/ext/image_operations.h" | 25 #include "skia/ext/image_operations.h" |
| 26 #include "skia/ext/platform_canvas.h" | 26 #include "skia/ext/platform_canvas.h" |
| 27 #include "third_party/skia/include/core/SkBitmap.h" | 27 #include "third_party/skia/include/core/SkBitmap.h" |
| 28 | 28 |
| 29 | 29 |
| 30 namespace keys = extension_tabs_module_constants; | 30 namespace keys = extension_tabs_module_constants; |
| 31 | 31 |
| 32 // Forward declare static helper functions defined below. | 32 // Forward declare static helper functions defined below. |
| 33 static DictionaryValue* CreateWindowValue(Browser* browser, bool populate_tabs); | |
| 34 static ListValue* CreateTabList(Browser* browser); | |
| 35 | 33 |
| 36 // |error_message| can optionally be passed in a will be set with an appropriate | 34 // |error_message| can optionally be passed in a will be set with an appropriate |
| 37 // message if the window cannot be found by id. | 35 // message if the window cannot be found by id. |
| 38 static Browser* GetBrowserInProfileWithId(Profile* profile, | 36 static Browser* GetBrowserInProfileWithId(Profile* profile, |
| 39 const int window_id, | 37 const int window_id, |
| 40 std::string* error_message); | 38 std::string* error_message); |
| 41 | 39 |
| 42 // |error_message| can optionally be passed in a will be set with an appropriate | 40 // |error_message| can optionally be passed in a will be set with an appropriate |
| 43 // message if the tab cannot be found by id. | 41 // message if the tab cannot be found by id. |
| 44 static bool GetTabById(int tab_id, Profile* profile, Browser** browser, | 42 static bool GetTabById(int tab_id, Profile* profile, Browser** browser, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 int tab_index = tab_strip->GetIndexOfTabContents(contents); | 88 int tab_index = tab_strip->GetIndexOfTabContents(contents); |
| 91 if (tab_index != -1) { | 89 if (tab_index != -1) { |
| 92 return ExtensionTabUtil::CreateTabValue(contents, tab_strip, tab_index); | 90 return ExtensionTabUtil::CreateTabValue(contents, tab_strip, tab_index); |
| 93 } | 91 } |
| 94 } | 92 } |
| 95 | 93 |
| 96 // Couldn't find it. This can happen if the tab is being dragged. | 94 // Couldn't find it. This can happen if the tab is being dragged. |
| 97 return ExtensionTabUtil::CreateTabValue(contents, NULL, -1); | 95 return ExtensionTabUtil::CreateTabValue(contents, NULL, -1); |
| 98 } | 96 } |
| 99 | 97 |
| 98 ListValue* ExtensionTabUtil::CreateTabList(const Browser* browser) { |
| 99 ListValue* tab_list = new ListValue(); |
| 100 TabStripModel* tab_strip = browser->tabstrip_model(); |
| 101 for (int i = 0; i < tab_strip->count(); ++i) { |
| 102 tab_list->Append(ExtensionTabUtil::CreateTabValue( |
| 103 tab_strip->GetTabContentsAt(i), tab_strip, i)); |
| 104 } |
| 105 |
| 106 return tab_list; |
| 107 } |
| 108 |
| 100 DictionaryValue* ExtensionTabUtil::CreateTabValue( | 109 DictionaryValue* ExtensionTabUtil::CreateTabValue( |
| 101 const TabContents* contents, TabStripModel* tab_strip, int tab_index) { | 110 const TabContents* contents, TabStripModel* tab_strip, int tab_index) { |
| 102 TabStatus status = GetTabStatus(contents); | 111 TabStatus status = GetTabStatus(contents); |
| 103 | 112 |
| 104 DictionaryValue* result = new DictionaryValue(); | 113 DictionaryValue* result = new DictionaryValue(); |
| 105 result->SetInteger(keys::kIdKey, ExtensionTabUtil::GetTabId(contents)); | 114 result->SetInteger(keys::kIdKey, ExtensionTabUtil::GetTabId(contents)); |
| 106 result->SetInteger(keys::kIndexKey, tab_index); | 115 result->SetInteger(keys::kIndexKey, tab_index); |
| 107 result->SetInteger(keys::kWindowIdKey, | 116 result->SetInteger(keys::kWindowIdKey, |
| 108 ExtensionTabUtil::GetWindowIdOfTab(contents)); | 117 ExtensionTabUtil::GetWindowIdOfTab(contents)); |
| 109 result->SetString(keys::kUrlKey, contents->GetURL().spec()); | 118 result->SetString(keys::kUrlKey, contents->GetURL().spec()); |
| 110 result->SetString(keys::kStatusKey, GetTabStatusText(status)); | 119 result->SetString(keys::kStatusKey, GetTabStatusText(status)); |
| 111 result->SetBoolean(keys::kSelectedKey, | 120 result->SetBoolean(keys::kSelectedKey, |
| 112 tab_strip && tab_index == tab_strip->selected_index()); | 121 tab_strip && tab_index == tab_strip->selected_index()); |
| 113 | 122 |
| 114 if (status != TAB_LOADING) { | 123 if (status != TAB_LOADING) { |
| 115 result->SetString(keys::kTitleKey, UTF16ToWide(contents->GetTitle())); | 124 result->SetString(keys::kTitleKey, UTF16ToWide(contents->GetTitle())); |
| 116 | 125 |
| 117 NavigationEntry* entry = contents->controller().GetActiveEntry(); | 126 NavigationEntry* entry = contents->controller().GetActiveEntry(); |
| 118 if (entry) { | 127 if (entry) { |
| 119 if (entry->favicon().is_valid()) | 128 if (entry->favicon().is_valid()) |
| 120 result->SetString(keys::kFavIconUrlKey, entry->favicon().url().spec()); | 129 result->SetString(keys::kFavIconUrlKey, entry->favicon().url().spec()); |
| 121 } | 130 } |
| 122 } | 131 } |
| 123 | 132 |
| 124 return result; | 133 return result; |
| 125 } | 134 } |
| 126 | 135 |
| 136 // if |populate| is true, each window gets a list property |tabs| which contains |
| 137 // fully populated tab objects. |
| 138 DictionaryValue* ExtensionTabUtil::CreateWindowValue(const Browser* browser, |
| 139 bool populate_tabs) { |
| 140 DictionaryValue* result = new DictionaryValue(); |
| 141 result->SetInteger(keys::kIdKey, ExtensionTabUtil::GetWindowId( |
| 142 browser)); |
| 143 bool focused = false; |
| 144 if (browser->window()) |
| 145 focused = browser->window()->IsActive(); |
| 146 |
| 147 result->SetBoolean(keys::kFocusedKey, focused); |
| 148 gfx::Rect bounds = browser->window()->GetRestoredBounds(); |
| 149 |
| 150 // TODO(rafaelw): zIndex ? |
| 151 result->SetInteger(keys::kLeftKey, bounds.x()); |
| 152 result->SetInteger(keys::kTopKey, bounds.y()); |
| 153 result->SetInteger(keys::kWidthKey, bounds.width()); |
| 154 result->SetInteger(keys::kHeightKey, bounds.height()); |
| 155 |
| 156 if (populate_tabs) { |
| 157 result->Set(keys::kTabsKey, ExtensionTabUtil::CreateTabList(browser)); |
| 158 } |
| 159 |
| 160 return result; |
| 161 } |
| 162 |
| 127 bool ExtensionTabUtil::GetTabById(int tab_id, Profile* profile, | 163 bool ExtensionTabUtil::GetTabById(int tab_id, Profile* profile, |
| 128 Browser** browser, | 164 Browser** browser, |
| 129 TabStripModel** tab_strip, | 165 TabStripModel** tab_strip, |
| 130 TabContents** contents, | 166 TabContents** contents, |
| 131 int* tab_index) { | 167 int* tab_index) { |
| 132 Browser* target_browser; | 168 Browser* target_browser; |
| 133 TabStripModel* target_tab_strip; | 169 TabStripModel* target_tab_strip; |
| 134 TabContents* target_contents; | 170 TabContents* target_contents; |
| 135 for (BrowserList::const_iterator iter = BrowserList::begin(); | 171 for (BrowserList::const_iterator iter = BrowserList::begin(); |
| 136 iter != BrowserList::end(); ++iter) { | 172 iter != BrowserList::end(); ++iter) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 159 // Windows --------------------------------------------------------------------- | 195 // Windows --------------------------------------------------------------------- |
| 160 | 196 |
| 161 bool GetWindowFunction::RunImpl() { | 197 bool GetWindowFunction::RunImpl() { |
| 162 int window_id; | 198 int window_id; |
| 163 EXTENSION_FUNCTION_VALIDATE(args_->GetAsInteger(&window_id)); | 199 EXTENSION_FUNCTION_VALIDATE(args_->GetAsInteger(&window_id)); |
| 164 | 200 |
| 165 Browser* browser = GetBrowserInProfileWithId(profile(), window_id, &error_); | 201 Browser* browser = GetBrowserInProfileWithId(profile(), window_id, &error_); |
| 166 if (!browser) | 202 if (!browser) |
| 167 return false; | 203 return false; |
| 168 | 204 |
| 169 result_.reset(CreateWindowValue(browser, false)); | 205 result_.reset(ExtensionTabUtil::CreateWindowValue(browser, false)); |
| 170 return true; | 206 return true; |
| 171 } | 207 } |
| 172 | 208 |
| 173 bool GetCurrentWindowFunction::RunImpl() { | 209 bool GetCurrentWindowFunction::RunImpl() { |
| 174 Browser* browser = dispatcher()->GetBrowser(); | 210 Browser* browser = dispatcher()->GetBrowser(); |
| 175 if (!browser) { | 211 if (!browser) { |
| 176 error_ = keys::kNoCurrentWindowError; | 212 error_ = keys::kNoCurrentWindowError; |
| 177 return false; | 213 return false; |
| 178 } | 214 } |
| 179 result_.reset(CreateWindowValue(browser, false)); | 215 result_.reset(ExtensionTabUtil::CreateWindowValue(browser, false)); |
| 180 return true; | 216 return true; |
| 181 } | 217 } |
| 182 | 218 |
| 183 bool GetLastFocusedWindowFunction::RunImpl() { | 219 bool GetLastFocusedWindowFunction::RunImpl() { |
| 184 Browser* browser = BrowserList::GetLastActiveWithProfile(profile()); | 220 Browser* browser = BrowserList::GetLastActiveWithProfile(profile()); |
| 185 if (!browser) { | 221 if (!browser) { |
| 186 error_ = keys::kNoLastFocusedWindowError; | 222 error_ = keys::kNoLastFocusedWindowError; |
| 187 return false; | 223 return false; |
| 188 } | 224 } |
| 189 result_.reset(CreateWindowValue(browser, false)); | 225 result_.reset(ExtensionTabUtil::CreateWindowValue(browser, false)); |
| 190 return true; | 226 return true; |
| 191 } | 227 } |
| 192 | 228 |
| 193 bool GetAllWindowsFunction::RunImpl() { | 229 bool GetAllWindowsFunction::RunImpl() { |
| 194 bool populate_tabs = false; | 230 bool populate_tabs = false; |
| 195 if (!args_->IsType(Value::TYPE_NULL)) { | 231 if (!args_->IsType(Value::TYPE_NULL)) { |
| 196 EXTENSION_FUNCTION_VALIDATE(args_->GetAsBoolean(&populate_tabs)); | 232 EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_DICTIONARY)); |
| 233 const DictionaryValue* args = static_cast<const DictionaryValue*>(args_); |
| 234 if (args->HasKey(keys::kPopulateKey)) { |
| 235 EXTENSION_FUNCTION_VALIDATE(args->GetBoolean(keys::kPopulateKey, |
| 236 &populate_tabs)); |
| 237 } |
| 197 } | 238 } |
| 198 | 239 |
| 199 result_.reset(new ListValue()); | 240 result_.reset(new ListValue()); |
| 200 for (BrowserList::const_iterator browser = BrowserList::begin(); | 241 for (BrowserList::const_iterator browser = BrowserList::begin(); |
| 201 browser != BrowserList::end(); ++browser) { | 242 browser != BrowserList::end(); ++browser) { |
| 202 // Only examine browsers in the current profile. | 243 // Only examine browsers in the current profile. |
| 203 if ((*browser)->profile() == profile()) { | 244 if ((*browser)->profile() == profile()) { |
| 204 static_cast<ListValue*>(result_.get())-> | 245 static_cast<ListValue*>(result_.get())-> |
| 205 Append(CreateWindowValue(*browser, populate_tabs)); | 246 Append(ExtensionTabUtil::CreateWindowValue(*browser, populate_tabs)); |
| 206 } | 247 } |
| 207 } | 248 } |
| 208 | 249 |
| 209 return true; | 250 return true; |
| 210 } | 251 } |
| 211 | 252 |
| 212 bool CreateWindowFunction::RunImpl() { | 253 bool CreateWindowFunction::RunImpl() { |
| 213 scoped_ptr<GURL> url(new GURL()); | 254 scoped_ptr<GURL> url(new GURL()); |
| 214 | 255 |
| 215 // Look for optional url. | 256 // Look for optional url. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 | 314 |
| 274 Browser* new_window = Browser::Create(dispatcher()->profile()); | 315 Browser* new_window = Browser::Create(dispatcher()->profile()); |
| 275 new_window->AddTabWithURL(*(url.get()), GURL(), PageTransition::LINK, true, | 316 new_window->AddTabWithURL(*(url.get()), GURL(), PageTransition::LINK, true, |
| 276 -1, false, NULL); | 317 -1, false, NULL); |
| 277 | 318 |
| 278 new_window->window()->SetBounds(bounds); | 319 new_window->window()->SetBounds(bounds); |
| 279 new_window->window()->Show(); | 320 new_window->window()->Show(); |
| 280 | 321 |
| 281 // TODO(rafaelw): support |focused|, |zIndex| | 322 // TODO(rafaelw): support |focused|, |zIndex| |
| 282 | 323 |
| 283 result_.reset(CreateWindowValue(new_window, false)); | 324 result_.reset(ExtensionTabUtil::CreateWindowValue(new_window, false)); |
| 284 | 325 |
| 285 return true; | 326 return true; |
| 286 } | 327 } |
| 287 | 328 |
| 288 bool UpdateWindowFunction::RunImpl() { | 329 bool UpdateWindowFunction::RunImpl() { |
| 289 EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_LIST)); | 330 EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_LIST)); |
| 290 const ListValue* args = static_cast<const ListValue*>(args_); | 331 const ListValue* args = static_cast<const ListValue*>(args_); |
| 291 int window_id; | 332 int window_id; |
| 292 EXTENSION_FUNCTION_VALIDATE(args->GetInteger(0, &window_id)); | 333 EXTENSION_FUNCTION_VALIDATE(args->GetInteger(0, &window_id)); |
| 293 DictionaryValue* update_props; | 334 DictionaryValue* update_props; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 323 | 364 |
| 324 if (update_props->HasKey(keys::kHeightKey)) { | 365 if (update_props->HasKey(keys::kHeightKey)) { |
| 325 EXTENSION_FUNCTION_VALIDATE(update_props->GetInteger( | 366 EXTENSION_FUNCTION_VALIDATE(update_props->GetInteger( |
| 326 keys::kHeightKey, | 367 keys::kHeightKey, |
| 327 &bounds_val)); | 368 &bounds_val)); |
| 328 bounds.set_height(bounds_val); | 369 bounds.set_height(bounds_val); |
| 329 } | 370 } |
| 330 | 371 |
| 331 browser->window()->SetBounds(bounds); | 372 browser->window()->SetBounds(bounds); |
| 332 // TODO(rafaelw): Support |focused|. | 373 // TODO(rafaelw): Support |focused|. |
| 333 result_.reset(CreateWindowValue(browser, false)); | 374 result_.reset(ExtensionTabUtil::CreateWindowValue(browser, false)); |
| 334 | 375 |
| 335 return true; | 376 return true; |
| 336 } | 377 } |
| 337 | 378 |
| 338 bool RemoveWindowFunction::RunImpl() { | 379 bool RemoveWindowFunction::RunImpl() { |
| 339 int window_id; | 380 int window_id; |
| 340 EXTENSION_FUNCTION_VALIDATE(args_->GetAsInteger(&window_id)); | 381 EXTENSION_FUNCTION_VALIDATE(args_->GetAsInteger(&window_id)); |
| 341 | 382 |
| 342 Browser* browser = GetBrowserInProfileWithId(profile(), window_id, &error_); | 383 Browser* browser = GetBrowserInProfileWithId(profile(), window_id, &error_); |
| 343 if (!browser) | 384 if (!browser) |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 EXTENSION_FUNCTION_VALIDATE(args_->GetAsInteger(&window_id)); | 426 EXTENSION_FUNCTION_VALIDATE(args_->GetAsInteger(&window_id)); |
| 386 browser = GetBrowserInProfileWithId(profile(), window_id, &error_); | 427 browser = GetBrowserInProfileWithId(profile(), window_id, &error_); |
| 387 } else { | 428 } else { |
| 388 browser = dispatcher()->GetBrowser(); | 429 browser = dispatcher()->GetBrowser(); |
| 389 if (!browser) | 430 if (!browser) |
| 390 error_ = keys::kNoCurrentWindowError; | 431 error_ = keys::kNoCurrentWindowError; |
| 391 } | 432 } |
| 392 if (!browser) | 433 if (!browser) |
| 393 return false; | 434 return false; |
| 394 | 435 |
| 395 result_.reset(CreateTabList(browser)); | 436 result_.reset(ExtensionTabUtil::CreateTabList(browser)); |
| 396 | 437 |
| 397 return true; | 438 return true; |
| 398 } | 439 } |
| 399 | 440 |
| 400 bool CreateTabFunction::RunImpl() { | 441 bool CreateTabFunction::RunImpl() { |
| 401 EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_DICTIONARY)); | 442 EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_DICTIONARY)); |
| 402 const DictionaryValue* args = static_cast<const DictionaryValue*>(args_); | 443 const DictionaryValue* args = static_cast<const DictionaryValue*>(args_); |
| 403 | 444 |
| 404 Browser *browser; | 445 Browser *browser; |
| 405 // windowId defaults to "current" window. | 446 // windowId defaults to "current" window. |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 const NotificationDetails& details) { | 802 const NotificationDetails& details) { |
| 762 DCHECK(type == NotificationType::TAB_LANGUAGE_DETERMINED); | 803 DCHECK(type == NotificationType::TAB_LANGUAGE_DETERMINED); |
| 763 std::string language(*Details<std::string>(details).ptr()); | 804 std::string language(*Details<std::string>(details).ptr()); |
| 764 result_.reset(Value::CreateStringValue(language.c_str())); | 805 result_.reset(Value::CreateStringValue(language.c_str())); |
| 765 SendResponse(true); | 806 SendResponse(true); |
| 766 Release(); // balanced in Run() | 807 Release(); // balanced in Run() |
| 767 } | 808 } |
| 768 | 809 |
| 769 // static helpers | 810 // static helpers |
| 770 | 811 |
| 771 // if |populate| is true, each window gets a list property |tabs| which contains | |
| 772 // fully populated tab objects. | |
| 773 static DictionaryValue* CreateWindowValue(Browser* browser, | |
| 774 bool populate_tabs) { | |
| 775 DictionaryValue* result = new DictionaryValue(); | |
| 776 result->SetInteger(keys::kIdKey, ExtensionTabUtil::GetWindowId( | |
| 777 browser)); | |
| 778 result->SetBoolean(keys::kFocusedKey, | |
| 779 browser->window()->IsActive()); | |
| 780 gfx::Rect bounds = browser->window()->GetRestoredBounds(); | |
| 781 | |
| 782 // TODO(rafaelw): zIndex ? | |
| 783 result->SetInteger(keys::kLeftKey, bounds.x()); | |
| 784 result->SetInteger(keys::kTopKey, bounds.y()); | |
| 785 result->SetInteger(keys::kWidthKey, bounds.width()); | |
| 786 result->SetInteger(keys::kHeightKey, bounds.height()); | |
| 787 | |
| 788 if (populate_tabs) { | |
| 789 result->Set(keys::kTabsKey, CreateTabList(browser)); | |
| 790 } | |
| 791 | |
| 792 return result; | |
| 793 } | |
| 794 | |
| 795 static ListValue* CreateTabList(Browser* browser) { | |
| 796 ListValue* tab_list = new ListValue(); | |
| 797 TabStripModel* tab_strip = browser->tabstrip_model(); | |
| 798 for (int i = 0; i < tab_strip->count(); ++i) { | |
| 799 tab_list->Append(ExtensionTabUtil::CreateTabValue( | |
| 800 tab_strip->GetTabContentsAt(i), tab_strip, i)); | |
| 801 } | |
| 802 | |
| 803 return tab_list; | |
| 804 } | |
| 805 | |
| 806 static Browser* GetBrowserInProfileWithId(Profile* profile, | 812 static Browser* GetBrowserInProfileWithId(Profile* profile, |
| 807 const int window_id, | 813 const int window_id, |
| 808 std::string* error_message) { | 814 std::string* error_message) { |
| 809 for (BrowserList::const_iterator browser = BrowserList::begin(); | 815 for (BrowserList::const_iterator browser = BrowserList::begin(); |
| 810 browser != BrowserList::end(); ++browser) { | 816 browser != BrowserList::end(); ++browser) { |
| 811 if ((*browser)->profile() == profile && | 817 if ((*browser)->profile() == profile && |
| 812 ExtensionTabUtil::GetWindowId(*browser) == window_id) | 818 ExtensionTabUtil::GetWindowId(*browser) == window_id) |
| 813 return *browser; | 819 return *browser; |
| 814 } | 820 } |
| 815 | 821 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 835 if (ExtensionTabUtil::GetTabById(tab_id, profile, browser, tab_strip, | 841 if (ExtensionTabUtil::GetTabById(tab_id, profile, browser, tab_strip, |
| 836 contents, tab_index)) | 842 contents, tab_index)) |
| 837 return true; | 843 return true; |
| 838 | 844 |
| 839 if (error_message) | 845 if (error_message) |
| 840 *error_message = ExtensionErrorUtils::FormatErrorMessage( | 846 *error_message = ExtensionErrorUtils::FormatErrorMessage( |
| 841 keys::kTabNotFoundError, IntToString(tab_id)); | 847 keys::kTabNotFoundError, IntToString(tab_id)); |
| 842 | 848 |
| 843 return false; | 849 return false; |
| 844 } | 850 } |
| OLD | NEW |