extension_tab_util.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/tabs/tabs_constants.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/shell_window_registry.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/tab_helper.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/window_controller.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/window_controller_list.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/net/url_fixer_upper.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/session_id.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_iterator.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/extensions/shell_window.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_manifest_constants.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/permissions/api_permission.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/favicon_status.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "googleurl/src/gurl.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace keys = extensions::tabs_constants; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace tabs = extensions::api::tabs; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationEntry; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::APIPermission; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extensions::WindowController* GetShellWindowController( 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const WebContents* contents) { 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::ShellWindowRegistry* registry = 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::ShellWindowRegistry::Get(profile); 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!registry) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ShellWindow* shell_window = 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registry->GetShellWindowForRenderViewHost(contents->GetRenderViewHost()); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!shell_window) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return extensions::WindowControllerList::GetInstance()-> 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FindWindowById(shell_window->session_id().id()); 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionTabUtil::GetWindowId(const Browser* browser) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser->session_id().id(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionTabUtil::GetWindowIdOfTabStripModel( 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TabStripModel* tab_strip_model) { 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it->tab_strip_model() == tab_strip_model) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetWindowId(*it); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionTabUtil::GetTabId(const WebContents* web_contents) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SessionID::IdForTab(web_contents); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ExtensionTabUtil::GetTabStatusText(bool is_loading) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return is_loading ? keys::kStatusValueLoading : keys::kStatusValueComplete; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int ExtensionTabUtil::GetWindowIdOfTab(const WebContents* web_contents) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SessionID::IdForWindowContainingTab(web_contents); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DictionaryValue* ExtensionTabUtil::CreateTabValue( 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WebContents* contents, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* tab_strip, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tab_index, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we have a matching ShellWindow with a controller, get the tab value 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // from its controller instead. 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::WindowController* controller = GetShellWindowController(contents); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (controller && 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (!extension || controller->IsVisibleToExtension(extension))) { 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return controller->CreateTabValue(extension, tab_index); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DictionaryValue *result = CreateTabValue(contents, tab_strip, tab_index); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScrubTabValueForExtension(contents, extension, result); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ListValue* ExtensionTabUtil::CreateTabList( 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Browser* browser, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListValue* tab_list = new ListValue(); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < tab_strip->count(); ++i) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_list->Append(CreateTabValue(tab_strip->GetWebContentsAt(i), 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension)); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return tab_list; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DictionaryValue* ExtensionTabUtil::CreateTabValue( 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WebContents* contents, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* tab_strip, 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int tab_index) { 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we have a matching ShellWindow with a controller, get the tab value 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // from its controller instead. 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::WindowController* controller = GetShellWindowController(contents); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (controller) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return controller->CreateTabValue(NULL, tab_index); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tab_strip) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionTabUtil::GetTabStripModel(contents, &tab_strip, &tab_index); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DictionaryValue* result = new DictionaryValue(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_loading = contents->IsLoading(); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kIdKey, GetTabId(contents)); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kIndexKey, tab_index); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kWindowIdKey, GetWindowIdOfTab(contents)); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetString(keys::kStatusKey, GetTabStatusText(is_loading)); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kActiveKey, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_index == tab_strip->active_index()); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kSelectedKey, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_index == tab_strip->active_index()); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kHighlightedKey, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_strip->IsTabSelected(tab_index)); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kPinnedKey, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_strip && tab_strip->IsTabPinned(tab_index)); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetBoolean(keys::kIncognitoKey, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents->GetBrowserContext()->IsOffTheRecord()); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Privacy-sensitive fields: these should be stripped off by 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ScrubTabValueForExtension if the extension should not see them. 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kUrlKey, contents->GetURL().spec()); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kTitleKey, contents->GetTitle()); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_loading) { 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NavigationEntry* entry = contents->GetController().GetActiveEntry(); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry && entry->GetFavicon().valid) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kFaviconUrlKey, entry->GetFavicon().url.spec()); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_strip) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* opener = tab_strip->GetOpenerOfWebContentsAt(tab_index); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (opener) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->SetInteger(keys::kOpenerTabIdKey, GetTabId(opener)); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionTabUtil::ScrubTabValueForExtension(const WebContents* contents, 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension, 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DictionaryValue* tab_info) { 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_permission = extension && extension->HasAPIPermissionForTab( 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetTabId(contents), APIPermission::kTab); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!has_permission) { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_info->Remove(keys::kUrlKey, NULL); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_info->Remove(keys::kTitleKey, NULL); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_info->Remove(keys::kFaviconUrlKey, NULL); 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionTabUtil::ScrubTabForExtension(const Extension* extension, 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tabs::Tab* tab) { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_permission = extension && extension->HasAPIPermission( 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) APIPermission::kTab); 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!has_permission) { 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->url.reset(); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->title.reset(); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->fav_icon_url.reset(); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::GetTabStripModel(const WebContents* web_contents, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel** tab_strip_model, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* tab_index) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(web_contents); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(tab_strip_model); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(tab_index); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel* tab_strip = it->tab_strip_model(); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = tab_strip->GetIndexOfWebContents(web_contents); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index != -1) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_strip_model = tab_strip; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_index = index; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::GetDefaultTab(Browser* browser, 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents** contents, 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* tab_id) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(browser); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(contents); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *contents = browser->tab_strip_model()->GetActiveWebContents(); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*contents) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_id) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_id = GetTabId(*contents); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::GetTabById(int tab_id, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool include_incognito, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser** browser, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel** tab_strip, 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents** contents, 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* tab_index) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* incognito_profile = 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) include_incognito && profile->HasOffTheRecordProfile() ? 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile->GetOffTheRecordProfile() : NULL; 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* target_browser = *it; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (target_browser->profile() == profile || 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_browser->profile() == incognito_profile) { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabStripModel* target_tab_strip = target_browser->tab_strip_model(); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < target_tab_strip->count(); ++i) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* target_contents = target_tab_strip->GetWebContentsAt(i); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SessionID::IdForTab(target_contents) == tab_id) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *browser = target_browser; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_strip) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_strip = target_tab_strip; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (contents) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *contents = target_contents; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_index) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *tab_index = i; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL ExtensionTabUtil::ResolvePossiblyRelativeURL(const std::string& url_string, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const extensions::Extension* extension) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url = GURL(url_string); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url.is_valid()) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url = extension->GetResourceURL(url_string); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return url; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionTabUtil::IsCrashURL(const GURL& url) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check a fixed-up URL, to normalize the scheme and parse hosts correctly. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL fixed_url = 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLFixerUpper::FixupURL(url.possibly_invalid_spec(), std::string()); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (fixed_url.SchemeIs(chrome::kChromeUIScheme) && 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (fixed_url.host() == chrome::kChromeUIBrowserCrashHost || 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fixed_url.host() == chrome::kChromeUICrashHost)); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionTabUtil::CreateTab(WebContents* web_contents, 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowOpenDisposition disposition, 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& initial_pos, 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool user_gesture) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::FromBrowserContext(web_contents->GetBrowserContext()); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::HostDesktopType active_desktop = chrome::GetActiveDesktop(); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindTabbedBrowser(profile, false, active_desktop); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool browser_created = !browser; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!browser) 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser = new Browser(Browser::CreateParams(profile, active_desktop)); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::NavigateParams params(browser, web_contents); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The extension_app_id parameter ends up as app_name in the Browser 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which causes the Browser to return true for is_app(). This affects 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // among other things, whether the location bar gets displayed. 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mpcomplete): This seems wrong. What if the extension content is hosted 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in a tab? 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (disposition == NEW_POPUP) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.extension_app_id = extension_id; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.disposition = disposition; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.window_bounds = initial_pos; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.window_action = chrome::NavigateParams::SHOW_WINDOW; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.user_gesture = user_gesture; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::Navigate(¶ms); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close the browser if chrome::Navigate created a new one. 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_created && (browser != params.browser)) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser->window()->Close(); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionTabUtil::ForEachTab( 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<void(WebContents*)>& callback) { 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (TabContentsIterator iterator; !iterator.done(); iterator.Next()) 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(*iterator); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extensions::WindowController* ExtensionTabUtil::GetWindowControllerOfTab( 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WebContents* web_contents) { 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents(web_contents); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser != NULL) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser->extension_window_controller(); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 326