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