extension_tab_util.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// found in the LICENSE file. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/extensions/extension_tab_util.h" 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "apps/shell_window.h" 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/extensions/api/tabs/tabs_constants.h" 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/extensions/shell_window_registry.h" 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/extensions/tab_helper.h" 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/extensions/window_controller.h" 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/extensions/window_controller_list.h" 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/net/url_fixer_upper.h" 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/sessions/session_id.h" 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/ui/browser.h" 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h" 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/ui/browser_iterator.h" 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 21926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/common/extensions/extension.h" 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/common/extensions/extension_manifest_constants.h" 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/common/extensions/manifest_url_handler.h" 25591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "chrome/common/extensions/permissions/api_permission.h" 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/common/extensions/permissions/permissions_data.h" 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/common/url_constants.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "content/public/browser/favicon_status.h" 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "content/public/browser/navigation_entry.h" 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "content/public/browser/web_contents.h" 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "googleurl/src/gurl.h" 32926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 33926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)namespace keys = extensions::tabs_constants; 34926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)namespace tabs = extensions::api::tabs; 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 36926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)using apps::ShellWindow; 37926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)using content::NavigationEntry; 38926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)using content::WebContents; 39926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)using extensions::APIPermission; 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using extensions::Extension; 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace { 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 44926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)extensions::WindowController* GetShellWindowController( 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const WebContents* contents) { 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) extensions::ShellWindowRegistry* registry = 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) extensions::ShellWindowRegistry::Get(profile); 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!registry) 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return NULL; 51926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ShellWindow* shell_window = 52926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) registry->GetShellWindowForRenderViewHost(contents->GetRenderViewHost()); 53926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!shell_window) 54926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return NULL; 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return extensions::WindowControllerList::GetInstance()-> 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FindWindowById(shell_window->session_id().id()); 57926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} // namespace 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int ExtensionTabUtil::GetWindowId(const Browser* browser) { 62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return browser->session_id().id(); 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int ExtensionTabUtil::GetWindowIdOfTabStripModel( 66926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) const TabStripModel* tab_strip_model) { 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (it->tab_strip_model() == tab_strip_model) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return GetWindowId(*it); 70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -1; 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)int ExtensionTabUtil::GetTabId(const WebContents* web_contents) { 75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SessionID::IdForTab(web_contents); 76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 77197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)std::string ExtensionTabUtil::GetTabStatusText(bool is_loading) { 79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return is_loading ? keys::kStatusValueLoading : keys::kStatusValueComplete; 80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 82197021e6b966cfb06891637935ef33fff06433d1Ben Murdochint ExtensionTabUtil::GetWindowIdOfTab(const WebContents* web_contents) { 83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return SessionID::IdForWindowContainingTab(web_contents); 84926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 85926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)DictionaryValue* ExtensionTabUtil::CreateTabValue( 87926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) const WebContents* contents, 88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) TabStripModel* tab_strip, 89926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) int tab_index, 90926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) const Extension* extension) { 91926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // If we have a matching ShellWindow with a controller, get the tab value 92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // from its controller instead. 93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) extensions::WindowController* controller = GetShellWindowController(contents); 94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (controller && 95926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) (!extension || controller->IsVisibleToExtension(extension))) { 96926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return controller->CreateTabValue(extension, tab_index); 97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) DictionaryValue *result = CreateTabValue(contents, tab_strip, tab_index); 99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ScrubTabValueForExtension(contents, extension, result); 100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return result; 101926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)base::ListValue* ExtensionTabUtil::CreateTabList( 104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) const Browser* browser, 105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) const Extension* extension) { 106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) base::ListValue* tab_list = new base::ListValue(); 107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (int i = 0; i < tab_strip->count(); ++i) { 109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) tab_list->Append(CreateTabValue(tab_strip->GetWebContentsAt(i), 110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) tab_strip, 111926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) i, 112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) extension)); 113926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 114926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 115926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return tab_list; 116926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 117926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 118926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)DictionaryValue* ExtensionTabUtil::CreateTabValue( 119926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) const WebContents* contents, 120926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) TabStripModel* tab_strip, 121926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) int tab_index) { 122926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // If we have a matching ShellWindow with a controller, get the tab value 123926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // from its controller instead. 124926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) extensions::WindowController* controller = GetShellWindowController(contents); 125926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (controller) 126926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return controller->CreateTabValue(NULL, tab_index); 127926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!tab_strip) 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ExtensionTabUtil::GetTabStripModel(contents, &tab_strip, &tab_index); 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DictionaryValue* result = new DictionaryValue(); 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool is_loading = contents->IsLoading(); 133926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) result->SetInteger(keys::kIdKey, GetTabId(contents)); 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result->SetInteger(keys::kIndexKey, tab_index); 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result->SetInteger(keys::kWindowIdKey, GetWindowIdOfTab(contents)); 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result->SetString(keys::kStatusKey, GetTabStatusText(is_loading)); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result->SetBoolean(keys::kActiveKey, 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tab_strip && tab_index == tab_strip->active_index()); 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result->SetBoolean(keys::kSelectedKey, 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tab_strip && tab_index == tab_strip->active_index()); 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result->SetBoolean(keys::kHighlightedKey, 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tab_strip && tab_strip->IsTabSelected(tab_index)); 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result->SetBoolean(keys::kPinnedKey, 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tab_strip && tab_strip->IsTabPinned(tab_index)); 145926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) result->SetBoolean(keys::kIncognitoKey, 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) contents->GetBrowserContext()->IsOffTheRecord()); 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Privacy-sensitive fields: these should be stripped off by 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // ScrubTabValueForExtension if the extension should not see them. 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result->SetString(keys::kUrlKey, contents->GetURL().spec()); 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result->SetString(keys::kTitleKey, contents->GetTitle()); 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!is_loading) { 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NavigationEntry* entry = contents->GetController().GetActiveEntry(); 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (entry && entry->GetFavicon().valid) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result->SetString(keys::kFaviconUrlKey, entry->GetFavicon().url.spec()); 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (tab_strip) { 159926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) WebContents* opener = tab_strip->GetOpenerOfWebContentsAt(tab_index); 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (opener) 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result->SetInteger(keys::kOpenerTabIdKey, GetTabId(opener)); 162926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 166926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ExtensionTabUtil::ScrubTabValueForExtension(const WebContents* contents, 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const Extension* extension, 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DictionaryValue* tab_info) { 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool has_permission = 171926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) extension && 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) extensions::PermissionsData::HasAPIPermissionForTab( 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) extension, GetTabId(contents), APIPermission::kTab); 174926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!has_permission) { 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tab_info->Remove(keys::kUrlKey, NULL); 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tab_info->Remove(keys::kTitleKey, NULL); 178926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) tab_info->Remove(keys::kFaviconUrlKey, NULL); 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ExtensionTabUtil::ScrubTabForExtension(const Extension* extension, 183926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) tabs::Tab* tab) { 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool has_permission = extension && extension->HasAPIPermission( 185926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) APIPermission::kTab); 186926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 187926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!has_permission) { 188926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) tab->url.reset(); 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tab->title.reset(); 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tab->fav_icon_url.reset(); 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 192926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 194926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool ExtensionTabUtil::GetTabStripModel(const WebContents* web_contents, 195926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) TabStripModel** tab_strip_model, 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int* tab_index) { 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCHECK(web_contents); 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCHECK(tab_strip_model); 199926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) DCHECK(tab_index); 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 201926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TabStripModel* tab_strip = it->tab_strip_model(); 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int index = tab_strip->GetIndexOfWebContents(web_contents); 204926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (index != -1) { 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *tab_strip_model = tab_strip; 206926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *tab_index = index; 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 209926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool ExtensionTabUtil::GetDefaultTab(Browser* browser, 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WebContents** contents, 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int* tab_id) { 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCHECK(browser); 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCHECK(contents); 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *contents = browser->tab_strip_model()->GetActiveWebContents(); 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (*contents) { 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (tab_id) 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *tab_id = GetTabId(*contents); 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool ExtensionTabUtil::GetTabById(int tab_id, 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Profile* profile, 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool include_incognito, 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Browser** browser, 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) TabStripModel** tab_strip, 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) WebContents** contents, 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int* tab_index) { 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Profile* incognito_profile = 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) include_incognito && profile->HasOffTheRecordProfile() ? 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) profile->GetOffTheRecordProfile() : NULL; 240 for (chrome::BrowserIterator it; !it.done(); it.Next()) { 241 Browser* target_browser = *it; 242 if (target_browser->profile() == profile || 243 target_browser->profile() == incognito_profile) { 244 TabStripModel* target_tab_strip = target_browser->tab_strip_model(); 245 for (int i = 0; i < target_tab_strip->count(); ++i) { 246 WebContents* target_contents = target_tab_strip->GetWebContentsAt(i); 247 if (SessionID::IdForTab(target_contents) == tab_id) { 248 if (browser) 249 *browser = target_browser; 250 if (tab_strip) 251 *tab_strip = target_tab_strip; 252 if (contents) 253 *contents = target_contents; 254 if (tab_index) 255 *tab_index = i; 256 return true; 257 } 258 } 259 } 260 } 261 return false; 262} 263 264GURL ExtensionTabUtil::ResolvePossiblyRelativeURL(const std::string& url_string, 265 const extensions::Extension* extension) { 266 GURL url = GURL(url_string); 267 if (!url.is_valid()) 268 url = extension->GetResourceURL(url_string); 269 270 return url; 271} 272 273bool ExtensionTabUtil::IsCrashURL(const GURL& url) { 274 // Check a fixed-up URL, to normalize the scheme and parse hosts correctly. 275 GURL fixed_url = 276 URLFixerUpper::FixupURL(url.possibly_invalid_spec(), std::string()); 277 return (fixed_url.SchemeIs(chrome::kChromeUIScheme) && 278 (fixed_url.host() == content::kChromeUIBrowserCrashHost || 279 fixed_url.host() == chrome::kChromeUICrashHost)); 280} 281 282void ExtensionTabUtil::CreateTab(WebContents* web_contents, 283 const std::string& extension_id, 284 WindowOpenDisposition disposition, 285 const gfx::Rect& initial_pos, 286 bool user_gesture) { 287 Profile* profile = 288 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 289 chrome::HostDesktopType active_desktop = chrome::GetActiveDesktop(); 290 Browser* browser = chrome::FindTabbedBrowser(profile, false, active_desktop); 291 const bool browser_created = !browser; 292 if (!browser) 293 browser = new Browser(Browser::CreateParams(profile, active_desktop)); 294 chrome::NavigateParams params(browser, web_contents); 295 296 // The extension_app_id parameter ends up as app_name in the Browser 297 // which causes the Browser to return true for is_app(). This affects 298 // among other things, whether the location bar gets displayed. 299 // TODO(mpcomplete): This seems wrong. What if the extension content is hosted 300 // in a tab? 301 if (disposition == NEW_POPUP) 302 params.extension_app_id = extension_id; 303 304 params.disposition = disposition; 305 params.window_bounds = initial_pos; 306 params.window_action = chrome::NavigateParams::SHOW_WINDOW; 307 params.user_gesture = user_gesture; 308 chrome::Navigate(¶ms); 309 310 // Close the browser if chrome::Navigate created a new one. 311 if (browser_created && (browser != params.browser)) 312 browser->window()->Close(); 313} 314 315// static 316void ExtensionTabUtil::ForEachTab( 317 const base::Callback<void(WebContents*)>& callback) { 318 for (TabContentsIterator iterator; !iterator.done(); iterator.Next()) 319 callback.Run(*iterator); 320} 321 322// static 323extensions::WindowController* ExtensionTabUtil::GetWindowControllerOfTab( 324 const WebContents* web_contents) { 325 Browser* browser = chrome::FindBrowserWithWebContents(web_contents); 326 if (browser != NULL) 327 return browser->extension_window_controller(); 328 329 return NULL; 330} 331 332void ExtensionTabUtil::OpenOptionsPage(const Extension* extension, 333 Browser* browser) { 334 DCHECK(!extensions::ManifestURL::GetOptionsPage(extension).is_empty()); 335 336 // Force the options page to open in non-OTR window, because it won't be 337 // able to save settings from OTR. 338 if (browser->profile()->IsOffTheRecord()) { 339 browser = chrome::FindOrCreateTabbedBrowser( 340 browser->profile()->GetOriginalProfile(), browser->host_desktop_type()); 341 } 342 343 content::OpenURLParams params( 344 extensions::ManifestURL::GetOptionsPage(extension), 345 content::Referrer(), SINGLETON_TAB, 346 content::PAGE_TRANSITION_LINK, false); 347 browser->OpenURL(params); 348 browser->window()->Show(); 349 WebContents* web_contents = 350 browser->tab_strip_model()->GetActiveWebContents(); 351 web_contents->GetDelegate()->ActivateContents(web_contents); 352} 353