| OLD | NEW |
| 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 <memory> | 10 #include <memory> |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 #include "chrome/browser/sessions/session_tab_helper.h" | 41 #include "chrome/browser/sessions/session_tab_helper.h" |
| 42 #include "chrome/browser/translate/chrome_translate_client.h" | 42 #include "chrome/browser/translate/chrome_translate_client.h" |
| 43 #include "chrome/browser/ui/apps/chrome_app_delegate.h" | 43 #include "chrome/browser/ui/apps/chrome_app_delegate.h" |
| 44 #include "chrome/browser/ui/browser.h" | 44 #include "chrome/browser/ui/browser.h" |
| 45 #include "chrome/browser/ui/browser_commands.h" | 45 #include "chrome/browser/ui/browser_commands.h" |
| 46 #include "chrome/browser/ui/browser_finder.h" | 46 #include "chrome/browser/ui/browser_finder.h" |
| 47 #include "chrome/browser/ui/browser_list.h" | 47 #include "chrome/browser/ui/browser_list.h" |
| 48 #include "chrome/browser/ui/browser_navigator.h" | 48 #include "chrome/browser/ui/browser_navigator.h" |
| 49 #include "chrome/browser/ui/browser_navigator_params.h" | 49 #include "chrome/browser/ui/browser_navigator_params.h" |
| 50 #include "chrome/browser/ui/browser_window.h" | 50 #include "chrome/browser/ui/browser_window.h" |
| 51 #include "chrome/browser/ui/panels/panel_manager.h" | |
| 52 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 51 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 53 #include "chrome/browser/ui/tabs/tab_utils.h" | 52 #include "chrome/browser/ui/tabs/tab_utils.h" |
| 54 #include "chrome/browser/ui/window_sizer/window_sizer.h" | 53 #include "chrome/browser/ui/window_sizer/window_sizer.h" |
| 55 #include "chrome/browser/web_applications/web_app.h" | 54 #include "chrome/browser/web_applications/web_app.h" |
| 56 #include "chrome/common/chrome_switches.h" | 55 #include "chrome/common/chrome_switches.h" |
| 57 #include "chrome/common/extensions/api/tabs.h" | 56 #include "chrome/common/extensions/api/tabs.h" |
| 58 #include "chrome/common/extensions/api/windows.h" | 57 #include "chrome/common/extensions/api/windows.h" |
| 59 #include "chrome/common/extensions/extension_constants.h" | 58 #include "chrome/common/extensions/extension_constants.h" |
| 60 #include "chrome/common/pref_names.h" | 59 #include "chrome/common/pref_names.h" |
| 61 #include "chrome/common/url_constants.h" | 60 #include "chrome/common/url_constants.h" |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 !is_panel; | 253 !is_panel; |
| 255 case windows::WINDOW_STATE_NORMAL: | 254 case windows::WINDOW_STATE_NORMAL: |
| 256 case windows::WINDOW_STATE_DOCKED: | 255 case windows::WINDOW_STATE_DOCKED: |
| 257 case windows::WINDOW_STATE_NONE: | 256 case windows::WINDOW_STATE_NONE: |
| 258 return true; | 257 return true; |
| 259 } | 258 } |
| 260 NOTREACHED(); | 259 NOTREACHED(); |
| 261 return true; | 260 return true; |
| 262 } | 261 } |
| 263 | 262 |
| 263 bool IsHangoutsExtensionId(const std::string& extension_id) { |
| 264 for (const char* id : extension_misc::kHangoutsExtensionIds) { |
| 265 if (extension_id == id) |
| 266 return true; |
| 267 } |
| 268 return false; |
| 269 } |
| 270 |
| 264 } // namespace | 271 } // namespace |
| 265 | 272 |
| 266 void ZoomModeToZoomSettings(ZoomController::ZoomMode zoom_mode, | 273 void ZoomModeToZoomSettings(ZoomController::ZoomMode zoom_mode, |
| 267 api::tabs::ZoomSettings* zoom_settings) { | 274 api::tabs::ZoomSettings* zoom_settings) { |
| 268 DCHECK(zoom_settings); | 275 DCHECK(zoom_settings); |
| 269 switch (zoom_mode) { | 276 switch (zoom_mode) { |
| 270 case ZoomController::ZOOM_MODE_DEFAULT: | 277 case ZoomController::ZOOM_MODE_DEFAULT: |
| 271 zoom_settings->mode = api::tabs::ZOOM_SETTINGS_MODE_AUTOMATIC; | 278 zoom_settings->mode = api::tabs::ZOOM_SETTINGS_MODE_AUTOMATIC; |
| 272 zoom_settings->scope = api::tabs::ZOOM_SETTINGS_SCOPE_PER_ORIGIN; | 279 zoom_settings->scope = api::tabs::ZOOM_SETTINGS_SCOPE_PER_ORIGIN; |
| 273 break; | 280 break; |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 return false; | 506 return false; |
| 500 } | 507 } |
| 501 } | 508 } |
| 502 | 509 |
| 503 if (!IsValidStateForWindowsCreateFunction(create_data)) { | 510 if (!IsValidStateForWindowsCreateFunction(create_data)) { |
| 504 error_ = keys::kInvalidWindowStateError; | 511 error_ = keys::kInvalidWindowStateError; |
| 505 return false; | 512 return false; |
| 506 } | 513 } |
| 507 | 514 |
| 508 Browser::Type window_type = Browser::TYPE_TABBED; | 515 Browser::Type window_type = Browser::TYPE_TABBED; |
| 509 bool create_panel = false; | |
| 510 | 516 |
| 511 // panel_create_mode only applies if create_panel = true | 517 #if defined(USE_ASH) |
| 512 PanelManager::CreateMode panel_create_mode = PanelManager::CREATE_AS_DOCKED; | 518 bool create_ash_panel = false; |
| 519 #endif // defined(USE_ASH) |
| 513 | 520 |
| 514 gfx::Rect window_bounds; | 521 gfx::Rect window_bounds; |
| 515 bool focused = true; | 522 bool focused = true; |
| 516 bool saw_focus_key = false; | 523 bool saw_focus_key = false; |
| 517 std::string extension_id; | 524 std::string extension_id; |
| 518 | 525 |
| 519 if (create_data) { | 526 if (create_data) { |
| 520 // Figure out window type before figuring out bounds so that default | 527 // Figure out window type before figuring out bounds so that default |
| 521 // bounds can be set according to the window type. | 528 // bounds can be set according to the window type. |
| 522 switch (create_data->type) { | 529 switch (create_data->type) { |
| 523 case windows::CREATE_TYPE_POPUP: | 530 case windows::CREATE_TYPE_POPUP: |
| 524 window_type = Browser::TYPE_POPUP; | 531 window_type = Browser::TYPE_POPUP; |
| 525 extension_id = extension()->id(); | 532 extension_id = extension()->id(); |
| 526 break; | 533 break; |
| 534 |
| 527 case windows::CREATE_TYPE_PANEL: | 535 case windows::CREATE_TYPE_PANEL: |
| 528 case windows::CREATE_TYPE_DETACHED_PANEL: { | 536 case windows::CREATE_TYPE_DETACHED_PANEL: { |
| 529 extension_id = extension()->id(); | 537 extension_id = extension()->id(); |
| 530 bool use_panels = PanelManager::ShouldUsePanels(extension_id); | 538 #if defined(USE_ASH) |
| 531 if (use_panels) { | 539 // Only ChromeOS' version of chrome.windows.create would create a panel |
| 532 create_panel = true; | 540 // window. It is whitelisted to Hangouts extension for limited time until |
| 533 #if !defined(USE_ASH) | 541 // it transitioned to other types of windows. |
| 534 // Non-ash supports both docked and detached panel types. | 542 if (IsHangoutsExtensionId(extension_id)) { |
| 535 if (create_data->type == windows::CREATE_TYPE_DETACHED_PANEL) { | 543 create_ash_panel = true; |
| 536 panel_create_mode = PanelManager::CREATE_AS_DETACHED; | 544 break; |
| 537 } | |
| 538 #endif // USE_ASH | |
| 539 } else { | |
| 540 window_type = Browser::TYPE_POPUP; | |
| 541 } | 545 } |
| 546 #endif // defined(USE_ASH) |
| 547 // Everything else gets POPUP instead of PANEL. |
| 548 // TODO(dimich): Eventually, remove the 'panel' values form valid |
| 549 // window.create parameters. However, this is a more breaking change, so |
| 550 // for now simply treat it as a POPUP. |
| 551 window_type = Browser::TYPE_POPUP; |
| 542 break; | 552 break; |
| 543 } | 553 } |
| 554 |
| 544 case windows::CREATE_TYPE_NONE: | 555 case windows::CREATE_TYPE_NONE: |
| 545 case windows::CREATE_TYPE_NORMAL: | 556 case windows::CREATE_TYPE_NORMAL: |
| 546 break; | 557 break; |
| 547 default: | 558 default: |
| 548 error_ = keys::kInvalidWindowTypeError; | 559 error_ = keys::kInvalidWindowTypeError; |
| 549 return false; | 560 return false; |
| 550 } | 561 } |
| 551 | 562 |
| 552 // Initialize default window bounds according to window type. | 563 // Initialize default window bounds according to window type. |
| 553 if (window_type == Browser::TYPE_TABBED || | 564 if (window_type == Browser::TYPE_TABBED || |
| 554 window_type == Browser::TYPE_POPUP || | 565 window_type == Browser::TYPE_POPUP) { |
| 555 create_panel) { | |
| 556 // Try to position the new browser relative to its originating | 566 // Try to position the new browser relative to its originating |
| 557 // browser window. The call offsets the bounds by kWindowTilePixels | 567 // browser window. The call offsets the bounds by kWindowTilePixels |
| 558 // (defined in WindowSizer to be 10). | 568 // (defined in WindowSizer to be 10). |
| 559 // | 569 // |
| 560 // NOTE(rafaelw): It's ok if GetCurrentBrowser() returns NULL here. | 570 // NOTE(rafaelw): It's ok if GetCurrentBrowser() returns NULL here. |
| 561 // GetBrowserWindowBounds will default to saved "default" values for | 571 // GetBrowserWindowBounds will default to saved "default" values for |
| 562 // the app. | 572 // the app. |
| 563 ui::WindowShowState show_state = ui::SHOW_STATE_DEFAULT; | 573 ui::WindowShowState show_state = ui::SHOW_STATE_DEFAULT; |
| 564 WindowSizer::GetBrowserWindowBoundsAndShowState(std::string(), | 574 WindowSizer::GetBrowserWindowBoundsAndShowState(std::string(), |
| 565 gfx::Rect(), | 575 gfx::Rect(), |
| 566 GetCurrentBrowser(), | 576 GetCurrentBrowser(), |
| 567 &window_bounds, | 577 &window_bounds, |
| 568 &show_state); | 578 &show_state); |
| 569 } | 579 } |
| 570 | 580 |
| 571 if (create_panel && PanelManager::CREATE_AS_DETACHED == panel_create_mode) { | |
| 572 window_bounds.set_origin( | |
| 573 PanelManager::GetInstance()->GetDefaultDetachedPanelOrigin()); | |
| 574 } | |
| 575 | |
| 576 // Any part of the bounds can optionally be set by the caller. | 581 // Any part of the bounds can optionally be set by the caller. |
| 577 if (create_data->left) | 582 if (create_data->left) |
| 578 window_bounds.set_x(*create_data->left); | 583 window_bounds.set_x(*create_data->left); |
| 579 | 584 |
| 580 if (create_data->top) | 585 if (create_data->top) |
| 581 window_bounds.set_y(*create_data->top); | 586 window_bounds.set_y(*create_data->top); |
| 582 | 587 |
| 583 if (create_data->width) | 588 if (create_data->width) |
| 584 window_bounds.set_width(*create_data->width); | 589 window_bounds.set_width(*create_data->width); |
| 585 | 590 |
| 586 if (create_data->height) | 591 if (create_data->height) |
| 587 window_bounds.set_height(*create_data->height); | 592 window_bounds.set_height(*create_data->height); |
| 588 | 593 |
| 589 if (create_data->focused) { | 594 if (create_data->focused) { |
| 590 focused = *create_data->focused; | 595 focused = *create_data->focused; |
| 591 saw_focus_key = true; | 596 saw_focus_key = true; |
| 592 } | 597 } |
| 593 } | 598 } |
| 594 | 599 |
| 595 if (create_panel) { | 600 #if defined(USE_ASH) |
| 601 if (create_ash_panel) { |
| 596 if (urls.empty()) | 602 if (urls.empty()) |
| 597 urls.push_back(GURL(chrome::kChromeUINewTabURL)); | 603 urls.push_back(GURL(chrome::kChromeUINewTabURL)); |
| 598 | 604 |
| 599 #if defined(USE_ASH) | |
| 600 AppWindow::CreateParams create_params; | 605 AppWindow::CreateParams create_params; |
| 601 create_params.window_type = AppWindow::WINDOW_TYPE_V1_PANEL; | 606 create_params.window_type = AppWindow::WINDOW_TYPE_V1_PANEL; |
| 602 create_params.window_key = extension_id; | 607 create_params.window_key = extension_id; |
| 603 create_params.window_spec.bounds = window_bounds; | 608 create_params.window_spec.bounds = window_bounds; |
| 604 create_params.focused = saw_focus_key && focused; | 609 create_params.focused = saw_focus_key && focused; |
| 605 AppWindow* app_window = | 610 AppWindow* app_window = |
| 606 new AppWindow(window_profile, new ChromeAppDelegate(true), extension()); | 611 new AppWindow(window_profile, new ChromeAppDelegate(true), extension()); |
| 607 AshPanelContents* ash_panel_contents = new AshPanelContents(app_window); | 612 AshPanelContents* ash_panel_contents = new AshPanelContents(app_window); |
| 608 app_window->Init(urls[0], ash_panel_contents, render_frame_host(), | 613 app_window->Init(urls[0], ash_panel_contents, render_frame_host(), |
| 609 create_params); | 614 create_params); |
| 610 WindowController* window_controller = | 615 WindowController* window_controller = |
| 611 WindowControllerList::GetInstance()->FindWindowById( | 616 WindowControllerList::GetInstance()->FindWindowById( |
| 612 app_window->session_id().id()); | 617 app_window->session_id().id()); |
| 613 if (!window_controller) | 618 if (!window_controller) |
| 614 return false; | 619 return false; |
| 615 SetResult(window_controller->CreateWindowValueWithTabs(extension())); | 620 SetResult(window_controller->CreateWindowValueWithTabs(extension())); |
| 616 return true; | 621 return true; |
| 617 #else | |
| 618 std::string title = | |
| 619 web_app::GenerateApplicationNameFromExtensionId(extension_id); | |
| 620 content::SiteInstance* source_site_instance = | |
| 621 render_frame_host()->GetSiteInstance(); | |
| 622 // Note: Panels ignore all but the first url provided. | |
| 623 Panel* panel = PanelManager::GetInstance()->CreatePanel( | |
| 624 title, window_profile, urls[0], source_site_instance, window_bounds, | |
| 625 panel_create_mode); | |
| 626 | |
| 627 // Unlike other window types, Panels do not take focus by default. | |
| 628 if (!saw_focus_key || !focused) | |
| 629 panel->ShowInactive(); | |
| 630 else | |
| 631 panel->Show(); | |
| 632 | |
| 633 SetResult(panel->extension_window_controller()->CreateWindowValueWithTabs( | |
| 634 extension())); | |
| 635 return true; | |
| 636 #endif | |
| 637 } | 622 } |
| 623 #endif // defined(USE_ASH) |
| 638 | 624 |
| 639 // Create a new BrowserWindow. | 625 // Create a new BrowserWindow. |
| 640 if (create_panel) | |
| 641 window_type = Browser::TYPE_POPUP; | |
| 642 Browser::CreateParams create_params(window_type, window_profile); | 626 Browser::CreateParams create_params(window_type, window_profile); |
| 643 if (extension_id.empty()) { | 627 if (extension_id.empty()) { |
| 644 create_params.initial_bounds = window_bounds; | 628 create_params.initial_bounds = window_bounds; |
| 645 } else { | 629 } else { |
| 646 create_params = Browser::CreateParams::CreateForApp( | 630 create_params = Browser::CreateParams::CreateForApp( |
| 647 web_app::GenerateApplicationNameFromExtensionId(extension_id), | 631 web_app::GenerateApplicationNameFromExtensionId(extension_id), |
| 648 false /* trusted_source */, window_bounds, window_profile); | 632 false /* trusted_source */, window_bounds, window_profile); |
| 649 } | 633 } |
| 650 create_params.initial_show_state = ui::SHOW_STATE_NORMAL; | 634 create_params.initial_show_state = ui::SHOW_STATE_NORMAL; |
| 651 if (create_data && create_data->state) { | 635 if (create_data && create_data->state) { |
| 652 create_params.initial_show_state = | 636 create_params.initial_show_state = |
| 653 ConvertToWindowShowState(create_data->state); | 637 ConvertToWindowShowState(create_data->state); |
| 654 } | 638 } |
| 655 | 639 |
| 656 Browser* new_window = new Browser(create_params); | 640 Browser* new_window = new Browser(create_params); |
| 657 | 641 |
| 658 for (const GURL& url : urls) { | 642 for (const GURL& url : urls) { |
| 659 chrome::NavigateParams navigate_params(new_window, url, | 643 chrome::NavigateParams navigate_params(new_window, url, |
| 660 ui::PAGE_TRANSITION_LINK); | 644 ui::PAGE_TRANSITION_LINK); |
| 661 navigate_params.disposition = NEW_FOREGROUND_TAB; | 645 navigate_params.disposition = NEW_FOREGROUND_TAB; |
| 662 navigate_params.source_site_instance = | 646 navigate_params.source_site_instance = |
| 663 render_frame_host()->GetSiteInstance(); | 647 render_frame_host()->GetSiteInstance(); |
| 664 chrome::Navigate(&navigate_params); | 648 chrome::Navigate(&navigate_params); |
| 665 if (create_panel) { | |
| 666 TabHelper::FromWebContents(navigate_params.target_contents) | |
| 667 ->SetExtensionAppIconById(extension_id); | |
| 668 } | |
| 669 } | 649 } |
| 670 | 650 |
| 671 WebContents* contents = NULL; | 651 WebContents* contents = NULL; |
| 672 // Move the tab into the created window only if it's an empty popup or it's | 652 // Move the tab into the created window only if it's an empty popup or it's |
| 673 // a tabbed window. | 653 // a tabbed window. |
| 674 if ((window_type == Browser::TYPE_POPUP && urls.empty()) || | 654 if ((window_type == Browser::TYPE_POPUP && urls.empty()) || |
| 675 window_type == Browser::TYPE_TABBED) { | 655 window_type == Browser::TYPE_TABBED) { |
| 676 if (source_tab_strip) | 656 if (source_tab_strip) |
| 677 contents = source_tab_strip->DetachWebContentsAt(tab_index); | 657 contents = source_tab_strip->DetachWebContentsAt(tab_index); |
| 678 if (contents) { | 658 if (contents) { |
| 679 TabStripModel* target_tab_strip = new_window->tab_strip_model(); | 659 TabStripModel* target_tab_strip = new_window->tab_strip_model(); |
| 680 target_tab_strip->InsertWebContentsAt(urls.size(), contents, | 660 target_tab_strip->InsertWebContentsAt(urls.size(), contents, |
| 681 TabStripModel::ADD_NONE); | 661 TabStripModel::ADD_NONE); |
| 682 } | 662 } |
| 683 } | 663 } |
| 684 // Create a new tab if the created window is still empty. Don't create a new | 664 // Create a new tab if the created window is still empty. Don't create a new |
| 685 // tab when it is intended to create an empty popup. | 665 // tab when it is intended to create an empty popup. |
| 686 if (!contents && urls.empty() && window_type != Browser::TYPE_POPUP) { | 666 if (!contents && urls.empty() && window_type != Browser::TYPE_POPUP) { |
| 687 chrome::NewTab(new_window); | 667 chrome::NewTab(new_window); |
| 688 } | 668 } |
| 689 chrome::SelectNumberedTab(new_window, 0); | 669 chrome::SelectNumberedTab(new_window, 0); |
| 690 | 670 |
| 691 // Unlike other window types, Panels do not take focus by default. | |
| 692 if (!saw_focus_key && create_panel) | |
| 693 focused = false; | |
| 694 | |
| 695 if (focused) | 671 if (focused) |
| 696 new_window->window()->Show(); | 672 new_window->window()->Show(); |
| 697 else | 673 else |
| 698 new_window->window()->ShowInactive(); | 674 new_window->window()->ShowInactive(); |
| 699 | 675 |
| 700 WindowController* controller = new_window->extension_window_controller(); | 676 WindowController* controller = new_window->extension_window_controller(); |
| 701 | 677 |
| 702 if (new_window->profile()->IsOffTheRecord() && | 678 if (new_window->profile()->IsOffTheRecord() && |
| 703 !GetProfile()->IsOffTheRecord() && !include_incognito()) { | 679 !GetProfile()->IsOffTheRecord() && !include_incognito()) { |
| 704 // Don't expose incognito windows if extension itself works in non-incognito | 680 // Don't expose incognito windows if extension itself works in non-incognito |
| (...skipping 1506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2211 params->tab_id | 2187 params->tab_id |
| 2212 ? ErrorUtils::FormatErrorMessage(keys::kCannotDiscardTab, | 2188 ? ErrorUtils::FormatErrorMessage(keys::kCannotDiscardTab, |
| 2213 base::IntToString(*params->tab_id)) | 2189 base::IntToString(*params->tab_id)) |
| 2214 : keys::kCannotFindTabToDiscard)); | 2190 : keys::kCannotFindTabToDiscard)); |
| 2215 } | 2191 } |
| 2216 | 2192 |
| 2217 TabsDiscardFunction::TabsDiscardFunction() {} | 2193 TabsDiscardFunction::TabsDiscardFunction() {} |
| 2218 TabsDiscardFunction::~TabsDiscardFunction() {} | 2194 TabsDiscardFunction::~TabsDiscardFunction() {} |
| 2219 | 2195 |
| 2220 } // namespace extensions | 2196 } // namespace extensions |
| OLD | NEW |