| 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/ui/browser.h" | 5 #include "chrome/browser/ui/browser.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <windows.h> | 8 #include <windows.h> |
| 9 #include <shellapi.h> | 9 #include <shellapi.h> |
| 10 #endif // OS_WIN | 10 #endif // OS_WIN |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 return true; | 253 return true; |
| 254 | 254 |
| 255 // If the |virtual_url()| isn't a chrome:// URL, check if it's actually | 255 // If the |virtual_url()| isn't a chrome:// URL, check if it's actually |
| 256 // view-source: of a chrome:// URL. | 256 // view-source: of a chrome:// URL. |
| 257 if (entry->GetVirtualURL().SchemeIs(chrome::kViewSourceScheme)) | 257 if (entry->GetVirtualURL().SchemeIs(chrome::kViewSourceScheme)) |
| 258 return entry->GetURL().SchemeIs(chrome::kChromeUIScheme); | 258 return entry->GetURL().SchemeIs(chrome::kChromeUIScheme); |
| 259 | 259 |
| 260 return false; | 260 return false; |
| 261 } | 261 } |
| 262 | 262 |
| 263 // Get the launch URL for a given extension, with optional override/fallback. | |
| 264 // |override_url|, if non-empty, will be preferred over the extension's | |
| 265 // launch url. | |
| 266 GURL UrlForExtension(const Extension* extension, const GURL& override_url) { | |
| 267 if (!extension) | |
| 268 return override_url; | |
| 269 | |
| 270 GURL url; | |
| 271 if (!override_url.is_empty()) { | |
| 272 DCHECK(extension->web_extent().MatchesURL(override_url)); | |
| 273 url = override_url; | |
| 274 } else { | |
| 275 url = extension->GetFullLaunchURL(); | |
| 276 } | |
| 277 | |
| 278 // For extensions lacking launch urls, determine a reasonable fallback. | |
| 279 if (!url.is_valid()) { | |
| 280 url = extension->options_url(); | |
| 281 if (!url.is_valid()) | |
| 282 url = GURL(chrome::kChromeUIExtensionsURL); | |
| 283 } | |
| 284 | |
| 285 return url; | |
| 286 } | |
| 287 | |
| 288 // Parse two comma-separated integers from str. Return true on success. | 263 // Parse two comma-separated integers from str. Return true on success. |
| 289 bool ParseCommaSeparatedIntegers(const std::string& str, | 264 bool ParseCommaSeparatedIntegers(const std::string& str, |
| 290 int* ret_num1, | 265 int* ret_num1, |
| 291 int* ret_num2) { | 266 int* ret_num2) { |
| 292 size_t num1_size = str.find_first_of(','); | 267 size_t num1_size = str.find_first_of(','); |
| 293 if (num1_size == std::string::npos) | 268 if (num1_size == std::string::npos) |
| 294 return false; | 269 return false; |
| 295 | 270 |
| 296 size_t num2_pos = num1_size + 1; | 271 size_t num2_pos = num1_size + 1; |
| 297 size_t num2_size = str.size() - num2_pos; | 272 size_t num2_size = str.size() - num2_pos; |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 681 | 656 |
| 682 // static | 657 // static |
| 683 void Browser::OpenURLOffTheRecord(Profile* profile, const GURL& url) { | 658 void Browser::OpenURLOffTheRecord(Profile* profile, const GURL& url) { |
| 684 Browser* browser = browser::FindOrCreateTabbedBrowser( | 659 Browser* browser = browser::FindOrCreateTabbedBrowser( |
| 685 profile->GetOffTheRecordProfile()); | 660 profile->GetOffTheRecordProfile()); |
| 686 browser->AddSelectedTabWithURL(url, content::PAGE_TRANSITION_LINK); | 661 browser->AddSelectedTabWithURL(url, content::PAGE_TRANSITION_LINK); |
| 687 browser->window()->Show(); | 662 browser->window()->Show(); |
| 688 } | 663 } |
| 689 | 664 |
| 690 // static | 665 // static |
| 691 WebContents* Browser::OpenApplication( | |
| 692 Profile* profile, | |
| 693 const Extension* extension, | |
| 694 extension_misc::LaunchContainer container, | |
| 695 const GURL& override_url, | |
| 696 WindowOpenDisposition disposition) { | |
| 697 WebContents* tab = NULL; | |
| 698 ExtensionPrefs* prefs = profile->GetExtensionService()->extension_prefs(); | |
| 699 prefs->SetActiveBit(extension->id(), true); | |
| 700 | |
| 701 UMA_HISTOGRAM_ENUMERATION("Extensions.AppLaunchContainer", container, 100); | |
| 702 | |
| 703 if (extension->is_platform_app()) { | |
| 704 extensions::AppEventRouter::DispatchOnLaunchedEvent(profile, extension); | |
| 705 return NULL; | |
| 706 } | |
| 707 | |
| 708 switch (container) { | |
| 709 case extension_misc::LAUNCH_NONE: { | |
| 710 NOTREACHED(); | |
| 711 break; | |
| 712 } | |
| 713 case extension_misc::LAUNCH_PANEL: | |
| 714 #if defined(USE_ASH) | |
| 715 if (extension && | |
| 716 CommandLine::ForCurrentProcess()->HasSwitch( | |
| 717 ash::switches::kAuraPanelManager)) { | |
| 718 tab = OpenApplicationPanel(profile, extension, override_url); | |
| 719 break; | |
| 720 } | |
| 721 // else fall through to LAUNCH_WINDOW | |
| 722 #endif | |
| 723 case extension_misc::LAUNCH_WINDOW: | |
| 724 tab = Browser::OpenApplicationWindow(profile, extension, container, | |
| 725 override_url, NULL); | |
| 726 break; | |
| 727 case extension_misc::LAUNCH_TAB: { | |
| 728 tab = Browser::OpenApplicationTab(profile, extension, override_url, | |
| 729 disposition); | |
| 730 break; | |
| 731 } | |
| 732 default: | |
| 733 NOTREACHED(); | |
| 734 break; | |
| 735 } | |
| 736 return tab; | |
| 737 } | |
| 738 | |
| 739 #if defined(USE_ASH) | |
| 740 // static | |
| 741 WebContents* Browser::OpenApplicationPanel( | |
| 742 Profile* profile, | |
| 743 const Extension* extension, | |
| 744 const GURL& url_input) { | |
| 745 GURL url = UrlForExtension(extension, url_input); | |
| 746 std::string app_name = | |
| 747 web_app::GenerateApplicationNameFromExtensionId(extension->id()); | |
| 748 gfx::Rect panel_bounds; | |
| 749 panel_bounds.set_width(extension->launch_width()); | |
| 750 panel_bounds.set_height(extension->launch_height()); | |
| 751 PanelViewAura* panel_view = new PanelViewAura(app_name); | |
| 752 panel_view->Init(profile, url, panel_bounds); | |
| 753 return panel_view->WebContents(); | |
| 754 } | |
| 755 #endif | |
| 756 | |
| 757 // static | |
| 758 WebContents* Browser::OpenApplicationWindow( | |
| 759 Profile* profile, | |
| 760 const Extension* extension, | |
| 761 extension_misc::LaunchContainer container, | |
| 762 const GURL& url_input, | |
| 763 Browser** app_browser) { | |
| 764 DCHECK(!url_input.is_empty() || extension); | |
| 765 GURL url = UrlForExtension(extension, url_input); | |
| 766 | |
| 767 std::string app_name; | |
| 768 app_name = extension ? | |
| 769 web_app::GenerateApplicationNameFromExtensionId(extension->id()) : | |
| 770 web_app::GenerateApplicationNameFromURL(url); | |
| 771 | |
| 772 Type type = TYPE_POPUP; | |
| 773 if (extension && | |
| 774 container == extension_misc::LAUNCH_PANEL && | |
| 775 AllowPanels(app_name)) { | |
| 776 type = TYPE_PANEL; | |
| 777 } | |
| 778 | |
| 779 gfx::Rect window_bounds; | |
| 780 if (extension) { | |
| 781 window_bounds.set_width(extension->launch_width()); | |
| 782 window_bounds.set_height(extension->launch_height()); | |
| 783 } | |
| 784 | |
| 785 CreateParams params(type, profile); | |
| 786 params.app_name = app_name; | |
| 787 params.initial_bounds = window_bounds; | |
| 788 | |
| 789 #if defined(USE_ASH) | |
| 790 if (extension && | |
| 791 container == extension_misc::LAUNCH_WINDOW) { | |
| 792 // In ash, LAUNCH_FULLSCREEN launches in a maximized app window and | |
| 793 // LAUNCH_WINDOW launches in a normal app window. | |
| 794 ExtensionPrefs::LaunchType launch_type = | |
| 795 profile->GetExtensionService()->extension_prefs()->GetLaunchType( | |
| 796 extension->id(), ExtensionPrefs::LAUNCH_DEFAULT); | |
| 797 if (launch_type == ExtensionPrefs::LAUNCH_FULLSCREEN) | |
| 798 params.initial_show_state = ui::SHOW_STATE_MAXIMIZED; | |
| 799 else if (launch_type == ExtensionPrefs::LAUNCH_WINDOW) | |
| 800 params.initial_show_state = ui::SHOW_STATE_NORMAL; | |
| 801 } | |
| 802 #endif | |
| 803 | |
| 804 Browser* browser = Browser::CreateWithParams(params); | |
| 805 | |
| 806 if (app_browser) | |
| 807 *app_browser = browser; | |
| 808 | |
| 809 TabContentsWrapper* wrapper = | |
| 810 browser->AddSelectedTabWithURL(url, content::PAGE_TRANSITION_START_PAGE); | |
| 811 WebContents* contents = wrapper->web_contents(); | |
| 812 contents->GetMutableRendererPrefs()->can_accept_load_drops = false; | |
| 813 contents->GetRenderViewHost()->SyncRendererPrefs(); | |
| 814 // TODO(stevenjb): Find the right centralized place to do this. Currently it | |
| 815 // is only done for app tabs in normal browsers through SetExtensionAppById. | |
| 816 if (extension && type == TYPE_PANEL) | |
| 817 wrapper->extension_tab_helper()->SetExtensionAppIconById(extension->id()); | |
| 818 | |
| 819 browser->window()->Show(); | |
| 820 | |
| 821 // TODO(jcampan): http://crbug.com/8123 we should not need to set the initial | |
| 822 // focus explicitly. | |
| 823 contents->GetView()->SetInitialFocus(); | |
| 824 return contents; | |
| 825 } | |
| 826 | |
| 827 WebContents* Browser::OpenAppShortcutWindow(Profile* profile, | |
| 828 const GURL& url, | |
| 829 bool update_shortcut) { | |
| 830 Browser* app_browser; | |
| 831 WebContents* tab = OpenApplicationWindow( | |
| 832 profile, | |
| 833 NULL, // this is a URL app. No extension. | |
| 834 extension_misc::LAUNCH_WINDOW, | |
| 835 url, | |
| 836 &app_browser); | |
| 837 | |
| 838 if (!tab) | |
| 839 return NULL; | |
| 840 | |
| 841 if (update_shortcut) { | |
| 842 // Set UPDATE_SHORTCUT as the pending web app action. This action is picked | |
| 843 // up in LoadingStateChanged to schedule a GetApplicationInfo. And when | |
| 844 // the web app info is available, ExtensionTabHelper notifies Browser via | |
| 845 // OnDidGetApplicationInfo, which calls | |
| 846 // web_app::UpdateShortcutForTabContents when it sees UPDATE_SHORTCUT as | |
| 847 // pending web app action. | |
| 848 app_browser->pending_web_app_action_ = UPDATE_SHORTCUT; | |
| 849 } | |
| 850 return tab; | |
| 851 } | |
| 852 | |
| 853 // static | |
| 854 WebContents* Browser::OpenApplicationTab(Profile* profile, | |
| 855 const Extension* extension, | |
| 856 const GURL& override_url, | |
| 857 WindowOpenDisposition disposition) { | |
| 858 Browser* browser = browser::FindTabbedBrowser(profile, false); | |
| 859 WebContents* contents = NULL; | |
| 860 if (!browser) { | |
| 861 // No browser for this profile, need to open a new one. | |
| 862 browser = Browser::Create(profile); | |
| 863 browser->window()->Show(); | |
| 864 // There's no current tab in this browser window, so add a new one. | |
| 865 disposition = NEW_FOREGROUND_TAB; | |
| 866 } else { | |
| 867 // For existing browser, ensure its window is activated. | |
| 868 browser->window()->Activate(); | |
| 869 } | |
| 870 | |
| 871 // Check the prefs for overridden mode. | |
| 872 ExtensionService* extension_service = profile->GetExtensionService(); | |
| 873 DCHECK(extension_service); | |
| 874 | |
| 875 ExtensionPrefs::LaunchType launch_type = | |
| 876 extension_service->extension_prefs()->GetLaunchType( | |
| 877 extension->id(), ExtensionPrefs::LAUNCH_DEFAULT); | |
| 878 UMA_HISTOGRAM_ENUMERATION("Extensions.AppTabLaunchType", launch_type, 100); | |
| 879 | |
| 880 static bool default_apps_trial_exists = | |
| 881 base::FieldTrialList::TrialExists(kDefaultAppsTrialName); | |
| 882 if (default_apps_trial_exists) { | |
| 883 UMA_HISTOGRAM_ENUMERATION( | |
| 884 base::FieldTrial::MakeName("Extensions.AppTabLaunchType", | |
| 885 kDefaultAppsTrialName), | |
| 886 launch_type, 100); | |
| 887 } | |
| 888 | |
| 889 int add_type = TabStripModel::ADD_ACTIVE; | |
| 890 if (launch_type == ExtensionPrefs::LAUNCH_PINNED) | |
| 891 add_type |= TabStripModel::ADD_PINNED; | |
| 892 | |
| 893 GURL extension_url = UrlForExtension(extension, override_url); | |
| 894 // TODO(erikkay): START_PAGE doesn't seem like the right transition in all | |
| 895 // cases. | |
| 896 browser::NavigateParams params(browser, extension_url, | |
| 897 content::PAGE_TRANSITION_START_PAGE); | |
| 898 params.tabstrip_add_types = add_type; | |
| 899 params.disposition = disposition; | |
| 900 | |
| 901 if (disposition == CURRENT_TAB) { | |
| 902 WebContents* existing_tab = browser->GetSelectedWebContents(); | |
| 903 TabStripModel* model = browser->tab_strip_model(); | |
| 904 int tab_index = model->GetWrapperIndex(existing_tab); | |
| 905 | |
| 906 existing_tab->OpenURL(OpenURLParams( | |
| 907 extension_url, | |
| 908 content::Referrer(existing_tab->GetURL(), | |
| 909 WebKit::WebReferrerPolicyDefault), | |
| 910 disposition, content::PAGE_TRANSITION_LINK, false)); | |
| 911 // Reset existing_tab as OpenURL() may have clobbered it. | |
| 912 existing_tab = browser->GetSelectedWebContents(); | |
| 913 if (params.tabstrip_add_types & TabStripModel::ADD_PINNED) { | |
| 914 model->SetTabPinned(tab_index, true); | |
| 915 // Pinning may have moved the tab. | |
| 916 tab_index = model->GetWrapperIndex(existing_tab); | |
| 917 } | |
| 918 if (params.tabstrip_add_types & TabStripModel::ADD_ACTIVE) | |
| 919 model->ActivateTabAt(tab_index, true); | |
| 920 | |
| 921 contents = existing_tab; | |
| 922 } else { | |
| 923 browser::Navigate(¶ms); | |
| 924 contents = params.target_contents->web_contents(); | |
| 925 } | |
| 926 | |
| 927 #if defined(USE_ASH) | |
| 928 // In ash, LAUNCH_FULLSCREEN launches in a maximized app window and it should | |
| 929 // not reach here. | |
| 930 DCHECK(launch_type != ExtensionPrefs::LAUNCH_FULLSCREEN); | |
| 931 #else | |
| 932 // TODO(skerner): If we are already in full screen mode, and the user | |
| 933 // set the app to open as a regular or pinned tab, what should happen? | |
| 934 // Today we open the tab, but stay in full screen mode. Should we leave | |
| 935 // full screen mode in this case? | |
| 936 if (launch_type == ExtensionPrefs::LAUNCH_FULLSCREEN && | |
| 937 !browser->window()->IsFullscreen()) { | |
| 938 browser->ToggleFullscreenMode(); | |
| 939 } | |
| 940 #endif | |
| 941 | |
| 942 return contents; | |
| 943 } | |
| 944 | |
| 945 // static | |
| 946 void Browser::OpenBookmarkManagerWindow(Profile* profile) { | 666 void Browser::OpenBookmarkManagerWindow(Profile* profile) { |
| 947 Browser* browser = Browser::Create(profile); | 667 Browser* browser = Browser::Create(profile); |
| 948 browser->OpenBookmarkManager(); | 668 browser->OpenBookmarkManager(); |
| 949 browser->window()->Show(); | 669 browser->window()->Show(); |
| 950 } | 670 } |
| 951 | 671 |
| 952 #if defined(OS_MACOSX) | 672 #if defined(OS_MACOSX) |
| 953 // static | 673 // static |
| 954 void Browser::OpenAboutWindow(Profile* profile) { | 674 void Browser::OpenAboutWindow(Profile* profile) { |
| 955 Browser* browser = Browser::Create(profile); | 675 Browser* browser = Browser::Create(profile); |
| (...skipping 4467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5423 if (contents && !allow_js_access) { | 5143 if (contents && !allow_js_access) { |
| 5424 contents->web_contents()->GetController().LoadURL( | 5144 contents->web_contents()->GetController().LoadURL( |
| 5425 target_url, | 5145 target_url, |
| 5426 content::Referrer(), | 5146 content::Referrer(), |
| 5427 content::PAGE_TRANSITION_LINK, | 5147 content::PAGE_TRANSITION_LINK, |
| 5428 std::string()); // No extra headers. | 5148 std::string()); // No extra headers. |
| 5429 } | 5149 } |
| 5430 | 5150 |
| 5431 return contents != NULL; | 5151 return contents != NULL; |
| 5432 } | 5152 } |
| OLD | NEW |