Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(647)

Side by Side Diff: chrome/browser/extensions/api/tabs/tabs_api.cc

Issue 1871713002: Convert //chrome/browser/extensions from scoped_ptr to std::unique_ptr (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase and fix header Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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/api/tabs/tabs_api.h" 5 #include "chrome/browser/extensions/api/tabs/tabs_api.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <algorithm> 8 #include <algorithm>
9 #include <limits> 9 #include <limits>
10 #include <utility> 10 #include <utility>
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 } 195 }
196 196
197 // Returns true if either |boolean| is a null pointer, or if |*boolean| and 197 // Returns true if either |boolean| is a null pointer, or if |*boolean| and
198 // |value| are equal. This function is used to check if a tab's parameters match 198 // |value| are equal. This function is used to check if a tab's parameters match
199 // those of the browser. 199 // those of the browser.
200 bool MatchesBool(bool* boolean, bool value) { 200 bool MatchesBool(bool* boolean, bool value) {
201 return !boolean || *boolean == value; 201 return !boolean || *boolean == value;
202 } 202 }
203 203
204 template <typename T> 204 template <typename T>
205 void AssignOptionalValue(const scoped_ptr<T>& source, 205 void AssignOptionalValue(const std::unique_ptr<T>& source,
206 scoped_ptr<T>& destination) { 206 std::unique_ptr<T>& destination) {
207 if (source.get()) { 207 if (source.get()) {
208 destination.reset(new T(*source.get())); 208 destination.reset(new T(*source.get()));
209 } 209 }
210 } 210 }
211 211
212 ui::WindowShowState ConvertToWindowShowState(windows::WindowState state) { 212 ui::WindowShowState ConvertToWindowShowState(windows::WindowState state) {
213 switch (state) { 213 switch (state) {
214 case windows::WINDOW_STATE_NORMAL: 214 case windows::WINDOW_STATE_NORMAL:
215 case windows::WINDOW_STATE_DOCKED: 215 case windows::WINDOW_STATE_DOCKED:
216 return ui::SHOW_STATE_NORMAL; 216 return ui::SHOW_STATE_NORMAL;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 case ZoomController::ZOOM_MODE_DISABLED: 278 case ZoomController::ZOOM_MODE_DISABLED:
279 zoom_settings->mode = api::tabs::ZOOM_SETTINGS_MODE_DISABLED; 279 zoom_settings->mode = api::tabs::ZOOM_SETTINGS_MODE_DISABLED;
280 zoom_settings->scope = api::tabs::ZOOM_SETTINGS_SCOPE_PER_TAB; 280 zoom_settings->scope = api::tabs::ZOOM_SETTINGS_SCOPE_PER_TAB;
281 break; 281 break;
282 } 282 }
283 } 283 }
284 284
285 // Windows --------------------------------------------------------------------- 285 // Windows ---------------------------------------------------------------------
286 286
287 bool WindowsGetFunction::RunSync() { 287 bool WindowsGetFunction::RunSync() {
288 scoped_ptr<windows::Get::Params> params(windows::Get::Params::Create(*args_)); 288 std::unique_ptr<windows::Get::Params> params(
289 windows::Get::Params::Create(*args_));
289 EXTENSION_FUNCTION_VALIDATE(params.get()); 290 EXTENSION_FUNCTION_VALIDATE(params.get());
290 291
291 ApiParameterExtractor<windows::Get::Params> extractor(params.get()); 292 ApiParameterExtractor<windows::Get::Params> extractor(params.get());
292 WindowController* controller; 293 WindowController* controller;
293 if (!windows_util::GetWindowFromWindowID( 294 if (!windows_util::GetWindowFromWindowID(
294 this, params->window_id, extractor.type_filters(), &controller)) { 295 this, params->window_id, extractor.type_filters(), &controller)) {
295 return false; 296 return false;
296 } 297 }
297 298
298 if (extractor.populate_tabs()) 299 if (extractor.populate_tabs())
299 SetResult(controller->CreateWindowValueWithTabs(extension())); 300 SetResult(controller->CreateWindowValueWithTabs(extension()));
300 else 301 else
301 SetResult(controller->CreateWindowValue()); 302 SetResult(controller->CreateWindowValue());
302 return true; 303 return true;
303 } 304 }
304 305
305 bool WindowsGetCurrentFunction::RunSync() { 306 bool WindowsGetCurrentFunction::RunSync() {
306 scoped_ptr<windows::GetCurrent::Params> params( 307 std::unique_ptr<windows::GetCurrent::Params> params(
307 windows::GetCurrent::Params::Create(*args_)); 308 windows::GetCurrent::Params::Create(*args_));
308 EXTENSION_FUNCTION_VALIDATE(params.get()); 309 EXTENSION_FUNCTION_VALIDATE(params.get());
309 310
310 ApiParameterExtractor<windows::GetCurrent::Params> extractor(params.get()); 311 ApiParameterExtractor<windows::GetCurrent::Params> extractor(params.get());
311 WindowController* controller; 312 WindowController* controller;
312 if (!windows_util::GetWindowFromWindowID( 313 if (!windows_util::GetWindowFromWindowID(
313 this, extension_misc::kCurrentWindowId, extractor.type_filters(), 314 this, extension_misc::kCurrentWindowId, extractor.type_filters(),
314 &controller)) { 315 &controller)) {
315 return false; 316 return false;
316 } 317 }
317 if (extractor.populate_tabs()) 318 if (extractor.populate_tabs())
318 SetResult(controller->CreateWindowValueWithTabs(extension())); 319 SetResult(controller->CreateWindowValueWithTabs(extension()));
319 else 320 else
320 SetResult(controller->CreateWindowValue()); 321 SetResult(controller->CreateWindowValue());
321 return true; 322 return true;
322 } 323 }
323 324
324 bool WindowsGetLastFocusedFunction::RunSync() { 325 bool WindowsGetLastFocusedFunction::RunSync() {
325 scoped_ptr<windows::GetLastFocused::Params> params( 326 std::unique_ptr<windows::GetLastFocused::Params> params(
326 windows::GetLastFocused::Params::Create(*args_)); 327 windows::GetLastFocused::Params::Create(*args_));
327 EXTENSION_FUNCTION_VALIDATE(params.get()); 328 EXTENSION_FUNCTION_VALIDATE(params.get());
328 329
329 ApiParameterExtractor<windows::GetLastFocused::Params> extractor( 330 ApiParameterExtractor<windows::GetLastFocused::Params> extractor(
330 params.get()); 331 params.get());
331 // The WindowControllerList should contain a list of application, 332 // The WindowControllerList should contain a list of application,
332 // browser and devtools windows. 333 // browser and devtools windows.
333 WindowController* controller = nullptr; 334 WindowController* controller = nullptr;
334 for (auto iter : WindowControllerList::GetInstance()->windows()) { 335 for (auto iter : WindowControllerList::GetInstance()->windows()) {
335 if (windows_util::CanOperateOnWindow(this, iter, 336 if (windows_util::CanOperateOnWindow(this, iter,
336 extractor.type_filters())) { 337 extractor.type_filters())) {
337 controller = iter; 338 controller = iter;
338 if (controller->window()->IsActive()) 339 if (controller->window()->IsActive())
339 break; // Use focused window. 340 break; // Use focused window.
340 } 341 }
341 } 342 }
342 if (!controller) { 343 if (!controller) {
343 error_ = keys::kNoLastFocusedWindowError; 344 error_ = keys::kNoLastFocusedWindowError;
344 return false; 345 return false;
345 } 346 }
346 if (extractor.populate_tabs()) 347 if (extractor.populate_tabs())
347 SetResult(controller->CreateWindowValueWithTabs(extension())); 348 SetResult(controller->CreateWindowValueWithTabs(extension()));
348 else 349 else
349 SetResult(controller->CreateWindowValue()); 350 SetResult(controller->CreateWindowValue());
350 return true; 351 return true;
351 } 352 }
352 353
353 bool WindowsGetAllFunction::RunSync() { 354 bool WindowsGetAllFunction::RunSync() {
354 scoped_ptr<windows::GetAll::Params> params( 355 std::unique_ptr<windows::GetAll::Params> params(
355 windows::GetAll::Params::Create(*args_)); 356 windows::GetAll::Params::Create(*args_));
356 EXTENSION_FUNCTION_VALIDATE(params.get()); 357 EXTENSION_FUNCTION_VALIDATE(params.get());
357 358
358 ApiParameterExtractor<windows::GetAll::Params> extractor(params.get()); 359 ApiParameterExtractor<windows::GetAll::Params> extractor(params.get());
359 base::ListValue* window_list = new base::ListValue(); 360 base::ListValue* window_list = new base::ListValue();
360 const WindowControllerList::ControllerList& windows = 361 const WindowControllerList::ControllerList& windows =
361 WindowControllerList::GetInstance()->windows(); 362 WindowControllerList::GetInstance()->windows();
362 for (WindowControllerList::ControllerList::const_iterator iter = 363 for (WindowControllerList::ControllerList::const_iterator iter =
363 windows.begin(); 364 windows.begin();
364 iter != windows.end(); ++iter) { 365 iter != windows.end(); ++iter) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 error_ = ErrorUtils::FormatErrorMessage( 417 error_ = ErrorUtils::FormatErrorMessage(
417 keys::kURLsNotAllowedInIncognitoError, first_url_erased); 418 keys::kURLsNotAllowedInIncognitoError, first_url_erased);
418 *is_error = true; 419 *is_error = true;
419 return false; 420 return false;
420 } 421 }
421 } 422 }
422 return incognito; 423 return incognito;
423 } 424 }
424 425
425 bool WindowsCreateFunction::RunSync() { 426 bool WindowsCreateFunction::RunSync() {
426 scoped_ptr<windows::Create::Params> params( 427 std::unique_ptr<windows::Create::Params> params(
427 windows::Create::Params::Create(*args_)); 428 windows::Create::Params::Create(*args_));
428 EXTENSION_FUNCTION_VALIDATE(params); 429 EXTENSION_FUNCTION_VALIDATE(params);
429 std::vector<GURL> urls; 430 std::vector<GURL> urls;
430 TabStripModel* source_tab_strip = NULL; 431 TabStripModel* source_tab_strip = NULL;
431 int tab_index = -1; 432 int tab_index = -1;
432 433
433 windows::Create::Params::CreateData* create_data = params->create_data.get(); 434 windows::Create::Params::CreateData* create_data = params->create_data.get();
434 435
435 // Look for optional url. 436 // Look for optional url.
436 if (create_data && create_data->url) { 437 if (create_data && create_data->url) {
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 // profile and CanCrossIncognito isn't allowed. 692 // profile and CanCrossIncognito isn't allowed.
692 SetResult(base::Value::CreateNullValue()); 693 SetResult(base::Value::CreateNullValue());
693 } else { 694 } else {
694 SetResult(controller->CreateWindowValueWithTabs(extension())); 695 SetResult(controller->CreateWindowValueWithTabs(extension()));
695 } 696 }
696 697
697 return true; 698 return true;
698 } 699 }
699 700
700 bool WindowsUpdateFunction::RunSync() { 701 bool WindowsUpdateFunction::RunSync() {
701 scoped_ptr<windows::Update::Params> params( 702 std::unique_ptr<windows::Update::Params> params(
702 windows::Update::Params::Create(*args_)); 703 windows::Update::Params::Create(*args_));
703 EXTENSION_FUNCTION_VALIDATE(params); 704 EXTENSION_FUNCTION_VALIDATE(params);
704 705
705 WindowController* controller; 706 WindowController* controller;
706 if (!windows_util::GetWindowFromWindowID( 707 if (!windows_util::GetWindowFromWindowID(
707 this, params->window_id, WindowController::GetAllWindowFilter(), 708 this, params->window_id, WindowController::GetAllWindowFilter(),
708 &controller)) { 709 &controller)) {
709 return false; 710 return false;
710 } 711 }
711 712
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 796
796 if (params->update_info.draw_attention) 797 if (params->update_info.draw_attention)
797 controller->window()->FlashFrame(*params->update_info.draw_attention); 798 controller->window()->FlashFrame(*params->update_info.draw_attention);
798 799
799 SetResult(controller->CreateWindowValue()); 800 SetResult(controller->CreateWindowValue());
800 801
801 return true; 802 return true;
802 } 803 }
803 804
804 bool WindowsRemoveFunction::RunSync() { 805 bool WindowsRemoveFunction::RunSync() {
805 scoped_ptr<windows::Remove::Params> params( 806 std::unique_ptr<windows::Remove::Params> params(
806 windows::Remove::Params::Create(*args_)); 807 windows::Remove::Params::Create(*args_));
807 EXTENSION_FUNCTION_VALIDATE(params); 808 EXTENSION_FUNCTION_VALIDATE(params);
808 809
809 WindowController* controller; 810 WindowController* controller;
810 if (!windows_util::GetWindowFromWindowID(this, params->window_id, 811 if (!windows_util::GetWindowFromWindowID(this, params->window_id,
811 WindowController::kNoWindowFilter, 812 WindowController::kNoWindowFilter,
812 &controller)) { 813 &controller)) {
813 return false; 814 return false;
814 } 815 }
815 816
816 WindowController::Reason reason; 817 WindowController::Reason reason;
817 if (!controller->CanClose(&reason)) { 818 if (!controller->CanClose(&reason)) {
818 if (reason == WindowController::REASON_NOT_EDITABLE) 819 if (reason == WindowController::REASON_NOT_EDITABLE)
819 error_ = keys::kTabStripNotEditableError; 820 error_ = keys::kTabStripNotEditableError;
820 return false; 821 return false;
821 } 822 }
822 controller->window()->Close(); 823 controller->window()->Close();
823 return true; 824 return true;
824 } 825 }
825 826
826 // Tabs ------------------------------------------------------------------------ 827 // Tabs ------------------------------------------------------------------------
827 828
828 bool TabsGetSelectedFunction::RunSync() { 829 bool TabsGetSelectedFunction::RunSync() {
829 // windowId defaults to "current" window. 830 // windowId defaults to "current" window.
830 int window_id = extension_misc::kCurrentWindowId; 831 int window_id = extension_misc::kCurrentWindowId;
831 832
832 scoped_ptr<tabs::GetSelected::Params> params( 833 std::unique_ptr<tabs::GetSelected::Params> params(
833 tabs::GetSelected::Params::Create(*args_)); 834 tabs::GetSelected::Params::Create(*args_));
834 EXTENSION_FUNCTION_VALIDATE(params.get()); 835 EXTENSION_FUNCTION_VALIDATE(params.get());
835 if (params->window_id.get()) 836 if (params->window_id.get())
836 window_id = *params->window_id; 837 window_id = *params->window_id;
837 838
838 Browser* browser = NULL; 839 Browser* browser = NULL;
839 if (!GetBrowserFromWindowID(this, window_id, &browser)) 840 if (!GetBrowserFromWindowID(this, window_id, &browser))
840 return false; 841 return false;
841 842
842 TabStripModel* tab_strip = browser->tab_strip_model(); 843 TabStripModel* tab_strip = browser->tab_strip_model();
843 WebContents* contents = tab_strip->GetActiveWebContents(); 844 WebContents* contents = tab_strip->GetActiveWebContents();
844 if (!contents) { 845 if (!contents) {
845 error_ = keys::kNoSelectedTabError; 846 error_ = keys::kNoSelectedTabError;
846 return false; 847 return false;
847 } 848 }
848 results_ = tabs::Get::Results::Create(*ExtensionTabUtil::CreateTabObject( 849 results_ = tabs::Get::Results::Create(*ExtensionTabUtil::CreateTabObject(
849 contents, tab_strip, tab_strip->active_index(), extension())); 850 contents, tab_strip, tab_strip->active_index(), extension()));
850 return true; 851 return true;
851 } 852 }
852 853
853 bool TabsGetAllInWindowFunction::RunSync() { 854 bool TabsGetAllInWindowFunction::RunSync() {
854 scoped_ptr<tabs::GetAllInWindow::Params> params( 855 std::unique_ptr<tabs::GetAllInWindow::Params> params(
855 tabs::GetAllInWindow::Params::Create(*args_)); 856 tabs::GetAllInWindow::Params::Create(*args_));
856 EXTENSION_FUNCTION_VALIDATE(params.get()); 857 EXTENSION_FUNCTION_VALIDATE(params.get());
857 // windowId defaults to "current" window. 858 // windowId defaults to "current" window.
858 int window_id = extension_misc::kCurrentWindowId; 859 int window_id = extension_misc::kCurrentWindowId;
859 if (params->window_id.get()) 860 if (params->window_id.get())
860 window_id = *params->window_id; 861 window_id = *params->window_id;
861 862
862 Browser* browser = NULL; 863 Browser* browser = NULL;
863 if (!GetBrowserFromWindowID(this, window_id, &browser)) 864 if (!GetBrowserFromWindowID(this, window_id, &browser))
864 return false; 865 return false;
865 866
866 SetResult(ExtensionTabUtil::CreateTabList(browser, extension())); 867 SetResult(ExtensionTabUtil::CreateTabList(browser, extension()));
867 868
868 return true; 869 return true;
869 } 870 }
870 871
871 bool TabsQueryFunction::RunSync() { 872 bool TabsQueryFunction::RunSync() {
872 scoped_ptr<tabs::Query::Params> params(tabs::Query::Params::Create(*args_)); 873 std::unique_ptr<tabs::Query::Params> params(
874 tabs::Query::Params::Create(*args_));
873 EXTENSION_FUNCTION_VALIDATE(params.get()); 875 EXTENSION_FUNCTION_VALIDATE(params.get());
874 876
875 bool loading_status_set = params->query_info.status != tabs::TAB_STATUS_NONE; 877 bool loading_status_set = params->query_info.status != tabs::TAB_STATUS_NONE;
876 bool loading = params->query_info.status == tabs::TAB_STATUS_LOADING; 878 bool loading = params->query_info.status == tabs::TAB_STATUS_LOADING;
877 879
878 URLPatternSet url_patterns; 880 URLPatternSet url_patterns;
879 if (params->query_info.url.get()) { 881 if (params->query_info.url.get()) {
880 std::vector<std::string> url_pattern_strings; 882 std::vector<std::string> url_pattern_strings;
881 if (params->query_info.url->as_string) 883 if (params->query_info.url->as_string)
882 url_pattern_strings.push_back(*params->query_info.url->as_string); 884 url_pattern_strings.push_back(*params->query_info.url->as_string);
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 ->ToValue() 1017 ->ToValue()
1016 .release()); 1018 .release());
1017 } 1019 }
1018 } 1020 }
1019 1021
1020 SetResult(result); 1022 SetResult(result);
1021 return true; 1023 return true;
1022 } 1024 }
1023 1025
1024 bool TabsCreateFunction::RunSync() { 1026 bool TabsCreateFunction::RunSync() {
1025 scoped_ptr<tabs::Create::Params> params(tabs::Create::Params::Create(*args_)); 1027 std::unique_ptr<tabs::Create::Params> params(
1028 tabs::Create::Params::Create(*args_));
1026 EXTENSION_FUNCTION_VALIDATE(params.get()); 1029 EXTENSION_FUNCTION_VALIDATE(params.get());
1027 1030
1028 ExtensionTabUtil::OpenTabParams options; 1031 ExtensionTabUtil::OpenTabParams options;
1029 AssignOptionalValue(params->create_properties.window_id, options.window_id); 1032 AssignOptionalValue(params->create_properties.window_id, options.window_id);
1030 AssignOptionalValue(params->create_properties.opener_tab_id, 1033 AssignOptionalValue(params->create_properties.opener_tab_id,
1031 options.opener_tab_id); 1034 options.opener_tab_id);
1032 AssignOptionalValue(params->create_properties.selected, options.active); 1035 AssignOptionalValue(params->create_properties.selected, options.active);
1033 // The 'active' property has replaced the 'selected' property. 1036 // The 'active' property has replaced the 'selected' property.
1034 AssignOptionalValue(params->create_properties.active, options.active); 1037 AssignOptionalValue(params->create_properties.active, options.active);
1035 AssignOptionalValue(params->create_properties.pinned, options.pinned); 1038 AssignOptionalValue(params->create_properties.pinned, options.pinned);
1036 AssignOptionalValue(params->create_properties.index, options.index); 1039 AssignOptionalValue(params->create_properties.index, options.index);
1037 AssignOptionalValue(params->create_properties.url, options.url); 1040 AssignOptionalValue(params->create_properties.url, options.url);
1038 1041
1039 std::string error; 1042 std::string error;
1040 scoped_ptr<base::DictionaryValue> result( 1043 std::unique_ptr<base::DictionaryValue> result(
1041 ExtensionTabUtil::OpenTab(this, options, &error)); 1044 ExtensionTabUtil::OpenTab(this, options, &error));
1042 if (!result) { 1045 if (!result) {
1043 SetError(error); 1046 SetError(error);
1044 return false; 1047 return false;
1045 } 1048 }
1046 1049
1047 // Return data about the newly created tab. 1050 // Return data about the newly created tab.
1048 if (has_callback()) { 1051 if (has_callback()) {
1049 SetResult(result.release()); 1052 SetResult(result.release());
1050 } 1053 }
1051 return true; 1054 return true;
1052 } 1055 }
1053 1056
1054 bool TabsDuplicateFunction::RunSync() { 1057 bool TabsDuplicateFunction::RunSync() {
1055 scoped_ptr<tabs::Duplicate::Params> params( 1058 std::unique_ptr<tabs::Duplicate::Params> params(
1056 tabs::Duplicate::Params::Create(*args_)); 1059 tabs::Duplicate::Params::Create(*args_));
1057 EXTENSION_FUNCTION_VALIDATE(params.get()); 1060 EXTENSION_FUNCTION_VALIDATE(params.get());
1058 int tab_id = params->tab_id; 1061 int tab_id = params->tab_id;
1059 1062
1060 Browser* browser = NULL; 1063 Browser* browser = NULL;
1061 TabStripModel* tab_strip = NULL; 1064 TabStripModel* tab_strip = NULL;
1062 int tab_index = -1; 1065 int tab_index = -1;
1063 if (!GetTabById(tab_id, 1066 if (!GetTabById(tab_id,
1064 GetProfile(), 1067 GetProfile(),
1065 include_incognito(), 1068 include_incognito(),
(...skipping 21 matching lines...) Expand all
1087 } 1090 }
1088 1091
1089 // Return data about the newly created tab. 1092 // Return data about the newly created tab.
1090 results_ = tabs::Get::Results::Create(*ExtensionTabUtil::CreateTabObject( 1093 results_ = tabs::Get::Results::Create(*ExtensionTabUtil::CreateTabObject(
1091 new_contents, new_tab_strip, new_tab_index, extension())); 1094 new_contents, new_tab_strip, new_tab_index, extension()));
1092 1095
1093 return true; 1096 return true;
1094 } 1097 }
1095 1098
1096 bool TabsGetFunction::RunSync() { 1099 bool TabsGetFunction::RunSync() {
1097 scoped_ptr<tabs::Get::Params> params(tabs::Get::Params::Create(*args_)); 1100 std::unique_ptr<tabs::Get::Params> params(tabs::Get::Params::Create(*args_));
1098 EXTENSION_FUNCTION_VALIDATE(params.get()); 1101 EXTENSION_FUNCTION_VALIDATE(params.get());
1099 int tab_id = params->tab_id; 1102 int tab_id = params->tab_id;
1100 1103
1101 TabStripModel* tab_strip = NULL; 1104 TabStripModel* tab_strip = NULL;
1102 WebContents* contents = NULL; 1105 WebContents* contents = NULL;
1103 int tab_index = -1; 1106 int tab_index = -1;
1104 if (!GetTabById(tab_id, 1107 if (!GetTabById(tab_id,
1105 GetProfile(), 1108 GetProfile(),
1106 include_incognito(), 1109 include_incognito(),
1107 NULL, 1110 NULL,
(...skipping 15 matching lines...) Expand all
1123 // empty tab (hence returning true). 1126 // empty tab (hence returning true).
1124 WebContents* caller_contents = GetSenderWebContents(); 1127 WebContents* caller_contents = GetSenderWebContents();
1125 if (caller_contents && ExtensionTabUtil::GetTabId(caller_contents) >= 0) 1128 if (caller_contents && ExtensionTabUtil::GetTabId(caller_contents) >= 0)
1126 results_ = tabs::Get::Results::Create( 1129 results_ = tabs::Get::Results::Create(
1127 *ExtensionTabUtil::CreateTabObject(caller_contents, extension())); 1130 *ExtensionTabUtil::CreateTabObject(caller_contents, extension()));
1128 1131
1129 return true; 1132 return true;
1130 } 1133 }
1131 1134
1132 bool TabsHighlightFunction::RunSync() { 1135 bool TabsHighlightFunction::RunSync() {
1133 scoped_ptr<tabs::Highlight::Params> params( 1136 std::unique_ptr<tabs::Highlight::Params> params(
1134 tabs::Highlight::Params::Create(*args_)); 1137 tabs::Highlight::Params::Create(*args_));
1135 EXTENSION_FUNCTION_VALIDATE(params.get()); 1138 EXTENSION_FUNCTION_VALIDATE(params.get());
1136 1139
1137 // Get the window id from the params; default to current window if omitted. 1140 // Get the window id from the params; default to current window if omitted.
1138 int window_id = extension_misc::kCurrentWindowId; 1141 int window_id = extension_misc::kCurrentWindowId;
1139 if (params->highlight_info.window_id.get()) 1142 if (params->highlight_info.window_id.get())
1140 window_id = *params->highlight_info.window_id; 1143 window_id = *params->highlight_info.window_id;
1141 1144
1142 Browser* browser = NULL; 1145 Browser* browser = NULL;
1143 if (!GetBrowserFromWindowID(this, window_id, &browser)) 1146 if (!GetBrowserFromWindowID(this, window_id, &browser))
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1193 *active_index = index; 1196 *active_index = index;
1194 1197
1195 selection->AddIndexToSelection(index); 1198 selection->AddIndexToSelection(index);
1196 return true; 1199 return true;
1197 } 1200 }
1198 1201
1199 TabsUpdateFunction::TabsUpdateFunction() : web_contents_(NULL) { 1202 TabsUpdateFunction::TabsUpdateFunction() : web_contents_(NULL) {
1200 } 1203 }
1201 1204
1202 bool TabsUpdateFunction::RunAsync() { 1205 bool TabsUpdateFunction::RunAsync() {
1203 scoped_ptr<tabs::Update::Params> params(tabs::Update::Params::Create(*args_)); 1206 std::unique_ptr<tabs::Update::Params> params(
1207 tabs::Update::Params::Create(*args_));
1204 EXTENSION_FUNCTION_VALIDATE(params.get()); 1208 EXTENSION_FUNCTION_VALIDATE(params.get());
1205 1209
1206 int tab_id = -1; 1210 int tab_id = -1;
1207 WebContents* contents = NULL; 1211 WebContents* contents = NULL;
1208 if (!params->tab_id.get()) { 1212 if (!params->tab_id.get()) {
1209 Browser* browser = GetCurrentBrowser(); 1213 Browser* browser = GetCurrentBrowser();
1210 if (!browser) { 1214 if (!browser) {
1211 error_ = keys::kNoCurrentWindowError; 1215 error_ = keys::kNoCurrentWindowError;
1212 return false; 1216 return false;
1213 } 1217 }
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 const GURL& url, 1398 const GURL& url,
1395 const base::ListValue& script_result) { 1399 const base::ListValue& script_result) {
1396 if (error.empty()) 1400 if (error.empty())
1397 PopulateResult(); 1401 PopulateResult();
1398 else 1402 else
1399 error_ = error; 1403 error_ = error;
1400 SendResponse(error.empty()); 1404 SendResponse(error.empty());
1401 } 1405 }
1402 1406
1403 bool TabsMoveFunction::RunSync() { 1407 bool TabsMoveFunction::RunSync() {
1404 scoped_ptr<tabs::Move::Params> params(tabs::Move::Params::Create(*args_)); 1408 std::unique_ptr<tabs::Move::Params> params(
1409 tabs::Move::Params::Create(*args_));
1405 EXTENSION_FUNCTION_VALIDATE(params.get()); 1410 EXTENSION_FUNCTION_VALIDATE(params.get());
1406 1411
1407 int new_index = params->move_properties.index; 1412 int new_index = params->move_properties.index;
1408 int* window_id = params->move_properties.window_id.get(); 1413 int* window_id = params->move_properties.window_id.get();
1409 scoped_ptr<base::ListValue> tab_values(new base::ListValue()); 1414 std::unique_ptr<base::ListValue> tab_values(new base::ListValue());
1410 1415
1411 size_t num_tabs = 0; 1416 size_t num_tabs = 0;
1412 if (params->tab_ids.as_integers) { 1417 if (params->tab_ids.as_integers) {
1413 std::vector<int>& tab_ids = *params->tab_ids.as_integers; 1418 std::vector<int>& tab_ids = *params->tab_ids.as_integers;
1414 num_tabs = tab_ids.size(); 1419 num_tabs = tab_ids.size();
1415 for (size_t i = 0; i < tab_ids.size(); ++i) { 1420 for (size_t i = 0; i < tab_ids.size(); ++i) {
1416 if (!MoveTab(tab_ids[i], &new_index, i, tab_values.get(), window_id)) 1421 if (!MoveTab(tab_ids[i], &new_index, i, tab_values.get(), window_id))
1417 return false; 1422 return false;
1418 } 1423 }
1419 } else { 1424 } else {
1420 EXTENSION_FUNCTION_VALIDATE(params->tab_ids.as_integer); 1425 EXTENSION_FUNCTION_VALIDATE(params->tab_ids.as_integer);
1421 num_tabs = 1; 1426 num_tabs = 1;
1422 if (!MoveTab(*params->tab_ids.as_integer, 1427 if (!MoveTab(*params->tab_ids.as_integer,
1423 &new_index, 1428 &new_index,
1424 0, 1429 0,
1425 tab_values.get(), 1430 tab_values.get(),
1426 window_id)) { 1431 window_id)) {
1427 return false; 1432 return false;
1428 } 1433 }
1429 } 1434 }
1430 1435
1431 if (!has_callback()) 1436 if (!has_callback())
1432 return true; 1437 return true;
1433 1438
1434 if (num_tabs == 0) { 1439 if (num_tabs == 0) {
1435 error_ = "No tabs given."; 1440 error_ = "No tabs given.";
1436 return false; 1441 return false;
1437 } else if (num_tabs == 1) { 1442 } else if (num_tabs == 1) {
1438 scoped_ptr<base::Value> value; 1443 std::unique_ptr<base::Value> value;
1439 CHECK(tab_values.get()->Remove(0, &value)); 1444 CHECK(tab_values.get()->Remove(0, &value));
1440 SetResult(value.release()); 1445 SetResult(value.release());
1441 } else { 1446 } else {
1442 // Only return the results as an array if there are multiple tabs. 1447 // Only return the results as an array if there are multiple tabs.
1443 SetResult(tab_values.release()); 1448 SetResult(tab_values.release());
1444 } 1449 }
1445 1450
1446 return true; 1451 return true;
1447 } 1452 }
1448 1453
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1543 tab_values->Append(ExtensionTabUtil::CreateTabObject( 1548 tab_values->Append(ExtensionTabUtil::CreateTabObject(
1544 contents, source_tab_strip, *new_index, extension()) 1549 contents, source_tab_strip, *new_index, extension())
1545 ->ToValue() 1550 ->ToValue()
1546 .release()); 1551 .release());
1547 } 1552 }
1548 1553
1549 return true; 1554 return true;
1550 } 1555 }
1551 1556
1552 bool TabsReloadFunction::RunSync() { 1557 bool TabsReloadFunction::RunSync() {
1553 scoped_ptr<tabs::Reload::Params> params( 1558 std::unique_ptr<tabs::Reload::Params> params(
1554 tabs::Reload::Params::Create(*args_)); 1559 tabs::Reload::Params::Create(*args_));
1555 EXTENSION_FUNCTION_VALIDATE(params.get()); 1560 EXTENSION_FUNCTION_VALIDATE(params.get());
1556 1561
1557 bool bypass_cache = false; 1562 bool bypass_cache = false;
1558 if (params->reload_properties.get() && 1563 if (params->reload_properties.get() &&
1559 params->reload_properties->bypass_cache.get()) { 1564 params->reload_properties->bypass_cache.get()) {
1560 bypass_cache = *params->reload_properties->bypass_cache; 1565 bypass_cache = *params->reload_properties->bypass_cache;
1561 } 1566 }
1562 1567
1563 content::WebContents* web_contents = NULL; 1568 content::WebContents* web_contents = NULL;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1599 } else if (bypass_cache) { 1604 } else if (bypass_cache) {
1600 web_contents->GetController().ReloadBypassingCache(true); 1605 web_contents->GetController().ReloadBypassingCache(true);
1601 } else { 1606 } else {
1602 web_contents->GetController().Reload(true); 1607 web_contents->GetController().Reload(true);
1603 } 1608 }
1604 1609
1605 return true; 1610 return true;
1606 } 1611 }
1607 1612
1608 bool TabsRemoveFunction::RunSync() { 1613 bool TabsRemoveFunction::RunSync() {
1609 scoped_ptr<tabs::Remove::Params> params(tabs::Remove::Params::Create(*args_)); 1614 std::unique_ptr<tabs::Remove::Params> params(
1615 tabs::Remove::Params::Create(*args_));
1610 EXTENSION_FUNCTION_VALIDATE(params.get()); 1616 EXTENSION_FUNCTION_VALIDATE(params.get());
1611 1617
1612 if (params->tab_ids.as_integers) { 1618 if (params->tab_ids.as_integers) {
1613 std::vector<int>& tab_ids = *params->tab_ids.as_integers; 1619 std::vector<int>& tab_ids = *params->tab_ids.as_integers;
1614 for (size_t i = 0; i < tab_ids.size(); ++i) { 1620 for (size_t i = 0; i < tab_ids.size(); ++i) {
1615 if (!RemoveTab(tab_ids[i])) 1621 if (!RemoveTab(tab_ids[i]))
1616 return false; 1622 return false;
1617 } 1623 }
1618 } else { 1624 } else {
1619 EXTENSION_FUNCTION_VALIDATE(params->tab_ids.as_integer); 1625 EXTENSION_FUNCTION_VALIDATE(params->tab_ids.as_integer);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1690 } 1696 }
1691 1697
1692 bool TabsCaptureVisibleTabFunction::RunAsync() { 1698 bool TabsCaptureVisibleTabFunction::RunAsync() {
1693 using api::extension_types::ImageDetails; 1699 using api::extension_types::ImageDetails;
1694 1700
1695 EXTENSION_FUNCTION_VALIDATE(args_); 1701 EXTENSION_FUNCTION_VALIDATE(args_);
1696 1702
1697 int context_id = extension_misc::kCurrentWindowId; 1703 int context_id = extension_misc::kCurrentWindowId;
1698 args_->GetInteger(0, &context_id); 1704 args_->GetInteger(0, &context_id);
1699 1705
1700 scoped_ptr<ImageDetails> image_details; 1706 std::unique_ptr<ImageDetails> image_details;
1701 if (args_->GetSize() > 1) { 1707 if (args_->GetSize() > 1) {
1702 base::Value* spec = NULL; 1708 base::Value* spec = NULL;
1703 EXTENSION_FUNCTION_VALIDATE(args_->Get(1, &spec) && spec); 1709 EXTENSION_FUNCTION_VALIDATE(args_->Get(1, &spec) && spec);
1704 image_details = ImageDetails::FromValue(*spec); 1710 image_details = ImageDetails::FromValue(*spec);
1705 } 1711 }
1706 1712
1707 WebContents* contents = GetWebContentsForID(context_id); 1713 WebContents* contents = GetWebContentsForID(context_id);
1708 1714
1709 return CaptureAsync( 1715 return CaptureAsync(
1710 contents, image_details.get(), 1716 contents, image_details.get(),
(...skipping 29 matching lines...) Expand all
1740 reason_description); 1746 reason_description);
1741 SendResponse(false); 1747 SendResponse(false);
1742 } 1748 }
1743 1749
1744 void TabsCaptureVisibleTabFunction::RegisterProfilePrefs( 1750 void TabsCaptureVisibleTabFunction::RegisterProfilePrefs(
1745 user_prefs::PrefRegistrySyncable* registry) { 1751 user_prefs::PrefRegistrySyncable* registry) {
1746 registry->RegisterBooleanPref(prefs::kDisableScreenshots, false); 1752 registry->RegisterBooleanPref(prefs::kDisableScreenshots, false);
1747 } 1753 }
1748 1754
1749 bool TabsDetectLanguageFunction::RunAsync() { 1755 bool TabsDetectLanguageFunction::RunAsync() {
1750 scoped_ptr<tabs::DetectLanguage::Params> params( 1756 std::unique_ptr<tabs::DetectLanguage::Params> params(
1751 tabs::DetectLanguage::Params::Create(*args_)); 1757 tabs::DetectLanguage::Params::Create(*args_));
1752 EXTENSION_FUNCTION_VALIDATE(params.get()); 1758 EXTENSION_FUNCTION_VALIDATE(params.get());
1753 1759
1754 int tab_id = 0; 1760 int tab_id = 0;
1755 Browser* browser = NULL; 1761 Browser* browser = NULL;
1756 WebContents* contents = NULL; 1762 WebContents* contents = NULL;
1757 1763
1758 // If |tab_id| is specified, look for it. Otherwise default to selected tab 1764 // If |tab_id| is specified, look for it. Otherwise default to selected tab
1759 // in the current window. 1765 // in the current window.
1760 if (params->tab_id.get()) { 1766 if (params->tab_id.get()) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1862 1868
1863 // |tab_id| is optional so it's ok if it's not there. 1869 // |tab_id| is optional so it's ok if it's not there.
1864 int tab_id = -1; 1870 int tab_id = -1;
1865 if (args_->GetInteger(0, &tab_id)) 1871 if (args_->GetInteger(0, &tab_id))
1866 EXTENSION_FUNCTION_VALIDATE(tab_id >= 0); 1872 EXTENSION_FUNCTION_VALIDATE(tab_id >= 0);
1867 1873
1868 // |details| are not optional. 1874 // |details| are not optional.
1869 base::DictionaryValue* details_value = NULL; 1875 base::DictionaryValue* details_value = NULL;
1870 if (!args_->GetDictionary(1, &details_value)) 1876 if (!args_->GetDictionary(1, &details_value))
1871 return false; 1877 return false;
1872 scoped_ptr<InjectDetails> details(new InjectDetails()); 1878 std::unique_ptr<InjectDetails> details(new InjectDetails());
1873 if (!InjectDetails::Populate(*details_value, details.get())) 1879 if (!InjectDetails::Populate(*details_value, details.get()))
1874 return false; 1880 return false;
1875 1881
1876 // If the tab ID wasn't given then it needs to be converted to the 1882 // If the tab ID wasn't given then it needs to be converted to the
1877 // currently active tab's ID. 1883 // currently active tab's ID.
1878 if (tab_id == -1) { 1884 if (tab_id == -1) {
1879 Browser* browser = chrome_details_.GetCurrentBrowser(); 1885 Browser* browser = chrome_details_.GetCurrentBrowser();
1880 if (!browser) 1886 if (!browser)
1881 return false; 1887 return false;
1882 content::WebContents* web_contents = NULL; 1888 content::WebContents* web_contents = NULL;
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2015 Browser* browser = GetCurrentBrowser(); 2021 Browser* browser = GetCurrentBrowser();
2016 if (!browser) 2022 if (!browser)
2017 error_ = keys::kNoCurrentWindowError; 2023 error_ = keys::kNoCurrentWindowError;
2018 else if (!ExtensionTabUtil::GetDefaultTab(browser, &web_contents, NULL)) 2024 else if (!ExtensionTabUtil::GetDefaultTab(browser, &web_contents, NULL))
2019 error_ = keys::kNoSelectedTabError; 2025 error_ = keys::kNoSelectedTabError;
2020 } 2026 }
2021 return web_contents; 2027 return web_contents;
2022 } 2028 }
2023 2029
2024 bool TabsSetZoomFunction::RunAsync() { 2030 bool TabsSetZoomFunction::RunAsync() {
2025 scoped_ptr<tabs::SetZoom::Params> params( 2031 std::unique_ptr<tabs::SetZoom::Params> params(
2026 tabs::SetZoom::Params::Create(*args_)); 2032 tabs::SetZoom::Params::Create(*args_));
2027 EXTENSION_FUNCTION_VALIDATE(params); 2033 EXTENSION_FUNCTION_VALIDATE(params);
2028 2034
2029 int tab_id = params->tab_id ? *params->tab_id : -1; 2035 int tab_id = params->tab_id ? *params->tab_id : -1;
2030 WebContents* web_contents = GetWebContents(tab_id); 2036 WebContents* web_contents = GetWebContents(tab_id);
2031 if (!web_contents) 2037 if (!web_contents)
2032 return false; 2038 return false;
2033 2039
2034 GURL url(web_contents->GetVisibleURL()); 2040 GURL url(web_contents->GetVisibleURL());
2035 if (PermissionsData::IsRestrictedUrl(url, extension(), &error_)) 2041 if (PermissionsData::IsRestrictedUrl(url, extension(), &error_))
(...skipping 11 matching lines...) Expand all
2047 // Tried to zoom a tab in disabled mode. 2053 // Tried to zoom a tab in disabled mode.
2048 error_ = keys::kCannotZoomDisabledTabError; 2054 error_ = keys::kCannotZoomDisabledTabError;
2049 return false; 2055 return false;
2050 } 2056 }
2051 2057
2052 SendResponse(true); 2058 SendResponse(true);
2053 return true; 2059 return true;
2054 } 2060 }
2055 2061
2056 bool TabsGetZoomFunction::RunAsync() { 2062 bool TabsGetZoomFunction::RunAsync() {
2057 scoped_ptr<tabs::GetZoom::Params> params( 2063 std::unique_ptr<tabs::GetZoom::Params> params(
2058 tabs::GetZoom::Params::Create(*args_)); 2064 tabs::GetZoom::Params::Create(*args_));
2059 EXTENSION_FUNCTION_VALIDATE(params); 2065 EXTENSION_FUNCTION_VALIDATE(params);
2060 2066
2061 int tab_id = params->tab_id ? *params->tab_id : -1; 2067 int tab_id = params->tab_id ? *params->tab_id : -1;
2062 WebContents* web_contents = GetWebContents(tab_id); 2068 WebContents* web_contents = GetWebContents(tab_id);
2063 if (!web_contents) 2069 if (!web_contents)
2064 return false; 2070 return false;
2065 2071
2066 double zoom_level = 2072 double zoom_level =
2067 ZoomController::FromWebContents(web_contents)->GetZoomLevel(); 2073 ZoomController::FromWebContents(web_contents)->GetZoomLevel();
2068 double zoom_factor = content::ZoomLevelToZoomFactor(zoom_level); 2074 double zoom_factor = content::ZoomLevelToZoomFactor(zoom_level);
2069 results_ = tabs::GetZoom::Results::Create(zoom_factor); 2075 results_ = tabs::GetZoom::Results::Create(zoom_factor);
2070 SendResponse(true); 2076 SendResponse(true);
2071 return true; 2077 return true;
2072 } 2078 }
2073 2079
2074 bool TabsSetZoomSettingsFunction::RunAsync() { 2080 bool TabsSetZoomSettingsFunction::RunAsync() {
2075 using api::tabs::ZoomSettings; 2081 using api::tabs::ZoomSettings;
2076 2082
2077 scoped_ptr<tabs::SetZoomSettings::Params> params( 2083 std::unique_ptr<tabs::SetZoomSettings::Params> params(
2078 tabs::SetZoomSettings::Params::Create(*args_)); 2084 tabs::SetZoomSettings::Params::Create(*args_));
2079 EXTENSION_FUNCTION_VALIDATE(params); 2085 EXTENSION_FUNCTION_VALIDATE(params);
2080 2086
2081 int tab_id = params->tab_id ? *params->tab_id : -1; 2087 int tab_id = params->tab_id ? *params->tab_id : -1;
2082 WebContents* web_contents = GetWebContents(tab_id); 2088 WebContents* web_contents = GetWebContents(tab_id);
2083 if (!web_contents) 2089 if (!web_contents)
2084 return false; 2090 return false;
2085 2091
2086 GURL url(web_contents->GetVisibleURL()); 2092 GURL url(web_contents->GetVisibleURL());
2087 if (PermissionsData::IsRestrictedUrl(url, extension(), &error_)) 2093 if (PermissionsData::IsRestrictedUrl(url, extension(), &error_))
(...skipping 29 matching lines...) Expand all
2117 zoom_mode = ZoomController::ZOOM_MODE_DISABLED; 2123 zoom_mode = ZoomController::ZOOM_MODE_DISABLED;
2118 } 2124 }
2119 2125
2120 ZoomController::FromWebContents(web_contents)->SetZoomMode(zoom_mode); 2126 ZoomController::FromWebContents(web_contents)->SetZoomMode(zoom_mode);
2121 2127
2122 SendResponse(true); 2128 SendResponse(true);
2123 return true; 2129 return true;
2124 } 2130 }
2125 2131
2126 bool TabsGetZoomSettingsFunction::RunAsync() { 2132 bool TabsGetZoomSettingsFunction::RunAsync() {
2127 scoped_ptr<tabs::GetZoomSettings::Params> params( 2133 std::unique_ptr<tabs::GetZoomSettings::Params> params(
2128 tabs::GetZoomSettings::Params::Create(*args_)); 2134 tabs::GetZoomSettings::Params::Create(*args_));
2129 EXTENSION_FUNCTION_VALIDATE(params); 2135 EXTENSION_FUNCTION_VALIDATE(params);
2130 2136
2131 int tab_id = params->tab_id ? *params->tab_id : -1; 2137 int tab_id = params->tab_id ? *params->tab_id : -1;
2132 WebContents* web_contents = GetWebContents(tab_id); 2138 WebContents* web_contents = GetWebContents(tab_id);
2133 if (!web_contents) 2139 if (!web_contents)
2134 return false; 2140 return false;
2135 ZoomController* zoom_controller = 2141 ZoomController* zoom_controller =
2136 ZoomController::FromWebContents(web_contents); 2142 ZoomController::FromWebContents(web_contents);
2137 2143
2138 ZoomController::ZoomMode zoom_mode = zoom_controller->zoom_mode(); 2144 ZoomController::ZoomMode zoom_mode = zoom_controller->zoom_mode();
2139 api::tabs::ZoomSettings zoom_settings; 2145 api::tabs::ZoomSettings zoom_settings;
2140 ZoomModeToZoomSettings(zoom_mode, &zoom_settings); 2146 ZoomModeToZoomSettings(zoom_mode, &zoom_settings);
2141 zoom_settings.default_zoom_factor.reset(new double( 2147 zoom_settings.default_zoom_factor.reset(new double(
2142 content::ZoomLevelToZoomFactor(zoom_controller->GetDefaultZoomLevel()))); 2148 content::ZoomLevelToZoomFactor(zoom_controller->GetDefaultZoomLevel())));
2143 2149
2144 results_ = api::tabs::GetZoomSettings::Results::Create(zoom_settings); 2150 results_ = api::tabs::GetZoomSettings::Results::Create(zoom_settings);
2145 SendResponse(true); 2151 SendResponse(true);
2146 return true; 2152 return true;
2147 } 2153 }
2148 2154
2149 } // namespace extensions 2155 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/tabs/ash_panel_contents.h ('k') | chrome/browser/extensions/api/tabs/tabs_api_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698