extension_tab_util.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_tab_util.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "apps/app_window.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "apps/app_window_registry.h" 9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/tabs/tabs_constants.h" 11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/extensions/chrome_extension_function.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/tab_helper.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/window_controller.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/window_controller_list.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/sessions/session_tab_helper.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_iterator.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/common/extensions/api/tabs.h" 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/extensions/manifest_url_handler.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/url_fixer/url_fixer.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/favicon_status.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/common/constants.h" 32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/common/error_utils.h" 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "extensions/common/manifest_constants.h" 35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/common/manifest_handlers/incognito_info.h" 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "extensions/common/permissions/api_permission.h" 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h" 387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using apps::AppWindow; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationEntry; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace extensions { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace keys = tabs_constants; 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)WindowController* GetAppWindowController(const WebContents* contents) { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) apps::AppWindowRegistry* registry = apps::AppWindowRegistry::Get(profile); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!registry) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppWindow* app_window = 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry->GetAppWindowForRenderViewHost(contents->GetRenderViewHost()); 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!app_window) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return WindowControllerList::GetInstance()->FindWindowById( 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_window->session_id().id()); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// |error_message| can optionally be passed in and will be set with an 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// appropriate message if the window cannot be found by id. 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)Browser* GetBrowserInProfileWithId(Profile* profile, 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const int window_id, 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool include_incognito, 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string* error_message) { 69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Profile* incognito_profile = 70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) include_incognito && profile->HasOffTheRecordProfile() 71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ? profile->GetOffTheRecordProfile() 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : NULL; 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser* browser = *it; 75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if ((browser->profile() == profile || 76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->profile() == incognito_profile) && 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ExtensionTabUtil::GetWindowId(browser) == window_id && 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->window()) { 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return browser; 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (error_message) 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *error_message = ErrorUtils::FormatErrorMessage( 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keys::kWindowNotFoundError, base::IntToString(window_id)); 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)Browser* CreateBrowser(ChromeUIThreadExtensionFunction* function, 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int window_id, 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string* error) { 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::WebContents* web_contents = function->GetAssociatedWebContents(); 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(web_contents); 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(web_contents->GetNativeView()); 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(!chrome::FindBrowserWithWebContents(web_contents)); 97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::HostDesktopType desktop_type = 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::GetHostDesktopTypeForNativeView(web_contents->GetNativeView()); 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser::CreateParams params( 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser::TYPE_TABBED, function->GetProfile(), desktop_type); 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser* browser = new Browser(params); 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->window()->Show(); 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return browser; 105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ExtensionTabUtil::OpenTabParams::OpenTabParams() 110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : create_browser_if_needed(false) { 111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ExtensionTabUtil::OpenTabParams::~OpenTabParams() { 114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Opens a new tab for a given extension. Returns NULL and sets |error| if an 117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// error occurs. 118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::DictionaryValue* ExtensionTabUtil::OpenTab( 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ChromeUIThreadExtensionFunction* function, 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const OpenTabParams& params, 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string* error) { 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // windowId defaults to "current" window. 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int window_id = extension_misc::kCurrentWindowId; 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.window_id.get()) 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_id = *params.window_id; 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser* browser = GetBrowserFromWindowID(function, window_id, error); 128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!browser) { 129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!params.create_browser_if_needed) { 130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser = CreateBrowser(function, window_id, error); 133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!browser) 134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Ensure the selected browser is tabbed. 138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!browser->is_type_tabbed() && browser->IsAttemptingToCloseBrowser()) 139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser = chrome::FindTabbedBrowser(function->GetProfile(), 140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->include_incognito(), 141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->host_desktop_type()); 142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!browser || !browser->window()) { 144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(rpaquay): Error message? 145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(jstritar): Add a constant, chrome.tabs.TAB_ID_ACTIVE, that 149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // represents the active tab. 150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WebContents* opener = NULL; 151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.opener_tab_id.get()) { 152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int opener_id = *params.opener_tab_id; 153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!ExtensionTabUtil::GetTabById(opener_id, 155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->GetProfile(), 156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->include_incognito(), 157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NULL, 158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NULL, 159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &opener, 160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NULL)) { 161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(rpaquay): Error message? 162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(rafaelw): handle setting remaining tab properties: 167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // -title 168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // -favIconUrl 169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GURL url; 171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.url.get()) { 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string url_string= *params.url; 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) url = ExtensionTabUtil::ResolvePossiblyRelativeURL(url_string, 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) function->extension()); 175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!url.is_valid()) { 176010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *error = 177010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, url_string); 178010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 179010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) url = GURL(chrome::kChromeUINewTabURL); 182010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 183010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 184010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Don't let extensions crash the browser or renderers. 185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (ExtensionTabUtil::IsCrashURL(url)) { 186010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *error = keys::kNoCrashBrowserError; 187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 189010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Default to foreground for the new tab. The presence of 'active' property 191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // will override this default. 192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool active = true; 193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.active.get()) 194010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) active = *params.active; 195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 196010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Default to not pinning the tab. Setting the 'pinned' property to true 197010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // will override this default. 198010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool pinned = false; 199010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.pinned.get()) 200010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pinned = *params.pinned; 201010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // We can't load extension URLs into incognito windows unless the extension 203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // uses split mode. Special case to fall back to a tabbed window. 204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (url.SchemeIs(kExtensionScheme) && 2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) !IncognitoInfo::IsSplitMode(function->extension()) && 206010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->profile()->IsOffTheRecord()) { 207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Profile* profile = browser->profile()->GetOriginalProfile(); 208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::HostDesktopType desktop_type = browser->host_desktop_type(); 209010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 210010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser = chrome::FindTabbedBrowser(profile, false, desktop_type); 211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!browser) { 212010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser = new Browser( 213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser::CreateParams(Browser::TYPE_TABBED, profile, desktop_type)); 214010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->window()->Show(); 215010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 216010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 217010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 218010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If index is specified, honor the value, but keep it bound to 219010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // -1 <= index <= tab_strip->count() where -1 invokes the default behavior. 220010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int index = -1; 221010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.index.get()) 222010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) index = *params.index; 223010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 224010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 226010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) index = std::min(std::max(index, -1), tab_strip->count()); 227010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int add_types = active ? TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE; 229010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) add_types |= TabStripModel::ADD_FORCE_INDEX; 230010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (pinned) 231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) add_types |= TabStripModel::ADD_PINNED; 232010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::NavigateParams navigate_params( 233010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser, url, content::PAGE_TRANSITION_LINK); 234010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigate_params.disposition = 235010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) active ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; 236010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigate_params.tabstrip_index = index; 237010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigate_params.tabstrip_add_types = add_types; 238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::Navigate(&navigate_params); 239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The tab may have been created in a different window, so make sure we look 241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // at the right tab strip. 242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tab_strip = navigate_params.browser->tab_strip_model(); 243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int new_index = 244010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tab_strip->GetIndexOfWebContents(navigate_params.target_contents); 245010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (opener) 246010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tab_strip->SetOpenerOfWebContentsAt(new_index, opener); 247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (active) 249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigate_params.target_contents->SetInitialFocus(); 250010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 251010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Return data about the newly created tab. 252010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return ExtensionTabUtil::CreateTabValue(navigate_params.target_contents, 253010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tab_strip, 254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new_index, 2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) function->extension()); 256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 258010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)Browser* ExtensionTabUtil::GetBrowserFromWindowID( 259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ChromeUIThreadExtensionFunction* function, 260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int window_id, 261010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string* error) { 262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (window_id == extension_misc::kCurrentWindowId) { 263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser* result = function->GetCurrentBrowser(); 264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!result || !result->window()) { 265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (error) 266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *error = keys::kNoCurrentWindowError; 267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return result; 270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return GetBrowserInProfileWithId(function->GetProfile(), 272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_id, 273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->include_incognito(), 274010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) error); 275010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 276010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 277010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionTabUtil::GetWindowId(const Browser* browser) { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser->session_id().id(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionTabUtil::GetWindowIdOfTabStripModel( 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TabStripModel* tab_strip_model) { 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it->tab_strip_model() == tab_strip_model) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetWindowId(*it); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int ExtensionTabUtil::GetTabId(const WebContents* web_contents) { 29203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return SessionTabHelper::IdForTab(web_contents); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ExtensionTabUtil::GetTabStatusText(bool is_loading) { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return is_loading ? keys::kStatusValueLoading : keys::kStatusValueComplete; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionTabUtil::GetWindowIdOfTab(const WebContents* web_contents) { 30003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return SessionTabHelper::IdForWindowContainingTab(web_contents); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::DictionaryValue* ExtensionTabUtil::CreateTabValue( 304010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WebContents* contents, 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* tab_strip, 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tab_index, 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we have a matching AppWindow with a controller, get the tab value 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // from its controller instead. 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WindowController* controller = GetAppWindowController(contents); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (controller && 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (!extension || controller->IsVisibleToExtension(extension))) { 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return controller->CreateTabValue(extension, tab_index); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* result = 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateTabValue(contents, tab_strip, tab_index); 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScrubTabValueForExtension(contents, extension, result); 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::ListValue* ExtensionTabUtil::CreateTabList( 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Browser* browser, 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ListValue* tab_list = new base::ListValue(); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < tab_strip->count(); ++i) { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_list->Append(CreateTabValue(tab_strip->GetWebContentsAt(i), 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip, 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i, 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension)); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return tab_list; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::DictionaryValue* ExtensionTabUtil::CreateTabValue( 337010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WebContents* contents, 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* tab_strip, 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int tab_index) { 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we have a matching AppWindow with a controller, get the tab value 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // from its controller instead. 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WindowController* controller = GetAppWindowController(contents); 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (controller) 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return controller->CreateTabValue(NULL, tab_index); 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tab_strip) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionTabUtil::GetTabStripModel(contents, &tab_strip, &tab_index); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* result = new base::DictionaryValue(); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_loading = contents->IsLoading(); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kIdKey, GetTabId(contents)); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kIndexKey, tab_index); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kWindowIdKey, GetWindowIdOfTab(contents)); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetString(keys::kStatusKey, GetTabStatusText(is_loading)); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kActiveKey, 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_index == tab_strip->active_index()); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kSelectedKey, 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_index == tab_strip->active_index()); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kHighlightedKey, 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_strip->IsTabSelected(tab_index)); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kPinnedKey, 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_strip->IsTabPinned(tab_index)); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kIncognitoKey, 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents->GetBrowserContext()->IsOffTheRecord()); 3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) result->SetInteger(keys::kWidthKey, 366010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) contents->GetContainerBounds().size().width()); 3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) result->SetInteger(keys::kHeightKey, 368010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) contents->GetContainerBounds().size().height()); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Privacy-sensitive fields: these should be stripped off by 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ScrubTabValueForExtension if the extension should not see them. 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kUrlKey, contents->GetURL().spec()); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kTitleKey, contents->GetTitle()); 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_loading) { 3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NavigationEntry* entry = contents->GetController().GetVisibleEntry(); 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry && entry->GetFavicon().valid) 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kFaviconUrlKey, entry->GetFavicon().url.spec()); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_strip) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* opener = tab_strip->GetOpenerOfWebContentsAt(tab_index); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (opener) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kOpenerTabIdKey, GetTabId(opener)); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionTabUtil::ScrubTabValueForExtension( 390010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WebContents* contents, 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const Extension* extension, 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* tab_info) { 39346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool has_permission = extension && 39446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension->permissions_data()->HasAPIPermissionForTab( 39546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GetTabId(contents), APIPermission::kTab); 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!has_permission) { 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_info->Remove(keys::kUrlKey, NULL); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_info->Remove(keys::kTitleKey, NULL); 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_info->Remove(keys::kFaviconUrlKey, NULL); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionTabUtil::ScrubTabForExtension(const Extension* extension, 405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) api::tabs::Tab* tab) { 40646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool has_permission = 40746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension && 40846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension->permissions_data()->HasAPIPermission(APIPermission::kTab); 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!has_permission) { 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->url.reset(); 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->title.reset(); 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->fav_icon_url.reset(); 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::GetTabStripModel(const WebContents* web_contents, 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel** tab_strip_model, 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* tab_index) { 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(web_contents); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(tab_strip_model); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(tab_index); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel* tab_strip = it->tab_strip_model(); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = tab_strip->GetIndexOfWebContents(web_contents); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index != -1) { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_strip_model = tab_strip; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_index = index; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::GetDefaultTab(Browser* browser, 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents** contents, 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* tab_id) { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(browser); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(contents); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *contents = browser->tab_strip_model()->GetActiveWebContents(); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*contents) { 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_id) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_id = GetTabId(*contents); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::GetTabById(int tab_id, 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool include_incognito, 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser** browser, 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel** tab_strip, 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents** contents, 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* tab_index) { 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* incognito_profile = 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) include_incognito && profile->HasOffTheRecordProfile() ? 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile->GetOffTheRecordProfile() : NULL; 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* target_browser = *it; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_browser->profile() == profile || 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_browser->profile() == incognito_profile) { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* target_tab_strip = target_browser->tab_strip_model(); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < target_tab_strip->count(); ++i) { 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* target_contents = target_tab_strip->GetWebContentsAt(i); 47003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (SessionTabHelper::IdForTab(target_contents) == tab_id) { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *browser = target_browser; 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_strip) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_strip = target_tab_strip; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (contents) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *contents = target_contents; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_index) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_index = i; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL ExtensionTabUtil::ResolvePossiblyRelativeURL(const std::string& url_string, 488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Extension* extension) { 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url = GURL(url_string); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url.is_valid()) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url = extension->GetResourceURL(url_string); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return url; 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::IsCrashURL(const GURL& url) { 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check a fixed-up URL, to normalize the scheme and parse hosts correctly. 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL fixed_url = 499f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) url_fixer::FixupURL(url.possibly_invalid_spec(), std::string()); 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return (fixed_url.SchemeIs(content::kChromeUIScheme) && 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (fixed_url.host() == content::kChromeUIBrowserCrashHost || 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fixed_url.host() == chrome::kChromeUICrashHost)); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionTabUtil::CreateTab(WebContents* web_contents, 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowOpenDisposition disposition, 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& initial_pos, 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool user_gesture) { 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::FromBrowserContext(web_contents->GetBrowserContext()); 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::HostDesktopType active_desktop = chrome::GetActiveDesktop(); 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindTabbedBrowser(profile, false, active_desktop); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool browser_created = !browser; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser) 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser = new Browser(Browser::CreateParams(profile, active_desktop)); 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::NavigateParams params(browser, web_contents); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The extension_app_id parameter ends up as app_name in the Browser 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which causes the Browser to return true for is_app(). This affects 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // among other things, whether the location bar gets displayed. 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mpcomplete): This seems wrong. What if the extension content is hosted 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in a tab? 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (disposition == NEW_POPUP) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.extension_app_id = extension_id; 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.disposition = disposition; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.window_bounds = initial_pos; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.window_action = chrome::NavigateParams::SHOW_WINDOW; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.user_gesture = user_gesture; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::Navigate(¶ms); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close the browser if chrome::Navigate created a new one. 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_created && (browser != params.browser)) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser->window()->Close(); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionTabUtil::ForEachTab( 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<void(WebContents*)>& callback) { 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (TabContentsIterator iterator; !iterator.done(); iterator.Next()) 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(*iterator); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)WindowController* ExtensionTabUtil::GetWindowControllerOfTab( 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WebContents* web_contents) { 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents(web_contents); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser != NULL) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser->extension_window_controller(); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExtensionTabUtil::OpenOptionsPage(const Extension* extension, 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Browser* browser) { 557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!ManifestURL::GetOptionsPage(extension).is_empty()); 558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Force the options page to open in non-OTR window, because it won't be 560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // able to save settings from OTR. 5610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) scoped_ptr<chrome::ScopedTabbedBrowserDisplayer> displayer; 562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (browser->profile()->IsOffTheRecord()) { 5630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) displayer.reset(new chrome::ScopedTabbedBrowserDisplayer( 5640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser->profile()->GetOriginalProfile(), 5650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser->host_desktop_type())); 5660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser = displayer->browser(); 567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::OpenURLParams params(ManifestURL::GetOptionsPage(extension), 570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Referrer(), 571f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SINGLETON_TAB, 572f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::PAGE_TRANSITION_LINK, 573f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) false); 574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) browser->OpenURL(params); 575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) browser->window()->Show(); 576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebContents* web_contents = 577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) browser->tab_strip_model()->GetActiveWebContents(); 578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) web_contents->GetDelegate()->ActivateContents(web_contents); 579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 581f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace extensions 582