extension_tab_util.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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) 7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/stringprintf.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/tabs/tabs_constants.h" 10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/extensions/chrome_extension_function.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/extensions/chrome_extension_function_details.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/tab_helper.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/window_controller.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/window_controller_list.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/sessions/session_tab_helper.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_iterator.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/ui/singleton_tabs.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/common/extensions/api/tabs.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/url_fixer/url_fixer.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/favicon_status.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/app_window/app_window.h" 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/app_window/app_window_registry.h" 33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/common/constants.h" 34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/common/error_utils.h" 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/feature_switch.h" 37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "extensions/common/manifest_constants.h" 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/common/manifest_handlers/incognito_info.h" 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/manifest_handlers/options_page_info.h" 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "extensions/common/permissions/api_permission.h" 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h" 427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationEntry; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace extensions { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace keys = tabs_constants; 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)WindowController* GetAppWindowController(const WebContents* contents) { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AppWindowRegistry* registry = AppWindowRegistry::Get(profile); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!registry) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppWindow* app_window = 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry->GetAppWindowForRenderViewHost(contents->GetRenderViewHost()); 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!app_window) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return WindowControllerList::GetInstance()->FindWindowById( 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_window->session_id().id()); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// |error_message| can optionally be passed in and will be set with an 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// appropriate message if the window cannot be found by id. 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)Browser* GetBrowserInProfileWithId(Profile* profile, 69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const int window_id, 70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool include_incognito, 71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string* error_message) { 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Profile* incognito_profile = 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) include_incognito && profile->HasOffTheRecordProfile() 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ? profile->GetOffTheRecordProfile() 75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : NULL; 76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser* browser = *it; 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if ((browser->profile() == profile || 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->profile() == incognito_profile) && 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ExtensionTabUtil::GetWindowId(browser) == window_id && 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->window()) { 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return browser; 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (error_message) 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *error_message = ErrorUtils::FormatErrorMessage( 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) keys::kWindowNotFoundError, base::IntToString(window_id)); 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)Browser* CreateBrowser(ChromeUIThreadExtensionFunction* function, 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int window_id, 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string* error) { 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::WebContents* web_contents = function->GetAssociatedWebContents(); 97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(web_contents); 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(web_contents->GetNativeView()); 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(!chrome::FindBrowserWithWebContents(web_contents)); 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::HostDesktopType desktop_type = 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::GetHostDesktopTypeForNativeView(web_contents->GetNativeView()); 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser::CreateParams params( 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser::TYPE_TABBED, function->GetProfile(), desktop_type); 105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser* browser = new Browser(params); 106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->window()->Show(); 107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return browser; 108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ExtensionTabUtil::OpenTabParams::OpenTabParams() 113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : create_browser_if_needed(false) { 114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ExtensionTabUtil::OpenTabParams::~OpenTabParams() { 117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Opens a new tab for a given extension. Returns NULL and sets |error| if an 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// error occurs. 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::DictionaryValue* ExtensionTabUtil::OpenTab( 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ChromeUIThreadExtensionFunction* function, 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const OpenTabParams& params, 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string* error) { 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // windowId defaults to "current" window. 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int window_id = extension_misc::kCurrentWindowId; 127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.window_id.get()) 128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_id = *params.window_id; 129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser* browser = GetBrowserFromWindowID(function, window_id, error); 131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!browser) { 132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!params.create_browser_if_needed) { 133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser = CreateBrowser(function, window_id, error); 136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!browser) 137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Ensure the selected browser is tabbed. 141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!browser->is_type_tabbed() && browser->IsAttemptingToCloseBrowser()) 142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser = chrome::FindTabbedBrowser(function->GetProfile(), 143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->include_incognito(), 144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->host_desktop_type()); 145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!browser || !browser->window()) { 147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(rpaquay): Error message? 148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(jstritar): Add a constant, chrome.tabs.TAB_ID_ACTIVE, that 152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // represents the active tab. 153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WebContents* opener = NULL; 154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.opener_tab_id.get()) { 155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int opener_id = *params.opener_tab_id; 156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!ExtensionTabUtil::GetTabById(opener_id, 158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->GetProfile(), 159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->include_incognito(), 160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NULL, 161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NULL, 162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &opener, 163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) NULL)) { 164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(rpaquay): Error message? 165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // TODO(rafaelw): handle setting remaining tab properties: 170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // -title 171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // -favIconUrl 172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GURL url; 174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.url.get()) { 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string url_string= *params.url; 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) url = ExtensionTabUtil::ResolvePossiblyRelativeURL(url_string, 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) function->extension()); 178010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!url.is_valid()) { 179010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *error = 180010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, url_string); 181010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 182010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) url = GURL(chrome::kChromeUINewTabURL); 185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 186010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Don't let extensions crash the browser or renderers. 188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (ExtensionTabUtil::IsCrashURL(url)) { 189010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *error = keys::kNoCrashBrowserError; 190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Default to foreground for the new tab. The presence of 'active' property 194010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // will override this default. 195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool active = true; 196010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.active.get()) 197010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) active = *params.active; 198010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 199010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Default to not pinning the tab. Setting the 'pinned' property to true 200010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // will override this default. 201010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool pinned = false; 202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.pinned.get()) 203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) pinned = *params.pinned; 204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 205010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // We can't load extension URLs into incognito windows unless the extension 206010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // uses split mode. Special case to fall back to a tabbed window. 207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (url.SchemeIs(kExtensionScheme) && 2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) !IncognitoInfo::IsSplitMode(function->extension()) && 209010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->profile()->IsOffTheRecord()) { 210010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Profile* profile = browser->profile()->GetOriginalProfile(); 211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::HostDesktopType desktop_type = browser->host_desktop_type(); 212010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser = chrome::FindTabbedBrowser(profile, false, desktop_type); 214010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!browser) { 215010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser = new Browser( 216010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser::CreateParams(Browser::TYPE_TABBED, profile, desktop_type)); 217010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) browser->window()->Show(); 218010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 219010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 220010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 221010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If index is specified, honor the value, but keep it bound to 222010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // -1 <= index <= tab_strip->count() where -1 invokes the default behavior. 223010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int index = -1; 224010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (params.index.get()) 225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) index = *params.index; 226010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 227010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 229010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) index = std::min(std::max(index, -1), tab_strip->count()); 230010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int add_types = active ? TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE; 232010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) add_types |= TabStripModel::ADD_FORCE_INDEX; 233010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (pinned) 234010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) add_types |= TabStripModel::ADD_PINNED; 235010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::NavigateParams navigate_params( 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser, url, ui::PAGE_TRANSITION_LINK); 237010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigate_params.disposition = 238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) active ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; 239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigate_params.tabstrip_index = index; 240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigate_params.tabstrip_add_types = add_types; 241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) chrome::Navigate(&navigate_params); 242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The tab may have been created in a different window, so make sure we look 244010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // at the right tab strip. 245010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tab_strip = navigate_params.browser->tab_strip_model(); 246010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int new_index = 247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tab_strip->GetIndexOfWebContents(navigate_params.target_contents); 248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (opener) 249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tab_strip->SetOpenerOfWebContentsAt(new_index, opener); 250010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 251010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (active) 252010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) navigate_params.target_contents->SetInitialFocus(); 253010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Return data about the newly created tab. 255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return ExtensionTabUtil::CreateTabValue(navigate_params.target_contents, 256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) tab_strip, 257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new_index, 2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) function->extension()); 259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 261010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)Browser* ExtensionTabUtil::GetBrowserFromWindowID( 262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ChromeUIThreadExtensionFunction* function, 263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int window_id, 264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string* error) { 265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (window_id == extension_misc::kCurrentWindowId) { 266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Browser* result = function->GetCurrentBrowser(); 267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!result || !result->window()) { 268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (error) 269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *error = keys::kNoCurrentWindowError; 270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return NULL; 271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return result; 273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 274010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return GetBrowserInProfileWithId(function->GetProfile(), 275010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) window_id, 276010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) function->include_incognito(), 277010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) error); 278010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 279010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 280010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciBrowser* ExtensionTabUtil::GetBrowserFromWindowID( 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ChromeExtensionFunctionDetails& details, 2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int window_id, 2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string* error) { 2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (window_id == extension_misc::kCurrentWindowId) { 2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Browser* result = details.GetCurrentBrowser(); 2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!result || !result->window()) { 2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error) 2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *error = keys::kNoCurrentWindowError; 2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return NULL; 2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return result; 2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return GetBrowserInProfileWithId(details.GetProfile(), 2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci window_id, 2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci details.function()->include_incognito(), 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci error); 2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionTabUtil::GetWindowId(const Browser* browser) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser->session_id().id(); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionTabUtil::GetWindowIdOfTabStripModel( 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TabStripModel* tab_strip_model) { 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it->tab_strip_model() == tab_strip_model) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetWindowId(*it); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int ExtensionTabUtil::GetTabId(const WebContents* web_contents) { 31503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return SessionTabHelper::IdForTab(web_contents); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ExtensionTabUtil::GetTabStatusText(bool is_loading) { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return is_loading ? keys::kStatusValueLoading : keys::kStatusValueComplete; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionTabUtil::GetWindowIdOfTab(const WebContents* web_contents) { 32303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return SessionTabHelper::IdForWindowContainingTab(web_contents); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::DictionaryValue* ExtensionTabUtil::CreateTabValue( 327010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WebContents* contents, 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* tab_strip, 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tab_index, 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we have a matching AppWindow with a controller, get the tab value 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // from its controller instead. 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WindowController* controller = GetAppWindowController(contents); 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (controller && 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (!extension || controller->IsVisibleToExtension(extension))) { 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return controller->CreateTabValue(extension, tab_index); 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* result = 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateTabValue(contents, tab_strip, tab_index); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScrubTabValueForExtension(contents, extension, result); 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::ListValue* ExtensionTabUtil::CreateTabList( 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Browser* browser, 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ListValue* tab_list = new base::ListValue(); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < tab_strip->count(); ++i) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_list->Append(CreateTabValue(tab_strip->GetWebContentsAt(i), 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip, 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i, 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension)); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return tab_list; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::DictionaryValue* ExtensionTabUtil::CreateTabValue( 360010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WebContents* contents, 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* tab_strip, 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int tab_index) { 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we have a matching AppWindow with a controller, get the tab value 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // from its controller instead. 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WindowController* controller = GetAppWindowController(contents); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (controller) 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return controller->CreateTabValue(NULL, tab_index); 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tab_strip) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionTabUtil::GetTabStripModel(contents, &tab_strip, &tab_index); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* result = new base::DictionaryValue(); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_loading = contents->IsLoading(); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kIdKey, GetTabId(contents)); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kIndexKey, tab_index); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kWindowIdKey, GetWindowIdOfTab(contents)); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetString(keys::kStatusKey, GetTabStatusText(is_loading)); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kActiveKey, 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_index == tab_strip->active_index()); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kSelectedKey, 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_index == tab_strip->active_index()); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kHighlightedKey, 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_strip->IsTabSelected(tab_index)); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kPinnedKey, 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_strip->IsTabPinned(tab_index)); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kIncognitoKey, 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents->GetBrowserContext()->IsOffTheRecord()); 3883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) result->SetInteger(keys::kWidthKey, 389010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) contents->GetContainerBounds().size().width()); 3903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) result->SetInteger(keys::kHeightKey, 391010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) contents->GetContainerBounds().size().height()); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Privacy-sensitive fields: these should be stripped off by 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ScrubTabValueForExtension if the extension should not see them. 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kUrlKey, contents->GetURL().spec()); 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kTitleKey, contents->GetTitle()); 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_loading) { 3983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NavigationEntry* entry = contents->GetController().GetVisibleEntry(); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry && entry->GetFavicon().valid) 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kFaviconUrlKey, entry->GetFavicon().url.spec()); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_strip) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* opener = tab_strip->GetOpenerOfWebContentsAt(tab_index); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (opener) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kOpenerTabIdKey, GetTabId(opener)); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionTabUtil::ScrubTabValueForExtension( 413010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) WebContents* contents, 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const Extension* extension, 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* tab_info) { 41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool has_permission = extension && 41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension->permissions_data()->HasAPIPermissionForTab( 41846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GetTabId(contents), APIPermission::kTab); 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!has_permission) { 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_info->Remove(keys::kUrlKey, NULL); 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_info->Remove(keys::kTitleKey, NULL); 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_info->Remove(keys::kFaviconUrlKey, NULL); 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionTabUtil::ScrubTabForExtension(const Extension* extension, 428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) api::tabs::Tab* tab) { 42946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool has_permission = 43046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension && 43146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension->permissions_data()->HasAPIPermission(APIPermission::kTab); 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!has_permission) { 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->url.reset(); 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->title.reset(); 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->fav_icon_url.reset(); 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::GetTabStripModel(const WebContents* web_contents, 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel** tab_strip_model, 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* tab_index) { 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(web_contents); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(tab_strip_model); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(tab_index); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel* tab_strip = it->tab_strip_model(); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = tab_strip->GetIndexOfWebContents(web_contents); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index != -1) { 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_strip_model = tab_strip; 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_index = index; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::GetDefaultTab(Browser* browser, 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents** contents, 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* tab_id) { 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(browser); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(contents); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *contents = browser->tab_strip_model()->GetActiveWebContents(); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*contents) { 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_id) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_id = GetTabId(*contents); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::GetTabById(int tab_id, 4771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci content::BrowserContext* browser_context, 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool include_incognito, 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser** browser, 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel** tab_strip, 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents** contents, 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* tab_index) { 4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Profile* profile = Profile::FromBrowserContext(browser_context); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* incognito_profile = 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) include_incognito && profile->HasOffTheRecordProfile() ? 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile->GetOffTheRecordProfile() : NULL; 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* target_browser = *it; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_browser->profile() == profile || 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_browser->profile() == incognito_profile) { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* target_tab_strip = target_browser->tab_strip_model(); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < target_tab_strip->count(); ++i) { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* target_contents = target_tab_strip->GetWebContentsAt(i); 49403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (SessionTabHelper::IdForTab(target_contents) == tab_id) { 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *browser = target_browser; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_strip) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_strip = target_tab_strip; 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (contents) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *contents = target_contents; 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_index) 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_index = i; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL ExtensionTabUtil::ResolvePossiblyRelativeURL(const std::string& url_string, 512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Extension* extension) { 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url = GURL(url_string); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url.is_valid()) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url = extension->GetResourceURL(url_string); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return url; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::IsCrashURL(const GURL& url) { 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check a fixed-up URL, to normalize the scheme and parse hosts correctly. 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL fixed_url = 523f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) url_fixer::FixupURL(url.possibly_invalid_spec(), std::string()); 5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return (fixed_url.SchemeIs(content::kChromeUIScheme) && 525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (fixed_url.host() == content::kChromeUIBrowserCrashHost || 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fixed_url.host() == chrome::kChromeUICrashHost)); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionTabUtil::CreateTab(WebContents* web_contents, 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowOpenDisposition disposition, 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& initial_pos, 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool user_gesture) { 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::FromBrowserContext(web_contents->GetBrowserContext()); 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::HostDesktopType active_desktop = chrome::GetActiveDesktop(); 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindTabbedBrowser(profile, false, active_desktop); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool browser_created = !browser; 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser) 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser = new Browser(Browser::CreateParams(profile, active_desktop)); 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::NavigateParams params(browser, web_contents); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The extension_app_id parameter ends up as app_name in the Browser 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which causes the Browser to return true for is_app(). This affects 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // among other things, whether the location bar gets displayed. 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mpcomplete): This seems wrong. What if the extension content is hosted 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in a tab? 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (disposition == NEW_POPUP) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.extension_app_id = extension_id; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.disposition = disposition; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.window_bounds = initial_pos; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.window_action = chrome::NavigateParams::SHOW_WINDOW; 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.user_gesture = user_gesture; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::Navigate(¶ms); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close the browser if chrome::Navigate created a new one. 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_created && (browser != params.browser)) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser->window()->Close(); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionTabUtil::ForEachTab( 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<void(WebContents*)>& callback) { 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (TabContentsIterator iterator; !iterator.done(); iterator.Next()) 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(*iterator); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)WindowController* ExtensionTabUtil::GetWindowControllerOfTab( 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WebContents* web_contents) { 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents(web_contents); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser != NULL) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser->extension_window_controller(); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExtensionTabUtil::OpenOptionsPage(const Extension* extension, 580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Browser* browser) { 5811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(OptionsPageInfo::HasOptionsPage(extension)); 582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Force the options page to open in non-OTR window, because it won't be 584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // able to save settings from OTR. 5850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) scoped_ptr<chrome::ScopedTabbedBrowserDisplayer> displayer; 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (browser->profile()->IsOffTheRecord()) { 5870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) displayer.reset(new chrome::ScopedTabbedBrowserDisplayer( 5880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser->profile()->GetOriginalProfile(), 5890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser->host_desktop_type())); 5900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) browser = displayer->browser(); 591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!OptionsPageInfo::ShouldOpenInTab(extension)) { 5941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If we should embed the options page for this extension, open 5951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // chrome://extensions in a new tab and show the extension options in an 5961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // embedded popup. 5971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chrome::NavigateParams params(chrome::GetSingletonTabNavigateParams( 5981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser, GURL(chrome::kChromeUIExtensionsURL))); 5991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci params.path_behavior = chrome::NavigateParams::IGNORE_AND_NAVIGATE; 6001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GURL::Replacements replacements; 6021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string query = 6031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::StringPrintf("options=%s", extension->id().c_str()); 6041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci replacements.SetQueryStr(query); 6051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci params.url = params.url.ReplaceComponents(replacements); 6061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci chrome::ShowSingletonTabOverwritingNTP(browser, params); 6081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 6091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Otherwise open a new tab with the extension's options page 6101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci content::OpenURLParams params(OptionsPageInfo::GetOptionsPage(extension), 6111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci content::Referrer(), 6121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SINGLETON_TAB, 6131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ui::PAGE_TRANSITION_LINK, 6141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci false); 6151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser->OpenURL(params); 6161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser->window()->Show(); 6171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WebContents* web_contents = 6181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser->tab_strip_model()->GetActiveWebContents(); 6191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci web_contents->GetDelegate()->ActivateContents(web_contents); 6201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace extensions 624