extension_tab_util.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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) GURL url; 170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.url.get()) { 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string url_string= *params.url; 172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url = ExtensionTabUtil::ResolvePossiblyRelativeURL( 173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) url_string, function->GetExtension()); 174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!url.is_valid()) { 175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *error = 176010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, url_string); 177010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 178010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) url = GURL(chrome::kChromeUINewTabURL); 181010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 182010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 183010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Don't let extensions crash the browser or renderers. 184010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (ExtensionTabUtil::IsCrashURL(url)) { 185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *error = keys::kNoCrashBrowserError; 186010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 189010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Default to foreground for the new tab. The presence of 'active' property 190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // will override this default. 191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool active = true; 192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.active.get()) 193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) active = *params.active; 194010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Default to not pinning the tab. Setting the 'pinned' property to true 196010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // will override this default. 197010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool pinned = false; 198010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.pinned.get()) 199010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pinned = *params.pinned; 200010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 201010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // We can't load extension URLs into incognito windows unless the extension 202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // uses split mode. Special case to fall back to a tabbed window. 203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (url.SchemeIs(kExtensionScheme) && 204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) !IncognitoInfo::IsSplitMode(function->GetExtension()) && 205010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->profile()->IsOffTheRecord()) { 206010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Profile* profile = browser->profile()->GetOriginalProfile(); 207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::HostDesktopType desktop_type = browser->host_desktop_type(); 208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 209010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser = chrome::FindTabbedBrowser(profile, false, desktop_type); 210010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!browser) { 211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser = new Browser( 212010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser::CreateParams(Browser::TYPE_TABBED, profile, desktop_type)); 213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->window()->Show(); 214010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 215010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 216010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 217010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If index is specified, honor the value, but keep it bound to 218010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // -1 <= index <= tab_strip->count() where -1 invokes the default behavior. 219010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int index = -1; 220010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.index.get()) 221010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) index = *params.index; 222010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 223010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 224010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) index = std::min(std::max(index, -1), tab_strip->count()); 226010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 227010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int add_types = active ? TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE; 228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) add_types |= TabStripModel::ADD_FORCE_INDEX; 229010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (pinned) 230010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) add_types |= TabStripModel::ADD_PINNED; 231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::NavigateParams navigate_params( 232010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser, url, content::PAGE_TRANSITION_LINK); 233010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigate_params.disposition = 234010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) active ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; 235010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigate_params.tabstrip_index = index; 236010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigate_params.tabstrip_add_types = add_types; 237010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::Navigate(&navigate_params); 238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The tab may have been created in a different window, so make sure we look 240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // at the right tab strip. 241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tab_strip = navigate_params.browser->tab_strip_model(); 242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int new_index = 243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tab_strip->GetIndexOfWebContents(navigate_params.target_contents); 244010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (opener) 245010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tab_strip->SetOpenerOfWebContentsAt(new_index, opener); 246010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (active) 248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigate_params.target_contents->SetInitialFocus(); 249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 250010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Return data about the newly created tab. 251010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return ExtensionTabUtil::CreateTabValue(navigate_params.target_contents, 252010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tab_strip, 253010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new_index, 254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->GetExtension()); 255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)Browser* ExtensionTabUtil::GetBrowserFromWindowID( 258010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ChromeUIThreadExtensionFunction* function, 259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int window_id, 260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string* error) { 261010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (window_id == extension_misc::kCurrentWindowId) { 262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser* result = function->GetCurrentBrowser(); 263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!result || !result->window()) { 264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (error) 265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *error = keys::kNoCurrentWindowError; 266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return result; 269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return GetBrowserInProfileWithId(function->GetProfile(), 271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_id, 272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->include_incognito(), 273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) error); 274010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 275010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 276010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionTabUtil::GetWindowId(const Browser* browser) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser->session_id().id(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionTabUtil::GetWindowIdOfTabStripModel( 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TabStripModel* tab_strip_model) { 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it->tab_strip_model() == tab_strip_model) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetWindowId(*it); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int ExtensionTabUtil::GetTabId(const WebContents* web_contents) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SessionID::IdForTab(web_contents); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ExtensionTabUtil::GetTabStatusText(bool is_loading) { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return is_loading ? keys::kStatusValueLoading : keys::kStatusValueComplete; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionTabUtil::GetWindowIdOfTab(const WebContents* web_contents) { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SessionID::IdForWindowContainingTab(web_contents); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::DictionaryValue* ExtensionTabUtil::CreateTabValue( 303010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WebContents* contents, 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* tab_strip, 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tab_index, 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we have a matching AppWindow with a controller, get the tab value 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // from its controller instead. 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WindowController* controller = GetAppWindowController(contents); 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (controller && 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (!extension || controller->IsVisibleToExtension(extension))) { 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return controller->CreateTabValue(extension, tab_index); 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* result = 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateTabValue(contents, tab_strip, tab_index); 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScrubTabValueForExtension(contents, extension, result); 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::ListValue* ExtensionTabUtil::CreateTabList( 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Browser* browser, 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ListValue* tab_list = new base::ListValue(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < tab_strip->count(); ++i) { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_list->Append(CreateTabValue(tab_strip->GetWebContentsAt(i), 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip, 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i, 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension)); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return tab_list; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::DictionaryValue* ExtensionTabUtil::CreateTabValue( 336010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WebContents* contents, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* tab_strip, 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int tab_index) { 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we have a matching AppWindow with a controller, get the tab value 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // from its controller instead. 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WindowController* controller = GetAppWindowController(contents); 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (controller) 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return controller->CreateTabValue(NULL, tab_index); 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tab_strip) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionTabUtil::GetTabStripModel(contents, &tab_strip, &tab_index); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* result = new base::DictionaryValue(); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_loading = contents->IsLoading(); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kIdKey, GetTabId(contents)); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kIndexKey, tab_index); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kWindowIdKey, GetWindowIdOfTab(contents)); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetString(keys::kStatusKey, GetTabStatusText(is_loading)); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kActiveKey, 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_index == tab_strip->active_index()); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kSelectedKey, 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_index == tab_strip->active_index()); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kHighlightedKey, 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_strip->IsTabSelected(tab_index)); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kPinnedKey, 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_strip->IsTabPinned(tab_index)); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kIncognitoKey, 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents->GetBrowserContext()->IsOffTheRecord()); 3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) result->SetInteger(keys::kWidthKey, 365010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) contents->GetContainerBounds().size().width()); 3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) result->SetInteger(keys::kHeightKey, 367010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) contents->GetContainerBounds().size().height()); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Privacy-sensitive fields: these should be stripped off by 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ScrubTabValueForExtension if the extension should not see them. 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kUrlKey, contents->GetURL().spec()); 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kTitleKey, contents->GetTitle()); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_loading) { 3743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NavigationEntry* entry = contents->GetController().GetVisibleEntry(); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry && entry->GetFavicon().valid) 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kFaviconUrlKey, entry->GetFavicon().url.spec()); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_strip) { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* opener = tab_strip->GetOpenerOfWebContentsAt(tab_index); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (opener) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kOpenerTabIdKey, GetTabId(opener)); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionTabUtil::ScrubTabValueForExtension( 389010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WebContents* contents, 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const Extension* extension, 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* tab_info) { 39246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool has_permission = extension && 39346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension->permissions_data()->HasAPIPermissionForTab( 39446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 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) { 40546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool has_permission = 40646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension && 40746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension->permissions_data()->HasAPIPermission(APIPermission::kTab); 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!has_permission) { 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->url.reset(); 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->title.reset(); 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->fav_icon_url.reset(); 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::GetTabStripModel(const WebContents* web_contents, 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel** tab_strip_model, 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* tab_index) { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(web_contents); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(tab_strip_model); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(tab_index); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel* tab_strip = it->tab_strip_model(); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = tab_strip->GetIndexOfWebContents(web_contents); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index != -1) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_strip_model = tab_strip; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_index = index; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::GetDefaultTab(Browser* browser, 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents** contents, 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* tab_id) { 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(browser); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(contents); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *contents = browser->tab_strip_model()->GetActiveWebContents(); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*contents) { 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_id) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_id = GetTabId(*contents); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::GetTabById(int tab_id, 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool include_incognito, 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser** browser, 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel** tab_strip, 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents** contents, 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* tab_index) { 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* incognito_profile = 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) include_incognito && profile->HasOffTheRecordProfile() ? 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile->GetOffTheRecordProfile() : NULL; 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* target_browser = *it; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_browser->profile() == profile || 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_browser->profile() == incognito_profile) { 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* target_tab_strip = target_browser->tab_strip_model(); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < target_tab_strip->count(); ++i) { 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* target_contents = target_tab_strip->GetWebContentsAt(i); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SessionID::IdForTab(target_contents) == tab_id) { 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *browser = target_browser; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_strip) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_strip = target_tab_strip; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (contents) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *contents = target_contents; 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_index) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_index = i; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL ExtensionTabUtil::ResolvePossiblyRelativeURL(const std::string& url_string, 487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Extension* extension) { 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url = GURL(url_string); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url.is_valid()) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url = extension->GetResourceURL(url_string); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return url; 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::IsCrashURL(const GURL& url) { 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check a fixed-up URL, to normalize the scheme and parse hosts correctly. 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL fixed_url = 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLFixerUpper::FixupURL(url.possibly_invalid_spec(), std::string()); 4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return (fixed_url.SchemeIs(content::kChromeUIScheme) && 500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (fixed_url.host() == content::kChromeUIBrowserCrashHost || 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fixed_url.host() == chrome::kChromeUICrashHost)); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionTabUtil::CreateTab(WebContents* web_contents, 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowOpenDisposition disposition, 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& initial_pos, 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool user_gesture) { 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::FromBrowserContext(web_contents->GetBrowserContext()); 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::HostDesktopType active_desktop = chrome::GetActiveDesktop(); 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindTabbedBrowser(profile, false, active_desktop); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool browser_created = !browser; 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser) 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser = new Browser(Browser::CreateParams(profile, active_desktop)); 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::NavigateParams params(browser, web_contents); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The extension_app_id parameter ends up as app_name in the Browser 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which causes the Browser to return true for is_app(). This affects 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // among other things, whether the location bar gets displayed. 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mpcomplete): This seems wrong. What if the extension content is hosted 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in a tab? 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (disposition == NEW_POPUP) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.extension_app_id = extension_id; 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.disposition = disposition; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.window_bounds = initial_pos; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.window_action = chrome::NavigateParams::SHOW_WINDOW; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.user_gesture = user_gesture; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::Navigate(¶ms); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close the browser if chrome::Navigate created a new one. 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_created && (browser != params.browser)) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser->window()->Close(); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionTabUtil::ForEachTab( 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<void(WebContents*)>& callback) { 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (TabContentsIterator iterator; !iterator.done(); iterator.Next()) 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(*iterator); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)WindowController* ExtensionTabUtil::GetWindowControllerOfTab( 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WebContents* web_contents) { 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents(web_contents); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser != NULL) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser->extension_window_controller(); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExtensionTabUtil::OpenOptionsPage(const Extension* extension, 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Browser* browser) { 556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!ManifestURL::GetOptionsPage(extension).is_empty()); 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Force the options page to open in non-OTR window, because it won't be 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // able to save settings from OTR. 5600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) scoped_ptr<chrome::ScopedTabbedBrowserDisplayer> displayer; 561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (browser->profile()->IsOffTheRecord()) { 5620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) displayer.reset(new chrome::ScopedTabbedBrowserDisplayer( 5630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser->profile()->GetOriginalProfile(), 5640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser->host_desktop_type())); 5650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser = displayer->browser(); 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 568f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::OpenURLParams params(ManifestURL::GetOptionsPage(extension), 569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::Referrer(), 570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SINGLETON_TAB, 571f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) content::PAGE_TRANSITION_LINK, 572f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) false); 573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) browser->OpenURL(params); 574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) browser->window()->Show(); 575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebContents* web_contents = 576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) browser->tab_strip_model()->GetActiveWebContents(); 577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) web_contents->GetDelegate()->ActivateContents(web_contents); 578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace extensions 581