extension_tab_util.cc revision 010d83a9304c5a91596085d917d248abff47903a
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" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/session_id.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" 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/extensions/manifest_url_handler.h" 25558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/common/net/url_fixer_upper.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/favicon_status.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/common/constants.h" 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/common/error_utils.h" 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "extensions/common/manifest_constants.h" 34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/common/manifest_handlers/incognito_info.h" 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "extensions/common/permissions/api_permission.h" 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h" 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using apps::AppWindow; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationEntry; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace extensions { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace keys = tabs_constants; 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)WindowController* GetAppWindowController(const WebContents* contents) { 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) apps::AppWindowRegistry* registry = apps::AppWindowRegistry::Get(profile); 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!registry) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppWindow* app_window = 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry->GetAppWindowForRenderViewHost(contents->GetRenderViewHost()); 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!app_window) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return WindowControllerList::GetInstance()->FindWindowById( 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_window->session_id().id()); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// |error_message| can optionally be passed in and will be set with an 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// appropriate message if the window cannot be found by id. 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)Browser* GetBrowserInProfileWithId(Profile* profile, 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const int window_id, 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool include_incognito, 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string* error_message) { 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Profile* incognito_profile = 69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) include_incognito && profile->HasOffTheRecordProfile() 70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ? profile->GetOffTheRecordProfile() 71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : NULL; 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser* browser = *it; 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if ((browser->profile() == profile || 75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->profile() == incognito_profile) && 76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ExtensionTabUtil::GetWindowId(browser) == window_id && 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->window()) { 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return browser; 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (error_message) 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *error_message = ErrorUtils::FormatErrorMessage( 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keys::kWindowNotFoundError, base::IntToString(window_id)); 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)Browser* CreateBrowser(ChromeUIThreadExtensionFunction* function, 90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int window_id, 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string* error) { 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::WebContents* web_contents = function->GetAssociatedWebContents(); 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(web_contents); 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(web_contents->GetNativeView()); 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(!chrome::FindBrowserWithWebContents(web_contents)); 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::HostDesktopType desktop_type = 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::GetHostDesktopTypeForNativeView(web_contents->GetNativeView()); 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser::CreateParams params( 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser::TYPE_TABBED, function->GetProfile(), desktop_type); 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser* browser = new Browser(params); 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->window()->Show(); 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return browser; 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ExtensionTabUtil::OpenTabParams::OpenTabParams() 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : create_browser_if_needed(false) { 110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ExtensionTabUtil::OpenTabParams::~OpenTabParams() { 113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Opens a new tab for a given extension. Returns NULL and sets |error| if an 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// error occurs. 117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::DictionaryValue* ExtensionTabUtil::OpenTab( 118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ChromeUIThreadExtensionFunction* function, 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const OpenTabParams& params, 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string* error) { 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // windowId defaults to "current" window. 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int window_id = extension_misc::kCurrentWindowId; 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.window_id.get()) 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_id = *params.window_id; 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser* browser = GetBrowserFromWindowID(function, window_id, error); 127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!browser) { 128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!params.create_browser_if_needed) { 129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser = CreateBrowser(function, window_id, error); 132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!browser) 133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Ensure the selected browser is tabbed. 137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!browser->is_type_tabbed() && browser->IsAttemptingToCloseBrowser()) 138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser = chrome::FindTabbedBrowser(function->GetProfile(), 139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->include_incognito(), 140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->host_desktop_type()); 141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!browser || !browser->window()) { 143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(rpaquay): Error message? 144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(jstritar): Add a constant, chrome.tabs.TAB_ID_ACTIVE, that 148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // represents the active tab. 149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WebContents* opener = NULL; 150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.opener_tab_id.get()) { 151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int opener_id = *params.opener_tab_id; 152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!ExtensionTabUtil::GetTabById(opener_id, 154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->GetProfile(), 155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->include_incognito(), 156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NULL, 157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NULL, 158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &opener, 159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NULL)) { 160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(rpaquay): Error message? 161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(rafaelw): handle setting remaining tab properties: 166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // -title 167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // -favIconUrl 168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string url_string; 170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GURL url; 171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.url.get()) { 172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url_string = *params.url; 173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url = ExtensionTabUtil::ResolvePossiblyRelativeURL( 174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url_string, function->GetExtension()); 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) } 180010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 181010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 182010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Don't let extensions crash the browser or renderers. 183010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (ExtensionTabUtil::IsCrashURL(url)) { 184010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *error = keys::kNoCrashBrowserError; 185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 186010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Default to foreground for the new tab. The presence of 'active' property 189010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // will override this default. 190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool active = true; 191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.active.get()) 192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) active = *params.active; 193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 194010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Default to not pinning the tab. Setting the 'pinned' property to true 195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // will override this default. 196010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool pinned = false; 197010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.pinned.get()) 198010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pinned = *params.pinned; 199010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 200010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // We can't load extension URLs into incognito windows unless the extension 201010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // uses split mode. Special case to fall back to a tabbed window. 202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (url.SchemeIs(kExtensionScheme) && 203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) !IncognitoInfo::IsSplitMode(function->GetExtension()) && 204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->profile()->IsOffTheRecord()) { 205010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Profile* profile = browser->profile()->GetOriginalProfile(); 206010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::HostDesktopType desktop_type = browser->host_desktop_type(); 207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser = chrome::FindTabbedBrowser(profile, false, desktop_type); 209010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!browser) { 210010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser = new Browser( 211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser::CreateParams(Browser::TYPE_TABBED, profile, desktop_type)); 212010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->window()->Show(); 213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 214010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 215010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 216010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If index is specified, honor the value, but keep it bound to 217010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // -1 <= index <= tab_strip->count() where -1 invokes the default behavior. 218010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int index = -1; 219010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.index.get()) 220010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) index = *params.index; 221010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 222010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 223010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 224010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) index = std::min(std::max(index, -1), tab_strip->count()); 225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 226010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int add_types = active ? TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE; 227010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) add_types |= TabStripModel::ADD_FORCE_INDEX; 228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (pinned) 229010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) add_types |= TabStripModel::ADD_PINNED; 230010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::NavigateParams navigate_params( 231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser, url, content::PAGE_TRANSITION_LINK); 232010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigate_params.disposition = 233010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) active ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; 234010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigate_params.tabstrip_index = index; 235010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigate_params.tabstrip_add_types = add_types; 236010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::Navigate(&navigate_params); 237010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The tab may have been created in a different window, so make sure we look 239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // at the right tab strip. 240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tab_strip = navigate_params.browser->tab_strip_model(); 241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int new_index = 242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tab_strip->GetIndexOfWebContents(navigate_params.target_contents); 243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (opener) 244010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tab_strip->SetOpenerOfWebContentsAt(new_index, opener); 245010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 246010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (active) 247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigate_params.target_contents->SetInitialFocus(); 248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Return data about the newly created tab. 250010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return ExtensionTabUtil::CreateTabValue(navigate_params.target_contents, 251010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tab_strip, 252010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new_index, 253010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->GetExtension()); 254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)Browser* ExtensionTabUtil::GetBrowserFromWindowID( 257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ChromeUIThreadExtensionFunction* function, 258010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int window_id, 259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string* error) { 260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (window_id == extension_misc::kCurrentWindowId) { 261010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser* result = function->GetCurrentBrowser(); 262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!result || !result->window()) { 263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (error) 264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *error = keys::kNoCurrentWindowError; 265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return result; 268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return GetBrowserInProfileWithId(function->GetProfile(), 270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_id, 271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->include_incognito(), 272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) error); 273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 274010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 275010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionTabUtil::GetWindowId(const Browser* browser) { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser->session_id().id(); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionTabUtil::GetWindowIdOfTabStripModel( 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TabStripModel* tab_strip_model) { 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it->tab_strip_model() == tab_strip_model) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetWindowId(*it); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 289010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)int ExtensionTabUtil::GetTabId(WebContents* web_contents) { 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SessionID::IdForTab(web_contents); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ExtensionTabUtil::GetTabStatusText(bool is_loading) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return is_loading ? keys::kStatusValueLoading : keys::kStatusValueComplete; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionTabUtil::GetWindowIdOfTab(const WebContents* web_contents) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SessionID::IdForWindowContainingTab(web_contents); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::DictionaryValue* ExtensionTabUtil::CreateTabValue( 302010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WebContents* contents, 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* tab_strip, 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tab_index, 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we have a matching AppWindow with a controller, get the tab value 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // from its controller instead. 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WindowController* controller = GetAppWindowController(contents); 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (controller && 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (!extension || controller->IsVisibleToExtension(extension))) { 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return controller->CreateTabValue(extension, tab_index); 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* result = 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateTabValue(contents, tab_strip, tab_index); 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScrubTabValueForExtension(contents, extension, result); 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::ListValue* ExtensionTabUtil::CreateTabList( 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Browser* browser, 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ListValue* tab_list = new base::ListValue(); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < tab_strip->count(); ++i) { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_list->Append(CreateTabValue(tab_strip->GetWebContentsAt(i), 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip, 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i, 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension)); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return tab_list; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::DictionaryValue* ExtensionTabUtil::CreateTabValue( 335010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WebContents* contents, 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* tab_strip, 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int tab_index) { 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we have a matching AppWindow with a controller, get the tab value 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // from its controller instead. 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WindowController* controller = GetAppWindowController(contents); 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (controller) 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return controller->CreateTabValue(NULL, tab_index); 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tab_strip) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionTabUtil::GetTabStripModel(contents, &tab_strip, &tab_index); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* result = new base::DictionaryValue(); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_loading = contents->IsLoading(); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kIdKey, GetTabId(contents)); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kIndexKey, tab_index); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kWindowIdKey, GetWindowIdOfTab(contents)); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetString(keys::kStatusKey, GetTabStatusText(is_loading)); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kActiveKey, 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_index == tab_strip->active_index()); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kSelectedKey, 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_index == tab_strip->active_index()); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kHighlightedKey, 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_strip->IsTabSelected(tab_index)); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kPinnedKey, 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_strip->IsTabPinned(tab_index)); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kIncognitoKey, 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents->GetBrowserContext()->IsOffTheRecord()); 3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) result->SetInteger(keys::kWidthKey, 364010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) contents->GetContainerBounds().size().width()); 3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) result->SetInteger(keys::kHeightKey, 366010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) contents->GetContainerBounds().size().height()); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Privacy-sensitive fields: these should be stripped off by 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ScrubTabValueForExtension if the extension should not see them. 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kUrlKey, contents->GetURL().spec()); 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kTitleKey, contents->GetTitle()); 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_loading) { 3733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NavigationEntry* entry = contents->GetController().GetVisibleEntry(); 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry && entry->GetFavicon().valid) 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kFaviconUrlKey, entry->GetFavicon().url.spec()); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_strip) { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* opener = tab_strip->GetOpenerOfWebContentsAt(tab_index); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (opener) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kOpenerTabIdKey, GetTabId(opener)); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionTabUtil::ScrubTabValueForExtension( 388010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WebContents* contents, 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const Extension* extension, 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* tab_info) { 39190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool has_permission = 39290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) extension && 393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PermissionsData::HasAPIPermissionForTab( 39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) extension, GetTabId(contents), APIPermission::kTab); 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!has_permission) { 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_info->Remove(keys::kUrlKey, NULL); 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_info->Remove(keys::kTitleKey, NULL); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_info->Remove(keys::kFaviconUrlKey, NULL); 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionTabUtil::ScrubTabForExtension(const Extension* extension, 404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) api::tabs::Tab* tab) { 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_permission = extension && extension->HasAPIPermission( 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) APIPermission::kTab); 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!has_permission) { 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->url.reset(); 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->title.reset(); 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->fav_icon_url.reset(); 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::GetTabStripModel(const WebContents* web_contents, 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel** tab_strip_model, 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* tab_index) { 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(web_contents); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(tab_strip_model); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(tab_index); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel* tab_strip = it->tab_strip_model(); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = tab_strip->GetIndexOfWebContents(web_contents); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index != -1) { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_strip_model = tab_strip; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_index = index; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::GetDefaultTab(Browser* browser, 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents** contents, 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* tab_id) { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(browser); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(contents); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *contents = browser->tab_strip_model()->GetActiveWebContents(); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*contents) { 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_id) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_id = GetTabId(*contents); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::GetTabById(int tab_id, 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool include_incognito, 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser** browser, 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel** tab_strip, 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents** contents, 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* tab_index) { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* incognito_profile = 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) include_incognito && profile->HasOffTheRecordProfile() ? 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile->GetOffTheRecordProfile() : NULL; 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* target_browser = *it; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_browser->profile() == profile || 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_browser->profile() == incognito_profile) { 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* target_tab_strip = target_browser->tab_strip_model(); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < target_tab_strip->count(); ++i) { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* target_contents = target_tab_strip->GetWebContentsAt(i); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SessionID::IdForTab(target_contents) == tab_id) { 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *browser = target_browser; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_strip) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_strip = target_tab_strip; 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (contents) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *contents = target_contents; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_index) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_index = i; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL ExtensionTabUtil::ResolvePossiblyRelativeURL(const std::string& url_string, 486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Extension* extension) { 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url = GURL(url_string); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url.is_valid()) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url = extension->GetResourceURL(url_string); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return url; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::IsCrashURL(const GURL& url) { 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check a fixed-up URL, to normalize the scheme and parse hosts correctly. 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL fixed_url = 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLFixerUpper::FixupURL(url.possibly_invalid_spec(), std::string()); 4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return (fixed_url.SchemeIs(content::kChromeUIScheme) && 499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (fixed_url.host() == content::kChromeUIBrowserCrashHost || 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fixed_url.host() == chrome::kChromeUICrashHost)); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionTabUtil::CreateTab(WebContents* web_contents, 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowOpenDisposition disposition, 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& initial_pos, 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool user_gesture) { 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::FromBrowserContext(web_contents->GetBrowserContext()); 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::HostDesktopType active_desktop = chrome::GetActiveDesktop(); 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindTabbedBrowser(profile, false, active_desktop); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool browser_created = !browser; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser) 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser = new Browser(Browser::CreateParams(profile, active_desktop)); 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::NavigateParams params(browser, web_contents); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The extension_app_id parameter ends up as app_name in the Browser 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which causes the Browser to return true for is_app(). This affects 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // among other things, whether the location bar gets displayed. 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mpcomplete): This seems wrong. What if the extension content is hosted 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in a tab? 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (disposition == NEW_POPUP) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.extension_app_id = extension_id; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.disposition = disposition; 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.window_bounds = initial_pos; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.window_action = chrome::NavigateParams::SHOW_WINDOW; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.user_gesture = user_gesture; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::Navigate(¶ms); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close the browser if chrome::Navigate created a new one. 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_created && (browser != params.browser)) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser->window()->Close(); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionTabUtil::ForEachTab( 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<void(WebContents*)>& callback) { 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (TabContentsIterator iterator; !iterator.done(); iterator.Next()) 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(*iterator); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)WindowController* ExtensionTabUtil::GetWindowControllerOfTab( 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WebContents* web_contents) { 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents(web_contents); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser != NULL) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser->extension_window_controller(); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExtensionTabUtil::OpenOptionsPage(const Extension* extension, 554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Browser* browser) { 555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!ManifestURL::GetOptionsPage(extension).is_empty()); 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Force the options page to open in non-OTR window, because it won't be 558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // able to save settings from OTR. 5590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) scoped_ptr<chrome::ScopedTabbedBrowserDisplayer> displayer; 560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (browser->profile()->IsOffTheRecord()) { 5610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) displayer.reset(new chrome::ScopedTabbedBrowserDisplayer( 5620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser->profile()->GetOriginalProfile(), 5630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser->host_desktop_type())); 5640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser = displayer->browser(); 565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 567f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::OpenURLParams params(ManifestURL::GetOptionsPage(extension), 568f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Referrer(), 569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SINGLETON_TAB, 570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::PAGE_TRANSITION_LINK, 571f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) false); 572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) browser->OpenURL(params); 573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) browser->window()->Show(); 574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebContents* web_contents = 575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) browser->tab_strip_model()->GetActiveWebContents(); 576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) web_contents->GetDelegate()->ActivateContents(web_contents); 577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace extensions 580