extension_tab_util.cc revision f2477e01787aa58f445919b809d89e252beef54f
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_tab_util.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "apps/shell_window.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "apps/shell_window_registry.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/tabs/tabs_constants.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/tab_helper.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/window_controller.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/window_controller_list.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/sessions/session_id.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_iterator.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/manifest_url_handler.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/net/url_fixer_upper.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/url_constants.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/favicon_status.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/navigation_entry.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents_view.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/extension.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/manifest_constants.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/permissions/api_permission.h" 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h" 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "url/gurl.h" 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using apps::ShellWindow; 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::NavigationEntry; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::WebContents; 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions { 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace keys = tabs_constants; 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WindowController* GetShellWindowController(const WebContents* contents) { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apps::ShellWindowRegistry* registry = 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) apps::ShellWindowRegistry::Get(profile); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!registry) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ShellWindow* shell_window = 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registry->GetShellWindowForRenderViewHost(contents->GetRenderViewHost()); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!shell_window) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return WindowControllerList::GetInstance()-> 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FindWindowById(shell_window->session_id().id()); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int ExtensionTabUtil::GetWindowId(const Browser* browser) { 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return browser->session_id().id(); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int ExtensionTabUtil::GetWindowIdOfTabStripModel( 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const TabStripModel* tab_strip_model) { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it->tab_strip_model() == tab_strip_model) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetWindowId(*it); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int ExtensionTabUtil::GetTabId(const WebContents* web_contents) { 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SessionID::IdForTab(web_contents); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string ExtensionTabUtil::GetTabStatusText(bool is_loading) { 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return is_loading ? keys::kStatusValueLoading : keys::kStatusValueComplete; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int ExtensionTabUtil::GetWindowIdOfTab(const WebContents* web_contents) { 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SessionID::IdForWindowContainingTab(web_contents); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DictionaryValue* ExtensionTabUtil::CreateTabValue( 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const WebContents* contents, 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel* tab_strip, 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int tab_index, 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension) { 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we have a matching ShellWindow with a controller, get the tab value 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // from its controller instead. 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WindowController* controller = GetShellWindowController(contents); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (controller && 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (!extension || controller->IsVisibleToExtension(extension))) { 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return controller->CreateTabValue(extension, tab_index); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DictionaryValue *result = CreateTabValue(contents, tab_strip, tab_index); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScrubTabValueForExtension(contents, extension, result); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::ListValue* ExtensionTabUtil::CreateTabList( 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Browser* browser, 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension) { 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue* tab_list = new base::ListValue(); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < tab_strip->count(); ++i) { 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_list->Append(CreateTabValue(tab_strip->GetWebContentsAt(i), 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_strip, 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) i, 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension)); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return tab_list; 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DictionaryValue* ExtensionTabUtil::CreateTabValue( 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const WebContents* contents, 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel* tab_strip, 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int tab_index) { 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we have a matching ShellWindow with a controller, get the tab value 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // from its controller instead. 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WindowController* controller = GetShellWindowController(contents); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (controller) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return controller->CreateTabValue(NULL, tab_index); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!tab_strip) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionTabUtil::GetTabStripModel(contents, &tab_strip, &tab_index); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DictionaryValue* result = new DictionaryValue(); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_loading = contents->IsLoading(); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetInteger(keys::kIdKey, GetTabId(contents)); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetInteger(keys::kIndexKey, tab_index); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetInteger(keys::kWindowIdKey, GetWindowIdOfTab(contents)); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kStatusKey, GetTabStatusText(is_loading)); 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetBoolean(keys::kActiveKey, 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_strip && tab_index == tab_strip->active_index()); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetBoolean(keys::kSelectedKey, 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_strip && tab_index == tab_strip->active_index()); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetBoolean(keys::kHighlightedKey, 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_strip && tab_strip->IsTabSelected(tab_index)); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetBoolean(keys::kPinnedKey, 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_strip && tab_strip->IsTabPinned(tab_index)); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetBoolean(keys::kIncognitoKey, 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) contents->GetBrowserContext()->IsOffTheRecord()); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetInteger(keys::kWidthKey, 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) contents->GetView()->GetContainerSize().width()); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetInteger(keys::kHeightKey, 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) contents->GetView()->GetContainerSize().height()); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Privacy-sensitive fields: these should be stripped off by 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ScrubTabValueForExtension if the extension should not see them. 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kUrlKey, contents->GetURL().spec()); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kTitleKey, contents->GetTitle()); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_loading) { 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NavigationEntry* entry = contents->GetController().GetVisibleEntry(); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry && entry->GetFavicon().valid) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetString(keys::kFaviconUrlKey, entry->GetFavicon().url.spec()); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (tab_strip) { 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebContents* opener = tab_strip->GetOpenerOfWebContentsAt(tab_index); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (opener) 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result->SetInteger(keys::kOpenerTabIdKey, GetTabId(opener)); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result; 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionTabUtil::ScrubTabValueForExtension(const WebContents* contents, 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension, 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DictionaryValue* tab_info) { 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_permission = 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension && 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PermissionsData::HasAPIPermissionForTab( 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension, GetTabId(contents), APIPermission::kTab); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!has_permission) { 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_info->Remove(keys::kUrlKey, NULL); 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_info->Remove(keys::kTitleKey, NULL); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_info->Remove(keys::kFaviconUrlKey, NULL); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionTabUtil::ScrubTabForExtension(const Extension* extension, 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) api::tabs::Tab* tab) { 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool has_permission = extension && extension->HasAPIPermission( 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) APIPermission::kTab); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!has_permission) { 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->url.reset(); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->title.reset(); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab->fav_icon_url.reset(); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ExtensionTabUtil::GetTabStripModel(const WebContents* web_contents, 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel** tab_strip_model, 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* tab_index) { 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(web_contents); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(tab_strip_model); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(tab_index); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel* tab_strip = it->tab_strip_model(); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int index = tab_strip->GetIndexOfWebContents(web_contents); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (index != -1) { 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *tab_strip_model = tab_strip; 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *tab_index = index; 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ExtensionTabUtil::GetDefaultTab(Browser* browser, 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebContents** contents, 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* tab_id) { 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(browser); 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(contents); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *contents = browser->tab_strip_model()->GetActiveWebContents(); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (*contents) { 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (tab_id) 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *tab_id = GetTabId(*contents); 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ExtensionTabUtil::GetTabById(int tab_id, 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile, 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool include_incognito, 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser** browser, 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel** tab_strip, 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebContents** contents, 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int* tab_index) { 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* incognito_profile = 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) include_incognito && profile->HasOffTheRecordProfile() ? 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile->GetOffTheRecordProfile() : NULL; 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (chrome::BrowserIterator it; !it.done(); it.Next()) { 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* target_browser = *it; 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (target_browser->profile() == profile || 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_browser->profile() == incognito_profile) { 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel* target_tab_strip = target_browser->tab_strip_model(); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < target_tab_strip->count(); ++i) { 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebContents* target_contents = target_tab_strip->GetWebContentsAt(i); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (SessionID::IdForTab(target_contents) == tab_id) { 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *browser = target_browser; 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (tab_strip) 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *tab_strip = target_tab_strip; 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (contents) 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *contents = target_contents; 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (tab_index) 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *tab_index = i; 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GURL ExtensionTabUtil::ResolvePossiblyRelativeURL(const std::string& url_string, 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension) { 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url = GURL(url_string); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!url.is_valid()) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) url = extension->GetResourceURL(url_string); 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return url; 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ExtensionTabUtil::IsCrashURL(const GURL& url) { 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check a fixed-up URL, to normalize the scheme and parse hosts correctly. 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL fixed_url = 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLFixerUpper::FixupURL(url.possibly_invalid_spec(), std::string()); 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (fixed_url.SchemeIs(chrome::kChromeUIScheme) && 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (fixed_url.host() == content::kChromeUIBrowserCrashHost || 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fixed_url.host() == chrome::kChromeUICrashHost)); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionTabUtil::CreateTab(WebContents* web_contents, 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& extension_id, 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WindowOpenDisposition disposition, 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Rect& initial_pos, 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool user_gesture) { 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile = 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile::FromBrowserContext(web_contents->GetBrowserContext()); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::HostDesktopType active_desktop = chrome::GetActiveDesktop(); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindTabbedBrowser(profile, false, active_desktop); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool browser_created = !browser; 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!browser) 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser = new Browser(Browser::CreateParams(profile, active_desktop)); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::NavigateParams params(browser, web_contents); 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The extension_app_id parameter ends up as app_name in the Browser 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // which causes the Browser to return true for is_app(). This affects 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // among other things, whether the location bar gets displayed. 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(mpcomplete): This seems wrong. What if the extension content is hosted 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in a tab? 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (disposition == NEW_POPUP) 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.extension_app_id = extension_id; 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.disposition = disposition; 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.window_bounds = initial_pos; 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.window_action = chrome::NavigateParams::SHOW_WINDOW; 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.user_gesture = user_gesture; 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::Navigate(¶ms); 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Close the browser if chrome::Navigate created a new one. 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser_created && (browser != params.browser)) 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->window()->Close(); 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionTabUtil::ForEachTab( 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Callback<void(WebContents*)>& callback) { 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (TabContentsIterator iterator; !iterator.done(); iterator.Next()) 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(*iterator); 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WindowController* ExtensionTabUtil::GetWindowControllerOfTab( 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const WebContents* web_contents) { 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser = chrome::FindBrowserWithWebContents(web_contents); 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser != NULL) 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return browser->extension_window_controller(); 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionTabUtil::OpenOptionsPage(const Extension* extension, 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser) { 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!ManifestURL::GetOptionsPage(extension).is_empty()); 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Force the options page to open in non-OTR window, because it won't be 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // able to save settings from OTR. 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<chrome::ScopedTabbedBrowserDisplayer> displayer; 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (browser->profile()->IsOffTheRecord()) { 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) displayer.reset(new chrome::ScopedTabbedBrowserDisplayer( 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->profile()->GetOriginalProfile(), 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->host_desktop_type())); 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser = displayer->browser(); 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::OpenURLParams params(ManifestURL::GetOptionsPage(extension), 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::Referrer(), 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SINGLETON_TAB, 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::PAGE_TRANSITION_LINK, 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) false); 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->OpenURL(params); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->window()->Show(); 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebContents* web_contents = 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->tab_strip_model()->GetActiveWebContents(); 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_contents->GetDelegate()->ActivateContents(web_contents); 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace extensions 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)