This source file includes following definitions.
- GetBrowserInProfileWithId
- GetBrowserFromWindowID
- GetTabById
- MatchesBool
- CreateBrowserWindow
- RunImpl
- RunImpl
- RunImpl
- RunImpl
- ShouldOpenIncognitoWindow
- RunImpl
- RunImpl
- RunImpl
- RunImpl
- RunImpl
- RunImpl
- RunImpl
- RunImpl
- RunImpl
- RunImpl
- RunImpl
- HighlightTab
- RunImpl
- UpdateURL
- PopulateResult
- OnExecuteCodeFinished
- RunImpl
- MoveTab
- RunImpl
- RunImpl
- RemoveTab
- IsScreenshotEnabled
- GetWebContentsForID
- OnCaptureFailure
- RegisterProfilePrefs
- RunImpl
- Observe
- GotLanguage
- HasPermission
- CanExecuteScriptOnPage
- GetScriptExecutor
- IsWebView
- ShouldInsertCSS
- OnExecuteCodeFinished
- Init
- ShouldInsertCSS
#include "chrome/browser/extensions/api/tabs/tabs_api.h"
#include <algorithm>
#include <limits>
#include <vector>
#include "apps/app_window.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/ref_counted_memory.h"
#include "base/message_loop/message_loop.h"
#include "base/prefs/pref_service.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/api/tabs/tabs_constants.h"
#include "chrome/browser/extensions/api/tabs/windows_util.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/script_executor.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "chrome/browser/extensions/window_controller.h"
#include "chrome/browser/extensions/window_controller_list.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/translate/translate_tab_helper.h"
#include "chrome/browser/ui/apps/chrome_app_window_delegate.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_iterator.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/browser/ui/panels/panel_manager.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/window_sizer/window_sizer.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/api/i18n/default_locale_handler.h"
#include "chrome/common/extensions/api/tabs.h"
#include "chrome/common/extensions/api/windows.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_l10n_util.h"
#include "chrome/common/extensions/message_bundle.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/translate/core/common/language_detection_details.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "content/public/common/url_constants.h"
#include "extensions/browser/extension_function_dispatcher.h"
#include "extensions/browser/extension_function_util.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/file_reader.h"
#include "extensions/common/constants.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_messages.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/manifest_handlers/incognito_info.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/user_script.h"
#include "skia/ext/image_operations.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/models/list_selection_model.h"
#include "ui/base/ui_base_types.h"
#if defined(OS_WIN)
#include "win8/util/win8_util.h"
#endif
#if defined(USE_ASH)
#include "apps/app_window_registry.h"
#include "ash/ash_switches.h"
#include "chrome/browser/extensions/api/tabs/ash_panel_contents.h"
#endif
using apps::AppWindow;
using content::BrowserThread;
using content::NavigationController;
using content::NavigationEntry;
using content::OpenURLParams;
using content::Referrer;
using content::WebContents;
namespace extensions {
namespace windows = api::windows;
namespace keys = tabs_constants;
namespace tabs = api::tabs;
using api::tabs::InjectDetails;
namespace {
Browser* GetBrowserInProfileWithId(Profile* profile,
const int window_id,
bool include_incognito,
std::string* error_message) {
Profile* incognito_profile =
include_incognito && profile->HasOffTheRecordProfile() ?
profile->GetOffTheRecordProfile() : NULL;
for (chrome::BrowserIterator it; !it.done(); it.Next()) {
Browser* browser = *it;
if ((browser->profile() == profile ||
browser->profile() == incognito_profile) &&
ExtensionTabUtil::GetWindowId(browser) == window_id &&
browser->window()) {
return browser;
}
}
if (error_message)
*error_message = ErrorUtils::FormatErrorMessage(
keys::kWindowNotFoundError, base::IntToString(window_id));
return NULL;
}
bool GetBrowserFromWindowID(ChromeAsyncExtensionFunction* function,
int window_id,
Browser** browser) {
if (window_id == extension_misc::kCurrentWindowId) {
*browser = function->GetCurrentBrowser();
if (!(*browser) || !(*browser)->window()) {
function->SetError(keys::kNoCurrentWindowError);
return false;
}
} else {
std::string error;
*browser = GetBrowserInProfileWithId(function->GetProfile(),
window_id,
function->include_incognito(),
&error);
if (!*browser) {
function->SetError(error);
return false;
}
}
return true;
}
bool GetTabById(int tab_id,
Profile* profile,
bool include_incognito,
Browser** browser,
TabStripModel** tab_strip,
content::WebContents** contents,
int* tab_index,
std::string* error_message) {
if (ExtensionTabUtil::GetTabById(tab_id, profile, include_incognito,
browser, tab_strip, contents, tab_index))
return true;
if (error_message)
*error_message = ErrorUtils::FormatErrorMessage(
keys::kTabNotFoundError, base::IntToString(tab_id));
return false;
}
bool MatchesBool(bool* boolean, bool value) {
return !boolean || *boolean == value;
}
Browser* CreateBrowserWindow(const Browser::CreateParams& params,
Profile* profile,
const std::string& extension_id) {
bool use_existing_browser_window = false;
#if defined(OS_WIN)
if (win8::IsSingleWindowMetroMode())
use_existing_browser_window = true;
#endif
Browser* new_window = NULL;
if (use_existing_browser_window)
new_window = chrome::FindTabbedBrowser(profile, false,
params.host_desktop_type);
if (!new_window)
new_window = new Browser(params);
return new_window;
}
}
bool WindowsGetFunction::RunImpl() {
scoped_ptr<windows::Get::Params> params(windows::Get::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
bool populate_tabs = false;
if (params->get_info.get() && params->get_info->populate.get())
populate_tabs = *params->get_info->populate;
WindowController* controller;
if (!windows_util::GetWindowFromWindowID(this,
params->window_id,
&controller)) {
return false;
}
if (populate_tabs)
SetResult(controller->CreateWindowValueWithTabs(GetExtension()));
else
SetResult(controller->CreateWindowValue());
return true;
}
bool WindowsGetCurrentFunction::RunImpl() {
scoped_ptr<windows::GetCurrent::Params> params(
windows::GetCurrent::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
bool populate_tabs = false;
if (params->get_info.get() && params->get_info->populate.get())
populate_tabs = *params->get_info->populate;
WindowController* controller;
if (!windows_util::GetWindowFromWindowID(this,
extension_misc::kCurrentWindowId,
&controller)) {
return false;
}
if (populate_tabs)
SetResult(controller->CreateWindowValueWithTabs(GetExtension()));
else
SetResult(controller->CreateWindowValue());
return true;
}
bool WindowsGetLastFocusedFunction::RunImpl() {
scoped_ptr<windows::GetLastFocused::Params> params(
windows::GetLastFocused::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
bool populate_tabs = false;
if (params->get_info.get() && params->get_info->populate.get())
populate_tabs = *params->get_info->populate;
Browser* browser = chrome::FindAnyBrowser(
GetProfile(), include_incognito(), chrome::GetActiveDesktop());
if (!browser || !browser->window()) {
error_ = keys::kNoLastFocusedWindowError;
return false;
}
WindowController* controller =
browser->extension_window_controller();
if (populate_tabs)
SetResult(controller->CreateWindowValueWithTabs(GetExtension()));
else
SetResult(controller->CreateWindowValue());
return true;
}
bool WindowsGetAllFunction::RunImpl() {
scoped_ptr<windows::GetAll::Params> params(
windows::GetAll::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
bool populate_tabs = false;
if (params->get_info.get() && params->get_info->populate.get())
populate_tabs = *params->get_info->populate;
base::ListValue* window_list = new base::ListValue();
const WindowControllerList::ControllerList& windows =
WindowControllerList::GetInstance()->windows();
for (WindowControllerList::ControllerList::const_iterator iter =
windows.begin();
iter != windows.end(); ++iter) {
if (!this->CanOperateOnWindow(*iter))
continue;
if (populate_tabs)
window_list->Append((*iter)->CreateWindowValueWithTabs(GetExtension()));
else
window_list->Append((*iter)->CreateWindowValue());
}
SetResult(window_list);
return true;
}
bool WindowsCreateFunction::ShouldOpenIncognitoWindow(
const windows::Create::Params::CreateData* create_data,
std::vector<GURL>* urls, bool* is_error) {
*is_error = false;
const IncognitoModePrefs::Availability incognito_availability =
IncognitoModePrefs::GetAvailability(GetProfile()->GetPrefs());
bool incognito = false;
if (create_data && create_data->incognito) {
incognito = *create_data->incognito;
if (incognito && incognito_availability == IncognitoModePrefs::DISABLED) {
error_ = keys::kIncognitoModeIsDisabled;
*is_error = true;
return false;
}
if (!incognito && incognito_availability == IncognitoModePrefs::FORCED) {
error_ = keys::kIncognitoModeIsForced;
*is_error = true;
return false;
}
} else if (incognito_availability == IncognitoModePrefs::FORCED) {
incognito = true;
}
if (incognito && !GetProfile()->IsGuestSession()) {
std::string first_url_erased;
for (size_t i = 0; i < urls->size();) {
if (chrome::IsURLAllowedInIncognito((*urls)[i], GetProfile())) {
i++;
} else {
if (first_url_erased.empty())
first_url_erased = (*urls)[i].spec();
urls->erase(urls->begin() + i);
}
}
if (urls->empty() && !first_url_erased.empty()) {
error_ = ErrorUtils::FormatErrorMessage(
keys::kURLsNotAllowedInIncognitoError, first_url_erased);
*is_error = true;
return false;
}
}
return incognito;
}
bool WindowsCreateFunction::RunImpl() {
scoped_ptr<windows::Create::Params> params(
windows::Create::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params);
std::vector<GURL> urls;
TabStripModel* source_tab_strip = NULL;
int tab_index = -1;
windows::Create::Params::CreateData* create_data = params->create_data.get();
if (create_data && create_data->url) {
std::vector<std::string> url_strings;
if (create_data->url->as_string)
url_strings.push_back(*create_data->url->as_string);
else if (create_data->url->as_strings)
url_strings.swap(*create_data->url->as_strings);
for (std::vector<std::string>::iterator i = url_strings.begin();
i != url_strings.end(); ++i) {
GURL url = ExtensionTabUtil::ResolvePossiblyRelativeURL(
*i, GetExtension());
if (!url.is_valid()) {
error_ = ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, *i);
return false;
}
if (ExtensionTabUtil::IsCrashURL(url)) {
error_ = keys::kNoCrashBrowserError;
return false;
}
urls.push_back(url);
}
}
if (create_data && create_data->tab_id) {
if (!GetTabById(*create_data->tab_id,
GetProfile(),
include_incognito(),
NULL,
&source_tab_strip,
NULL,
&tab_index,
&error_))
return false;
}
Profile* window_profile = GetProfile();
Browser::Type window_type = Browser::TYPE_TABBED;
bool create_panel = false;
PanelManager::CreateMode panel_create_mode = PanelManager::CREATE_AS_DOCKED;
gfx::Rect window_bounds;
bool focused = true;
bool saw_focus_key = false;
std::string extension_id;
bool is_error = true;
bool open_incognito_window = ShouldOpenIncognitoWindow(create_data, &urls,
&is_error);
if (is_error) {
return false;
}
if (open_incognito_window) {
window_profile = window_profile->GetOffTheRecordProfile();
}
if (create_data) {
switch (create_data->type) {
case windows::Create::Params::CreateData::TYPE_POPUP:
window_type = Browser::TYPE_POPUP;
extension_id = GetExtension()->id();
break;
case windows::Create::Params::CreateData::TYPE_PANEL:
case windows::Create::Params::CreateData::TYPE_DETACHED_PANEL: {
extension_id = GetExtension()->id();
bool use_panels = false;
#if !defined(OS_ANDROID)
use_panels = PanelManager::ShouldUsePanels(extension_id);
#endif
if (use_panels) {
create_panel = true;
if (chrome::GetActiveDesktop() != chrome::HOST_DESKTOP_TYPE_ASH &&
create_data->type ==
windows::Create::Params::CreateData::TYPE_DETACHED_PANEL) {
panel_create_mode = PanelManager::CREATE_AS_DETACHED;
}
} else {
window_type = Browser::TYPE_POPUP;
}
break;
}
case windows::Create::Params::CreateData::TYPE_NONE:
case windows::Create::Params::CreateData::TYPE_NORMAL:
break;
default:
error_ = keys::kInvalidWindowTypeError;
return false;
}
if (window_type == Browser::TYPE_TABBED ||
window_type == Browser::TYPE_POPUP ||
create_panel) {
ui::WindowShowState show_state = ui::SHOW_STATE_DEFAULT;
WindowSizer::GetBrowserWindowBoundsAndShowState(std::string(),
gfx::Rect(),
GetCurrentBrowser(),
&window_bounds,
&show_state);
}
if (create_panel && PanelManager::CREATE_AS_DETACHED == panel_create_mode) {
window_bounds.set_origin(
PanelManager::GetInstance()->GetDefaultDetachedPanelOrigin());
}
if (create_data->left)
window_bounds.set_x(*create_data->left);
if (create_data->top)
window_bounds.set_y(*create_data->top);
if (create_data->width)
window_bounds.set_width(*create_data->width);
if (create_data->height)
window_bounds.set_height(*create_data->height);
if (create_data->focused) {
focused = *create_data->focused;
saw_focus_key = true;
}
}
if (create_panel) {
if (urls.empty())
urls.push_back(GURL(chrome::kChromeUINewTabURL));
#if defined(USE_ASH)
if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH) {
AppWindow::CreateParams create_params;
create_params.window_type = AppWindow::WINDOW_TYPE_V1_PANEL;
create_params.window_spec.bounds = window_bounds;
create_params.focused = saw_focus_key && focused;
AppWindow* app_window = new AppWindow(
window_profile, new ChromeAppWindowDelegate(), GetExtension());
AshPanelContents* ash_panel_contents = new AshPanelContents(app_window);
app_window->Init(urls[0], ash_panel_contents, create_params);
SetResult(ash_panel_contents->GetExtensionWindowController()->
CreateWindowValueWithTabs(GetExtension()));
return true;
}
#endif
std::string title =
web_app::GenerateApplicationNameFromExtensionId(extension_id);
Panel* panel = PanelManager::GetInstance()->CreatePanel(
title, window_profile, urls[0], window_bounds, panel_create_mode);
if (!saw_focus_key || !focused)
panel->ShowInactive();
else
panel->Show();
SetResult(
panel->extension_window_controller()->CreateWindowValueWithTabs(
GetExtension()));
return true;
}
chrome::HostDesktopType host_desktop_type = chrome::GetActiveDesktop();
if (create_panel)
window_type = Browser::TYPE_POPUP;
Browser::CreateParams create_params(window_type, window_profile,
host_desktop_type);
if (extension_id.empty()) {
create_params.initial_bounds = window_bounds;
} else {
create_params = Browser::CreateParams::CreateForApp(
window_type,
web_app::GenerateApplicationNameFromExtensionId(extension_id),
window_bounds,
window_profile,
host_desktop_type);
}
create_params.initial_show_state = ui::SHOW_STATE_NORMAL;
create_params.host_desktop_type = chrome::GetActiveDesktop();
Browser* new_window = CreateBrowserWindow(create_params, window_profile,
extension_id);
for (std::vector<GURL>::iterator i = urls.begin(); i != urls.end(); ++i) {
WebContents* tab = chrome::AddSelectedTabWithURL(
new_window, *i, content::PAGE_TRANSITION_LINK);
if (create_panel) {
TabHelper::FromWebContents(tab)->SetExtensionAppIconById(extension_id);
}
}
WebContents* contents = NULL;
if ((window_type == Browser::TYPE_POPUP && urls.empty()) ||
window_type == Browser::TYPE_TABBED) {
if (source_tab_strip)
contents = source_tab_strip->DetachWebContentsAt(tab_index);
if (contents) {
TabStripModel* target_tab_strip = new_window->tab_strip_model();
target_tab_strip->InsertWebContentsAt(urls.size(), contents,
TabStripModel::ADD_NONE);
}
}
if (!contents && urls.empty() && window_type != Browser::TYPE_POPUP) {
chrome::NewTab(new_window);
}
chrome::SelectNumberedTab(new_window, 0);
if (!saw_focus_key && create_panel)
focused = false;
if (focused)
new_window->window()->Show();
else
new_window->window()->ShowInactive();
if (new_window->profile()->IsOffTheRecord() &&
!GetProfile()->IsOffTheRecord() && !include_incognito()) {
SetResult(base::Value::CreateNullValue());
} else {
SetResult(
new_window->extension_window_controller()->CreateWindowValueWithTabs(
GetExtension()));
}
return true;
}
bool WindowsUpdateFunction::RunImpl() {
scoped_ptr<windows::Update::Params> params(
windows::Update::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params);
WindowController* controller;
if (!windows_util::GetWindowFromWindowID(this, params->window_id,
&controller))
return false;
#if defined(OS_WIN)
if (win8::IsSingleWindowMetroMode()) {
SetResult(controller->CreateWindowValue());
return true;
}
#endif
ui::WindowShowState show_state = ui::SHOW_STATE_DEFAULT;
switch (params->update_info.state) {
case windows::Update::Params::UpdateInfo::STATE_NORMAL:
show_state = ui::SHOW_STATE_NORMAL;
break;
case windows::Update::Params::UpdateInfo::STATE_MINIMIZED:
show_state = ui::SHOW_STATE_MINIMIZED;
break;
case windows::Update::Params::UpdateInfo::STATE_MAXIMIZED:
show_state = ui::SHOW_STATE_MAXIMIZED;
break;
case windows::Update::Params::UpdateInfo::STATE_FULLSCREEN:
show_state = ui::SHOW_STATE_FULLSCREEN;
break;
case windows::Update::Params::UpdateInfo::STATE_NONE:
break;
default:
error_ = keys::kInvalidWindowStateError;
return false;
}
if (show_state != ui::SHOW_STATE_FULLSCREEN &&
show_state != ui::SHOW_STATE_DEFAULT)
controller->SetFullscreenMode(false, GetExtension()->url());
switch (show_state) {
case ui::SHOW_STATE_MINIMIZED:
controller->window()->Minimize();
break;
case ui::SHOW_STATE_MAXIMIZED:
controller->window()->Maximize();
break;
case ui::SHOW_STATE_FULLSCREEN:
if (controller->window()->IsMinimized() ||
controller->window()->IsMaximized())
controller->window()->Restore();
controller->SetFullscreenMode(true, GetExtension()->url());
break;
case ui::SHOW_STATE_NORMAL:
controller->window()->Restore();
break;
default:
break;
}
gfx::Rect bounds;
if (controller->window()->IsMinimized())
bounds = controller->window()->GetRestoredBounds();
else
bounds = controller->window()->GetBounds();
bool set_bounds = false;
if (params->update_info.left) {
bounds.set_x(*params->update_info.left);
set_bounds = true;
}
if (params->update_info.top) {
bounds.set_y(*params->update_info.top);
set_bounds = true;
}
if (params->update_info.width) {
bounds.set_width(*params->update_info.width);
set_bounds = true;
}
if (params->update_info.height) {
bounds.set_height(*params->update_info.height);
set_bounds = true;
}
if (set_bounds) {
if (show_state == ui::SHOW_STATE_MINIMIZED ||
show_state == ui::SHOW_STATE_MAXIMIZED ||
show_state == ui::SHOW_STATE_FULLSCREEN) {
error_ = keys::kInvalidWindowStateError;
return false;
}
controller->window()->SetBounds(bounds);
}
if (params->update_info.focused) {
if (*params->update_info.focused) {
if (show_state == ui::SHOW_STATE_MINIMIZED) {
error_ = keys::kInvalidWindowStateError;
return false;
}
controller->window()->Activate();
} else {
if (show_state == ui::SHOW_STATE_MAXIMIZED ||
show_state == ui::SHOW_STATE_FULLSCREEN) {
error_ = keys::kInvalidWindowStateError;
return false;
}
controller->window()->Deactivate();
}
}
if (params->update_info.draw_attention)
controller->window()->FlashFrame(*params->update_info.draw_attention);
SetResult(controller->CreateWindowValue());
return true;
}
bool WindowsRemoveFunction::RunImpl() {
scoped_ptr<windows::Remove::Params> params(
windows::Remove::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params);
WindowController* controller;
if (!windows_util::GetWindowFromWindowID(this, params->window_id,
&controller))
return false;
#if defined(OS_WIN)
if (win8::IsSingleWindowMetroMode())
return false;
#endif
WindowController::Reason reason;
if (!controller->CanClose(&reason)) {
if (reason == WindowController::REASON_NOT_EDITABLE)
error_ = keys::kTabStripNotEditableError;
return false;
}
controller->window()->Close();
return true;
}
bool TabsGetSelectedFunction::RunImpl() {
int window_id = extension_misc::kCurrentWindowId;
scoped_ptr<tabs::GetSelected::Params> params(
tabs::GetSelected::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
if (params->window_id.get())
window_id = *params->window_id;
Browser* browser = NULL;
if (!GetBrowserFromWindowID(this, window_id, &browser))
return false;
TabStripModel* tab_strip = browser->tab_strip_model();
WebContents* contents = tab_strip->GetActiveWebContents();
if (!contents) {
error_ = keys::kNoSelectedTabError;
return false;
}
SetResult(ExtensionTabUtil::CreateTabValue(contents,
tab_strip,
tab_strip->active_index(),
GetExtension()));
return true;
}
bool TabsGetAllInWindowFunction::RunImpl() {
scoped_ptr<tabs::GetAllInWindow::Params> params(
tabs::GetAllInWindow::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
int window_id = extension_misc::kCurrentWindowId;
if (params->window_id.get())
window_id = *params->window_id;
Browser* browser = NULL;
if (!GetBrowserFromWindowID(this, window_id, &browser))
return false;
SetResult(ExtensionTabUtil::CreateTabList(browser, GetExtension()));
return true;
}
bool TabsQueryFunction::RunImpl() {
scoped_ptr<tabs::Query::Params> params(tabs::Query::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
bool loading_status_set = params->query_info.status !=
tabs::Query::Params::QueryInfo::STATUS_NONE;
bool loading = params->query_info.status ==
tabs::Query::Params::QueryInfo::STATUS_LOADING;
URLPattern url_pattern(URLPattern::SCHEME_ALL, "<all_urls>");
if (params->query_info.url.get())
url_pattern = URLPattern(URLPattern::SCHEME_ALL, *params->query_info.url);
std::string title;
if (params->query_info.title.get())
title = *params->query_info.title;
int window_id = extension_misc::kUnknownWindowId;
if (params->query_info.window_id.get())
window_id = *params->query_info.window_id;
int index = -1;
if (params->query_info.index.get())
index = *params->query_info.index;
std::string window_type;
if (params->query_info.window_type !=
tabs::Query::Params::QueryInfo::WINDOW_TYPE_NONE) {
window_type = tabs::Query::Params::QueryInfo::ToString(
params->query_info.window_type);
}
base::ListValue* result = new base::ListValue();
Browser* last_active_browser = chrome::FindAnyBrowser(
GetProfile(), include_incognito(), chrome::GetActiveDesktop());
Browser* current_browser = GetCurrentBrowser();
for (chrome::BrowserIterator it; !it.done(); it.Next()) {
Browser* browser = *it;
if (!GetProfile()->IsSameProfile(browser->profile()))
continue;
if (!browser->window())
continue;
if (!include_incognito() && GetProfile() != browser->profile())
continue;
if (window_id >= 0 && window_id != ExtensionTabUtil::GetWindowId(browser))
continue;
if (window_id == extension_misc::kCurrentWindowId &&
browser != current_browser) {
continue;
}
if (!MatchesBool(params->query_info.current_window.get(),
browser == current_browser)) {
continue;
}
if (!MatchesBool(params->query_info.last_focused_window.get(),
browser == last_active_browser)) {
continue;
}
if (!window_type.empty() &&
window_type !=
browser->extension_window_controller()->GetWindowTypeText()) {
continue;
}
TabStripModel* tab_strip = browser->tab_strip_model();
for (int i = 0; i < tab_strip->count(); ++i) {
const WebContents* web_contents = tab_strip->GetWebContentsAt(i);
if (index > -1 && i != index)
continue;
if (!MatchesBool(params->query_info.highlighted.get(),
tab_strip->IsTabSelected(i))) {
continue;
}
if (!MatchesBool(params->query_info.active.get(),
i == tab_strip->active_index())) {
continue;
}
if (!MatchesBool(params->query_info.pinned.get(),
tab_strip->IsTabPinned(i))) {
continue;
}
if (!title.empty() && !MatchPattern(web_contents->GetTitle(),
base::UTF8ToUTF16(title)))
continue;
if (!url_pattern.MatchesURL(web_contents->GetURL()))
continue;
if (loading_status_set && loading != web_contents->IsLoading())
continue;
result->Append(ExtensionTabUtil::CreateTabValue(
web_contents, tab_strip, i, GetExtension()));
}
}
SetResult(result);
return true;
}
bool TabsCreateFunction::RunImpl() {
scoped_ptr<tabs::Create::Params> params(tabs::Create::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
int window_id = extension_misc::kCurrentWindowId;
if (params->create_properties.window_id.get())
window_id = *params->create_properties.window_id;
Browser* browser = NULL;
if (!GetBrowserFromWindowID(this, window_id, &browser))
return false;
if (!browser->is_type_tabbed() && browser->IsAttemptingToCloseBrowser())
browser = chrome::FindTabbedBrowser(
GetProfile(), include_incognito(), browser->host_desktop_type());
if (!browser || !browser->window())
return false;
WebContents* opener = NULL;
if (params->create_properties.opener_tab_id.get()) {
int opener_id = *params->create_properties.opener_tab_id;
if (!ExtensionTabUtil::GetTabById(opener_id,
GetProfile(),
include_incognito(),
NULL,
NULL,
&opener,
NULL)) {
return false;
}
}
std::string url_string;
GURL url;
if (params->create_properties.url.get()) {
url_string = *params->create_properties.url;
url = ExtensionTabUtil::ResolvePossiblyRelativeURL(url_string,
GetExtension());
if (!url.is_valid()) {
error_ = ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError,
url_string);
return false;
}
}
if (ExtensionTabUtil::IsCrashURL(url)) {
error_ = keys::kNoCrashBrowserError;
return false;
}
bool active = true;
if (params->create_properties.selected.get())
active = *params->create_properties.selected;
if (params->create_properties.active.get())
active = *params->create_properties.active;
bool pinned = false;
if (params->create_properties.pinned.get())
pinned = *params->create_properties.pinned;
if (url.SchemeIs(kExtensionScheme) &&
!IncognitoInfo::IsSplitMode(GetExtension()) &&
browser->profile()->IsOffTheRecord()) {
Profile* profile = browser->profile()->GetOriginalProfile();
chrome::HostDesktopType desktop_type = browser->host_desktop_type();
browser = chrome::FindTabbedBrowser(profile, false, desktop_type);
if (!browser) {
browser = new Browser(Browser::CreateParams(Browser::TYPE_TABBED,
profile, desktop_type));
browser->window()->Show();
}
}
int index = -1;
if (params->create_properties.index.get())
index = *params->create_properties.index;
TabStripModel* tab_strip = browser->tab_strip_model();
index = std::min(std::max(index, -1), tab_strip->count());
int add_types = active ? TabStripModel::ADD_ACTIVE :
TabStripModel::ADD_NONE;
add_types |= TabStripModel::ADD_FORCE_INDEX;
if (pinned)
add_types |= TabStripModel::ADD_PINNED;
chrome::NavigateParams navigate_params(
browser, url, content::PAGE_TRANSITION_LINK);
navigate_params.disposition =
active ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB;
navigate_params.tabstrip_index = index;
navigate_params.tabstrip_add_types = add_types;
chrome::Navigate(&navigate_params);
tab_strip = navigate_params.browser->tab_strip_model();
int new_index = tab_strip->GetIndexOfWebContents(
navigate_params.target_contents);
if (opener)
tab_strip->SetOpenerOfWebContentsAt(new_index, opener);
if (active)
navigate_params.target_contents->GetView()->SetInitialFocus();
if (has_callback()) {
SetResult(ExtensionTabUtil::CreateTabValue(
navigate_params.target_contents,
tab_strip, new_index, GetExtension()));
}
return true;
}
bool TabsDuplicateFunction::RunImpl() {
scoped_ptr<tabs::Duplicate::Params> params(
tabs::Duplicate::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
int tab_id = params->tab_id;
Browser* browser = NULL;
TabStripModel* tab_strip = NULL;
int tab_index = -1;
if (!GetTabById(tab_id,
GetProfile(),
include_incognito(),
&browser,
&tab_strip,
NULL,
&tab_index,
&error_)) {
return false;
}
WebContents* new_contents = chrome::DuplicateTabAt(browser, tab_index);
if (!has_callback())
return true;
TabStripModel* new_tab_strip = NULL;
int new_tab_index = -1;
ExtensionTabUtil::GetTabStripModel(new_contents,
&new_tab_strip,
&new_tab_index);
if (!new_tab_strip || new_tab_index == -1) {
return false;
}
SetResult(ExtensionTabUtil::CreateTabValue(
new_contents,
new_tab_strip, new_tab_index, GetExtension()));
return true;
}
bool TabsGetFunction::RunImpl() {
scoped_ptr<tabs::Get::Params> params(tabs::Get::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
int tab_id = params->tab_id;
TabStripModel* tab_strip = NULL;
WebContents* contents = NULL;
int tab_index = -1;
if (!GetTabById(tab_id,
GetProfile(),
include_incognito(),
NULL,
&tab_strip,
&contents,
&tab_index,
&error_))
return false;
SetResult(ExtensionTabUtil::CreateTabValue(contents,
tab_strip,
tab_index,
GetExtension()));
return true;
}
bool TabsGetCurrentFunction::RunImpl() {
DCHECK(dispatcher());
WebContents* contents = dispatcher()->delegate()->GetAssociatedWebContents();
if (contents)
SetResult(ExtensionTabUtil::CreateTabValue(contents, GetExtension()));
return true;
}
bool TabsHighlightFunction::RunImpl() {
scoped_ptr<tabs::Highlight::Params> params(
tabs::Highlight::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
int window_id = extension_misc::kCurrentWindowId;
if (params->highlight_info.window_id.get())
window_id = *params->highlight_info.window_id;
Browser* browser = NULL;
if (!GetBrowserFromWindowID(this, window_id, &browser))
return false;
TabStripModel* tabstrip = browser->tab_strip_model();
ui::ListSelectionModel selection;
int active_index = -1;
if (params->highlight_info.tabs.as_integers) {
std::vector<int>& tab_indices = *params->highlight_info.tabs.as_integers;
for (size_t i = 0; i < tab_indices.size(); ++i) {
if (!HighlightTab(tabstrip, &selection, &active_index, tab_indices[i]))
return false;
}
} else {
EXTENSION_FUNCTION_VALIDATE(params->highlight_info.tabs.as_integer);
if (!HighlightTab(tabstrip,
&selection,
&active_index,
*params->highlight_info.tabs.as_integer)) {
return false;
}
}
if (selection.empty()) {
error_ = keys::kNoHighlightedTabError;
return false;
}
selection.set_active(active_index);
browser->tab_strip_model()->SetSelectionFromModel(selection);
SetResult(
browser->extension_window_controller()->CreateWindowValueWithTabs(
GetExtension()));
return true;
}
bool TabsHighlightFunction::HighlightTab(TabStripModel* tabstrip,
ui::ListSelectionModel* selection,
int *active_index,
int index) {
if (!tabstrip->ContainsIndex(index)) {
error_ = ErrorUtils::FormatErrorMessage(
keys::kTabIndexNotFoundError, base::IntToString(index));
return false;
}
if (*active_index == -1)
*active_index = index;
selection->AddIndexToSelection(index);
return true;
}
TabsUpdateFunction::TabsUpdateFunction() : web_contents_(NULL) {
}
bool TabsUpdateFunction::RunImpl() {
scoped_ptr<tabs::Update::Params> params(tabs::Update::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
int tab_id = -1;
WebContents* contents = NULL;
if (!params->tab_id.get()) {
Browser* browser = GetCurrentBrowser();
if (!browser) {
error_ = keys::kNoCurrentWindowError;
return false;
}
contents = browser->tab_strip_model()->GetActiveWebContents();
if (!contents) {
error_ = keys::kNoSelectedTabError;
return false;
}
tab_id = SessionID::IdForTab(contents);
} else {
tab_id = *params->tab_id;
}
int tab_index = -1;
TabStripModel* tab_strip = NULL;
if (!GetTabById(tab_id,
GetProfile(),
include_incognito(),
NULL,
&tab_strip,
&contents,
&tab_index,
&error_)) {
return false;
}
web_contents_ = contents;
bool is_async = false;
if (params->update_properties.url.get() &&
!UpdateURL(*params->update_properties.url, tab_id, &is_async)) {
return false;
}
bool active = false;
if (params->update_properties.selected.get())
active = *params->update_properties.selected;
if (params->update_properties.active.get())
active = *params->update_properties.active;
if (active) {
if (tab_strip->active_index() != tab_index) {
tab_strip->ActivateTabAt(tab_index, false);
DCHECK_EQ(contents, tab_strip->GetActiveWebContents());
}
}
if (params->update_properties.highlighted.get()) {
bool highlighted = *params->update_properties.highlighted;
if (highlighted != tab_strip->IsTabSelected(tab_index))
tab_strip->ToggleSelectionAt(tab_index);
}
if (params->update_properties.pinned.get()) {
bool pinned = *params->update_properties.pinned;
tab_strip->SetTabPinned(tab_index, pinned);
tab_index = tab_strip->GetIndexOfWebContents(contents);
}
if (params->update_properties.opener_tab_id.get()) {
int opener_id = *params->update_properties.opener_tab_id;
WebContents* opener_contents = NULL;
if (!ExtensionTabUtil::GetTabById(opener_id,
GetProfile(),
include_incognito(),
NULL,
NULL,
&opener_contents,
NULL))
return false;
tab_strip->SetOpenerOfWebContentsAt(tab_index, opener_contents);
}
if (!is_async) {
PopulateResult();
SendResponse(true);
}
return true;
}
bool TabsUpdateFunction::UpdateURL(const std::string &url_string,
int tab_id,
bool* is_async) {
GURL url = ExtensionTabUtil::ResolvePossiblyRelativeURL(
url_string, GetExtension());
if (!url.is_valid()) {
error_ = ErrorUtils::FormatErrorMessage(
keys::kInvalidUrlError, url_string);
return false;
}
if (ExtensionTabUtil::IsCrashURL(url)) {
error_ = keys::kNoCrashBrowserError;
return false;
}
if (url.SchemeIs(content::kJavaScriptScheme)) {
content::RenderProcessHost* process = web_contents_->GetRenderProcessHost();
if (!PermissionsData::CanExecuteScriptOnPage(
GetExtension(),
web_contents_->GetURL(),
web_contents_->GetURL(),
tab_id,
NULL,
process ? process->GetID() : -1,
&error_)) {
return false;
}
TabHelper::FromWebContents(web_contents_)->
script_executor()->ExecuteScript(
extension_id(),
ScriptExecutor::JAVASCRIPT,
url.GetContent(),
ScriptExecutor::TOP_FRAME,
UserScript::DOCUMENT_IDLE,
ScriptExecutor::MAIN_WORLD,
ScriptExecutor::DEFAULT_PROCESS,
GURL(),
user_gesture_,
ScriptExecutor::NO_RESULT,
base::Bind(&TabsUpdateFunction::OnExecuteCodeFinished, this));
*is_async = true;
return true;
}
web_contents_->GetController().LoadURL(
url, content::Referrer(), content::PAGE_TRANSITION_LINK, std::string());
if (!url.SchemeIs(content::kJavaScriptScheme))
DCHECK_EQ(url.spec(), web_contents_->GetURL().spec());
return true;
}
void TabsUpdateFunction::PopulateResult() {
if (!has_callback())
return;
SetResult(ExtensionTabUtil::CreateTabValue(web_contents_, GetExtension()));
}
void TabsUpdateFunction::OnExecuteCodeFinished(
const std::string& error,
int32 on_page_id,
const GURL& url,
const base::ListValue& script_result) {
if (error.empty())
PopulateResult();
else
error_ = error;
SendResponse(error.empty());
}
bool TabsMoveFunction::RunImpl() {
scoped_ptr<tabs::Move::Params> params(tabs::Move::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
int new_index = params->move_properties.index;
int* window_id = params->move_properties.window_id.get();
scoped_ptr<base::ListValue> tab_values(new base::ListValue());
size_t num_tabs = 0;
if (params->tab_ids.as_integers) {
std::vector<int>& tab_ids = *params->tab_ids.as_integers;
num_tabs = tab_ids.size();
for (size_t i = 0; i < tab_ids.size(); ++i) {
if (!MoveTab(tab_ids[i], &new_index, i, tab_values.get(), window_id))
return false;
}
} else {
EXTENSION_FUNCTION_VALIDATE(params->tab_ids.as_integer);
num_tabs = 1;
if (!MoveTab(*params->tab_ids.as_integer,
&new_index,
0,
tab_values.get(),
window_id)) {
return false;
}
}
if (!has_callback())
return true;
if (num_tabs == 0) {
error_ = "No tabs given.";
return false;
} else if (num_tabs == 1) {
scoped_ptr<base::Value> value;
CHECK(tab_values.get()->Remove(0, &value));
SetResult(value.release());
} else {
SetResult(tab_values.release());
}
return true;
}
bool TabsMoveFunction::MoveTab(int tab_id,
int *new_index,
int iteration,
base::ListValue* tab_values,
int* window_id) {
Browser* source_browser = NULL;
TabStripModel* source_tab_strip = NULL;
WebContents* contents = NULL;
int tab_index = -1;
if (!GetTabById(tab_id,
GetProfile(),
include_incognito(),
&source_browser,
&source_tab_strip,
&contents,
&tab_index,
&error_)) {
return false;
}
if (!source_browser->window()->IsTabStripEditable()) {
error_ = keys::kTabStripNotEditableError;
return false;
}
*new_index += iteration;
if (window_id) {
Browser* target_browser = NULL;
if (!GetBrowserFromWindowID(this, *window_id, &target_browser))
return false;
if (!target_browser->window()->IsTabStripEditable()) {
error_ = keys::kTabStripNotEditableError;
return false;
}
if (!target_browser->is_type_tabbed()) {
error_ = keys::kCanOnlyMoveTabsWithinNormalWindowsError;
return false;
}
if (target_browser->profile() != source_browser->profile()) {
error_ = keys::kCanOnlyMoveTabsWithinSameProfileError;
return false;
}
if (ExtensionTabUtil::GetWindowId(target_browser) !=
ExtensionTabUtil::GetWindowId(source_browser)) {
TabStripModel* target_tab_strip = target_browser->tab_strip_model();
WebContents* web_contents =
source_tab_strip->DetachWebContentsAt(tab_index);
if (!web_contents) {
error_ = ErrorUtils::FormatErrorMessage(
keys::kTabNotFoundError, base::IntToString(tab_id));
return false;
}
if (*new_index > target_tab_strip->count() || *new_index < 0)
*new_index = target_tab_strip->count();
target_tab_strip->InsertWebContentsAt(
*new_index, web_contents, TabStripModel::ADD_NONE);
if (has_callback()) {
tab_values->Append(ExtensionTabUtil::CreateTabValue(
web_contents,
target_tab_strip,
*new_index,
GetExtension()));
}
return true;
}
}
if (*new_index >= source_tab_strip->count() || *new_index < 0)
*new_index = source_tab_strip->count() - 1;
if (*new_index != tab_index)
source_tab_strip->MoveWebContentsAt(tab_index, *new_index, false);
if (has_callback()) {
tab_values->Append(ExtensionTabUtil::CreateTabValue(
contents, source_tab_strip, *new_index, GetExtension()));
}
return true;
}
bool TabsReloadFunction::RunImpl() {
scoped_ptr<tabs::Reload::Params> params(
tabs::Reload::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
bool bypass_cache = false;
if (params->reload_properties.get() &&
params->reload_properties->bypass_cache.get()) {
bypass_cache = *params->reload_properties->bypass_cache;
}
content::WebContents* web_contents = NULL;
if (!params->tab_id.get()) {
Browser* browser = GetCurrentBrowser();
if (!browser) {
error_ = keys::kNoCurrentWindowError;
return false;
}
if (!ExtensionTabUtil::GetDefaultTab(browser, &web_contents, NULL))
return false;
} else {
int tab_id = *params->tab_id;
Browser* browser = NULL;
if (!GetTabById(tab_id,
GetProfile(),
include_incognito(),
&browser,
NULL,
&web_contents,
NULL,
&error_))
return false;
}
if (web_contents->ShowingInterstitialPage()) {
NavigationEntry* entry = web_contents->GetController().GetVisibleEntry();
OpenURLParams params(entry->GetURL(), Referrer(), CURRENT_TAB,
content::PAGE_TRANSITION_RELOAD, false);
GetCurrentBrowser()->OpenURL(params);
} else if (bypass_cache) {
web_contents->GetController().ReloadIgnoringCache(true);
} else {
web_contents->GetController().Reload(true);
}
return true;
}
bool TabsRemoveFunction::RunImpl() {
scoped_ptr<tabs::Remove::Params> params(tabs::Remove::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
if (params->tab_ids.as_integers) {
std::vector<int>& tab_ids = *params->tab_ids.as_integers;
for (size_t i = 0; i < tab_ids.size(); ++i) {
if (!RemoveTab(tab_ids[i]))
return false;
}
} else {
EXTENSION_FUNCTION_VALIDATE(params->tab_ids.as_integer);
if (!RemoveTab(*params->tab_ids.as_integer.get()))
return false;
}
return true;
}
bool TabsRemoveFunction::RemoveTab(int tab_id) {
Browser* browser = NULL;
WebContents* contents = NULL;
if (!GetTabById(tab_id,
GetProfile(),
include_incognito(),
&browser,
NULL,
&contents,
NULL,
&error_)) {
return false;
}
if (!browser->window()->IsTabStripEditable()) {
error_ = keys::kTabStripNotEditableError;
return false;
}
contents->Close();
return true;
}
bool TabsCaptureVisibleTabFunction::IsScreenshotEnabled() {
PrefService* service = GetProfile()->GetPrefs();
if (service->GetBoolean(prefs::kDisableScreenshots)) {
error_ = keys::kScreenshotsDisabled;
return false;
}
return true;
}
WebContents* TabsCaptureVisibleTabFunction::GetWebContentsForID(int window_id) {
Browser* browser = NULL;
if (!GetBrowserFromWindowID(this, window_id, &browser))
return NULL;
WebContents* contents = browser->tab_strip_model()->GetActiveWebContents();
if (!contents) {
error_ = keys::kInternalVisibleTabCaptureError;
return NULL;
}
if (!PermissionsData::CanCaptureVisiblePage(GetExtension(),
SessionID::IdForTab(contents),
&error_)) {
return NULL;
}
return contents;
}
void TabsCaptureVisibleTabFunction::OnCaptureFailure(FailureReason reason) {
error_ = keys::kInternalVisibleTabCaptureError;
SendResponse(false);
}
void TabsCaptureVisibleTabFunction::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterBooleanPref(
prefs::kDisableScreenshots,
false,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
}
bool TabsDetectLanguageFunction::RunImpl() {
scoped_ptr<tabs::DetectLanguage::Params> params(
tabs::DetectLanguage::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
int tab_id = 0;
Browser* browser = NULL;
WebContents* contents = NULL;
if (params->tab_id.get()) {
tab_id = *params->tab_id;
if (!GetTabById(tab_id,
GetProfile(),
include_incognito(),
&browser,
NULL,
&contents,
NULL,
&error_)) {
return false;
}
if (!browser || !contents)
return false;
} else {
browser = GetCurrentBrowser();
if (!browser)
return false;
contents = browser->tab_strip_model()->GetActiveWebContents();
if (!contents)
return false;
}
if (contents->GetController().NeedsReload()) {
error_ = keys::kCannotDetermineLanguageOfUnloadedTab;
return false;
}
AddRef();
TranslateTabHelper* translate_tab_helper =
TranslateTabHelper::FromWebContents(contents);
if (!translate_tab_helper->GetLanguageState().original_language().empty()) {
base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
&TabsDetectLanguageFunction::GotLanguage, this,
translate_tab_helper->GetLanguageState().original_language()));
return true;
}
registrar_.Add(this, chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED,
content::Source<WebContents>(contents));
registrar_.Add(
this, chrome::NOTIFICATION_TAB_CLOSING,
content::Source<NavigationController>(&(contents->GetController())));
registrar_.Add(
this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
content::Source<NavigationController>(&(contents->GetController())));
return true;
}
void TabsDetectLanguageFunction::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
std::string language;
if (type == chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED) {
const LanguageDetectionDetails* lang_det_details =
content::Details<const LanguageDetectionDetails>(details).ptr();
language = lang_det_details->adopted_language;
}
registrar_.RemoveAll();
GotLanguage(language);
}
void TabsDetectLanguageFunction::GotLanguage(const std::string& language) {
SetResult(new base::StringValue(language.c_str()));
SendResponse(true);
Release();
}
ExecuteCodeInTabFunction::ExecuteCodeInTabFunction()
: execute_tab_id_(-1) {
}
ExecuteCodeInTabFunction::~ExecuteCodeInTabFunction() {}
bool ExecuteCodeInTabFunction::HasPermission() {
if (Init() && PermissionsData::HasAPIPermissionForTab(
extension_.get(), execute_tab_id_, APIPermission::kTab)) {
return true;
}
return ExtensionFunction::HasPermission();
}
bool ExecuteCodeInTabFunction::CanExecuteScriptOnPage() {
content::WebContents* contents = NULL;
CHECK_GE(execute_tab_id_, 0);
if (!GetTabById(execute_tab_id_,
GetProfile(),
include_incognito(),
NULL,
NULL,
&contents,
NULL,
&error_)) {
return false;
}
CHECK(contents);
content::RenderProcessHost* process = contents->GetRenderProcessHost();
if (!PermissionsData::CanExecuteScriptOnPage(
GetExtension(),
contents->GetURL(),
contents->GetURL(),
execute_tab_id_,
NULL,
process ? process->GetID() : -1,
&error_)) {
return false;
}
return true;
}
ScriptExecutor* ExecuteCodeInTabFunction::GetScriptExecutor() {
Browser* browser = NULL;
content::WebContents* contents = NULL;
bool success = GetTabById(execute_tab_id_,
GetProfile(),
include_incognito(),
&browser,
NULL,
&contents,
NULL,
&error_) &&
contents && browser;
if (!success)
return NULL;
return TabHelper::FromWebContents(contents)->script_executor();
}
bool ExecuteCodeInTabFunction::IsWebView() const {
return false;
}
bool TabsExecuteScriptFunction::ShouldInsertCSS() const {
return false;
}
void TabsExecuteScriptFunction::OnExecuteCodeFinished(
const std::string& error,
int32 on_page_id,
const GURL& on_url,
const base::ListValue& result) {
if (error.empty())
SetResult(result.DeepCopy());
ExecuteCodeInTabFunction::OnExecuteCodeFinished(error, on_page_id, on_url,
result);
}
bool ExecuteCodeInTabFunction::Init() {
if (details_.get())
return true;
int tab_id = -1;
if (args_->GetInteger(0, &tab_id))
EXTENSION_FUNCTION_VALIDATE(tab_id >= 0);
base::DictionaryValue* details_value = NULL;
if (!args_->GetDictionary(1, &details_value))
return false;
scoped_ptr<InjectDetails> details(new InjectDetails());
if (!InjectDetails::Populate(*details_value, details.get()))
return false;
if (tab_id == -1) {
Browser* browser = GetCurrentBrowser();
if (!browser)
return false;
content::WebContents* web_contents = NULL;
if (!ExtensionTabUtil::GetDefaultTab(browser, &web_contents, &tab_id))
return false;
}
execute_tab_id_ = tab_id;
details_ = details.Pass();
return true;
}
bool TabsInsertCSSFunction::ShouldInsertCSS() const {
return true;
}
}