diff options
Diffstat (limited to 'chrome/browser')
21 files changed, 248 insertions, 106 deletions
diff --git a/chrome/browser/extensions/all_urls_apitest.cc b/chrome/browser/extensions/all_urls_apitest.cc index e22e8ec..6320644 100644 --- a/chrome/browser/extensions/all_urls_apitest.cc +++ b/chrome/browser/extensions/all_urls_apitest.cc @@ -83,7 +83,7 @@ IN_PROC_BROWSER_TEST_F(AllUrlsApiTest, WhitelistedExtension) { // Test that an extension NOT whitelisted for scripting can ask for <all_urls> // and run scripts on non-restricted all pages. IN_PROC_BROWSER_TEST_F(AllUrlsApiTest, RegularExtensions) { - // First load the two extension. + // First load the two extensions. FilePath extension_dir1 = test_data_dir_.AppendASCII("all_urls") .AppendASCII("content_script"); FilePath extension_dir2 = test_data_dir_.AppendASCII("all_urls") diff --git a/chrome/browser/extensions/api/messaging/message_service.cc b/chrome/browser/extensions/api/messaging/message_service.cc index 807cc4d..b5ed615 100644 --- a/chrome/browser/extensions/api/messaging/message_service.cc +++ b/chrome/browser/extensions/api/messaging/message_service.cc @@ -219,8 +219,10 @@ void MessageService::OpenChannelToExtension( // Include info about the opener's tab (if it was a tab). std::string tab_json = "null"; if (source_contents) { - scoped_ptr<DictionaryValue> tab_value( - ExtensionTabUtil::CreateTabValue(source_contents)); + scoped_ptr<DictionaryValue> tab_value(ExtensionTabUtil::CreateTabValue( + source_contents, + profile->GetExtensionService()->extensions()->GetByID( + source_extension_id))); base::JSONWriter::Write(tab_value.get(), &tab_json); } @@ -271,8 +273,10 @@ void MessageService::OpenChannelToTab( // Include info about the opener's tab (if it was a tab). std::string tab_json = "null"; if (source_contents) { - scoped_ptr<DictionaryValue> tab_value( - ExtensionTabUtil::CreateTabValue(source_contents)); + scoped_ptr<DictionaryValue> tab_value(ExtensionTabUtil::CreateTabValue( + source_contents, + profile->GetExtensionService()->extensions()->GetByID( + extension_id))); base::JSONWriter::Write(tab_value.get(), &tab_json); } diff --git a/chrome/browser/extensions/api/permissions/permissions_apitest.cc b/chrome/browser/extensions/api/permissions/permissions_apitest.cc index 3744a85..3e856ab 100644 --- a/chrome/browser/extensions/api/permissions/permissions_apitest.cc +++ b/chrome/browser/extensions/api/permissions/permissions_apitest.cc @@ -73,7 +73,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_AlwaysAllowed) { IN_PROC_BROWSER_TEST_F(ExtensionApiTest, OptionalPermissionsGranted) { // Mark all the tested APIs as granted to bypass the confirmation UI. APIPermissionSet apis; - apis.insert(APIPermission::kTab); + apis.insert(APIPermission::kBookmark); URLPatternSet explicit_hosts; AddPattern(&explicit_hosts, "http://*.c.com/*"); scoped_refptr<PermissionSet> granted_permissions = diff --git a/chrome/browser/extensions/api/tabs/tabs.cc b/chrome/browser/extensions/api/tabs/tabs.cc index 78d1881..45cb097 100644 --- a/chrome/browser/extensions/api/tabs/tabs.cc +++ b/chrome/browser/extensions/api/tabs/tabs.cc @@ -263,7 +263,7 @@ bool GetWindowFunction::RunImpl() { return false; if (populate_tabs) - SetResult(controller->CreateWindowValueWithTabs()); + SetResult(controller->CreateWindowValueWithTabs(GetExtension())); else SetResult(controller->CreateWindowValue()); return true; @@ -284,7 +284,7 @@ bool GetCurrentWindowFunction::RunImpl() { return false; } if (populate_tabs) - SetResult(controller->CreateWindowValueWithTabs()); + SetResult(controller->CreateWindowValueWithTabs(GetExtension())); else SetResult(controller->CreateWindowValue()); return true; @@ -311,7 +311,7 @@ bool GetLastFocusedWindowFunction::RunImpl() { WindowController* controller = browser->extension_window_controller(); if (populate_tabs) - SetResult(controller->CreateWindowValueWithTabs()); + SetResult(controller->CreateWindowValueWithTabs(GetExtension())); else SetResult(controller->CreateWindowValue()); return true; @@ -334,7 +334,7 @@ bool GetAllWindowsFunction::RunImpl() { if (!this->CanOperateOnWindow(*iter)) continue; if (populate_tabs) - window_list->Append((*iter)->CreateWindowValueWithTabs()); + window_list->Append((*iter)->CreateWindowValueWithTabs(GetExtension())); else window_list->Append((*iter)->CreateWindowValue()); } @@ -586,7 +586,8 @@ bool CreateWindowFunction::RunImpl() { panel->Show(); SetResult( - panel->extension_window_controller()->CreateWindowValueWithTabs()); + panel->extension_window_controller()->CreateWindowValueWithTabs( + GetExtension())); return true; } #endif @@ -638,7 +639,8 @@ bool CreateWindowFunction::RunImpl() { SetResult(Value::CreateNullValue()); } else { SetResult( - new_window->extension_window_controller()->CreateWindowValueWithTabs()); + new_window->extension_window_controller()->CreateWindowValueWithTabs( + GetExtension())); } return true; @@ -819,7 +821,8 @@ bool GetSelectedTabFunction::RunImpl() { } SetResult(ExtensionTabUtil::CreateTabValue(contents->web_contents(), tab_strip, - tab_strip->active_index())); + tab_strip->active_index(), + GetExtension())); return true; } @@ -833,7 +836,7 @@ bool GetAllTabsInWindowFunction::RunImpl() { if (!GetBrowserFromWindowID(this, window_id, &browser)) return false; - SetResult(ExtensionTabUtil::CreateTabList(browser)); + SetResult(ExtensionTabUtil::CreateTabList(browser, GetExtension())); return true; } @@ -944,7 +947,7 @@ bool QueryTabsFunction::RunImpl() { continue; result->Append(ExtensionTabUtil::CreateTabValue( - web_contents, tab_strip, i)); + web_contents, tab_strip, i, GetExtension())); } } @@ -1019,13 +1022,11 @@ bool CreateTabFunction::RunImpl() { // be used instead). bool active = true; if (args->HasKey(keys::kSelectedKey)) - EXTENSION_FUNCTION_VALIDATE( - args->GetBoolean(keys::kSelectedKey, &active)); + EXTENSION_FUNCTION_VALIDATE(args->GetBoolean(keys::kSelectedKey, &active)); // The 'active' property has replaced the 'selected' property. if (args->HasKey(keys::kActiveKey)) - EXTENSION_FUNCTION_VALIDATE( - args->GetBoolean(keys::kActiveKey, &active)); + EXTENSION_FUNCTION_VALIDATE(args->GetBoolean(keys::kActiveKey, &active)); // Default to not pinning the tab. Setting the 'pinned' property to true // will override this default. @@ -1081,7 +1082,7 @@ bool CreateTabFunction::RunImpl() { if (has_callback()) { SetResult(ExtensionTabUtil::CreateTabValue( params.target_contents->web_contents(), - tab_strip, new_index)); + tab_strip, new_index, GetExtension())); } return true; @@ -1100,7 +1101,8 @@ bool GetTabFunction::RunImpl() { SetResult(ExtensionTabUtil::CreateTabValue(contents->web_contents(), tab_strip, - tab_index)); + tab_index, + GetExtension())); return true; } @@ -1109,7 +1111,7 @@ bool GetCurrentTabFunction::RunImpl() { WebContents* contents = dispatcher()->delegate()->GetAssociatedWebContents(); if (contents) - SetResult(ExtensionTabUtil::CreateTabValue(contents)); + SetResult(ExtensionTabUtil::CreateTabValue(contents, GetExtension())); return true; } @@ -1166,7 +1168,8 @@ bool HighlightTabsFunction::RunImpl() { selection.set_active(active_index); browser->tab_strip_model()->SetSelectionFromModel(selection); SetResult( - browser->extension_window_controller()->CreateWindowValueWithTabs()); + browser->extension_window_controller()->CreateWindowValueWithTabs( + GetExtension())); return true; } @@ -1342,11 +1345,8 @@ void UpdateTabFunction::PopulateResult() { if (!has_callback()) return; - if (GetExtension()->HasAPIPermission(extensions::APIPermission::kTab)) { - SetResult(ExtensionTabUtil::CreateTabValue(tab_contents_->web_contents())); - } else { - SetResult(Value::CreateNullValue()); - } + SetResult(ExtensionTabUtil::CreateTabValue(tab_contents_->web_contents(), + GetExtension())); } void UpdateTabFunction::OnExecuteCodeFinished(const std::string& error, @@ -1438,9 +1438,13 @@ bool MoveTabsFunction::RunImpl() { target_tab_strip->InsertTabContentsAt( new_index, contents, TabStripModel::ADD_NONE); - if (has_callback()) + if (has_callback()) { tab_values.Append(ExtensionTabUtil::CreateTabValue( - contents->web_contents(), target_tab_strip, new_index)); + contents->web_contents(), + target_tab_strip, + new_index, + GetExtension())); + } continue; } @@ -1456,9 +1460,11 @@ bool MoveTabsFunction::RunImpl() { if (new_index != tab_index) source_tab_strip->MoveTabContentsAt(tab_index, new_index, false); - if (has_callback()) + if (has_callback()) { tab_values.Append(ExtensionTabUtil::CreateTabValue( - contents->web_contents(), source_tab_strip, new_index)); + contents->web_contents(), source_tab_strip, new_index, + GetExtension())); + } } if (!has_callback()) diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc index 1f74f52..dfe8f62 100644 --- a/chrome/browser/extensions/api/tabs/tabs_test.cc +++ b/chrome/browser/extensions/api/tabs/tabs_test.cc @@ -37,6 +37,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, GetWindow) { // Invalid window ID error. scoped_refptr<GetWindowFunction> function = new GetWindowFunction(); + scoped_refptr<extensions::Extension> extension(utils::CreateEmptyExtension()); + function->set_extension(extension.get()); EXPECT_TRUE(MatchPattern( utils::RunFunctionAndReturnError( function.get(), @@ -52,6 +54,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, GetWindow) { bounds = browser()->window()->GetBounds(); function = new GetWindowFunction(); + function->set_extension(extension.get()); scoped_ptr<base::DictionaryValue> result(utils::ToDictionary( utils::RunFunctionAndReturnSingleResult( function.get(), @@ -67,6 +70,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, GetWindow) { // With "populate" enabled. function = new GetWindowFunction(); + function->set_extension(extension.get()); result.reset(utils::ToDictionary( utils::RunFunctionAndReturnSingleResult( function.get(), @@ -91,6 +95,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, GetWindow) { Browser* popup_browser = new Browser( Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile())); function = new GetWindowFunction(); + function->set_extension(extension.get()); result.reset(utils::ToDictionary( utils::RunFunctionAndReturnSingleResult( function.get(), @@ -103,6 +108,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, GetWindow) { Browser* panel_browser = new Browser( Browser::CreateParams(Browser::TYPE_PANEL, browser()->profile())); function = new GetWindowFunction(); + function->set_extension(extension.get()); result.reset(utils::ToDictionary( utils::RunFunctionAndReturnSingleResult( function.get(), @@ -117,6 +123,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, GetWindow) { // Without "include_incognito". function = new GetWindowFunction(); + function->set_extension(extension.get()); EXPECT_TRUE(MatchPattern( utils::RunFunctionAndReturnError( function.get(), @@ -126,6 +133,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, GetWindow) { // With "include_incognito". function = new GetWindowFunction(); + function->set_extension(extension.get()); result.reset(utils::ToDictionary( utils::RunFunctionAndReturnSingleResult( function.get(), @@ -143,6 +151,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, GetCurrentWindow) { // Get the current window using new_browser. scoped_refptr<GetCurrentWindowFunction> function = new GetCurrentWindowFunction(); + scoped_refptr<extensions::Extension> extension(utils::CreateEmptyExtension()); + function->set_extension(extension.get()); scoped_ptr<base::DictionaryValue> result(utils::ToDictionary( utils::RunFunctionAndReturnSingleResult(function.get(), "[]", @@ -156,6 +166,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, GetCurrentWindow) { // Get the current window using the old window and make the tabs populated. function = new GetCurrentWindowFunction(); + function->set_extension(extension.get()); result.reset(utils::ToDictionary( utils::RunFunctionAndReturnSingleResult(function.get(), "[{\"populate\": true}]", @@ -176,6 +187,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, GetLastFocusedWindow) { scoped_refptr<GetLastFocusedWindowFunction> function = new GetLastFocusedWindowFunction(); + scoped_refptr<extensions::Extension> extension(utils::CreateEmptyExtension()); + function->set_extension(extension.get()); scoped_ptr<base::DictionaryValue> result(utils::ToDictionary( utils::RunFunctionAndReturnSingleResult(function.get(), "[]", @@ -188,6 +201,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, GetLastFocusedWindow) { EXPECT_FALSE(result.get()->GetList(keys::kTabsKey, &tabs)); function = new GetLastFocusedWindowFunction(); + function->set_extension(extension.get()); result.reset(utils::ToDictionary( utils::RunFunctionAndReturnSingleResult(function.get(), "[{\"populate\": true}]", @@ -212,6 +226,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, GetAllWindows) { } scoped_refptr<GetAllWindowsFunction> function = new GetAllWindowsFunction(); + scoped_refptr<extensions::Extension> extension(utils::CreateEmptyExtension()); + function->set_extension(extension.get()); scoped_ptr<base::ListValue> result(utils::ToList( utils::RunFunctionAndReturnSingleResult(function.get(), "[]", @@ -233,6 +249,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, GetAllWindows) { result_ids.clear(); function = new GetAllWindowsFunction(); + function->set_extension(extension.get()); result.reset(utils::ToList( utils::RunFunctionAndReturnSingleResult(function.get(), "[{\"populate\": true}]", @@ -263,11 +280,14 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, UpdateNoPermissions) { // Without a callback the function will not generate a result. update_tab_function->set_has_callback(true); - scoped_ptr<base::Value> result(utils::RunFunctionAndReturnSingleResult( + scoped_ptr<base::DictionaryValue> result(utils::ToDictionary( + utils::RunFunctionAndReturnSingleResult( update_tab_function.get(), - "[null, {\"url\": \"neutrinos\"}]", - browser())); - EXPECT_EQ(base::Value::TYPE_NULL, result->GetType()); + "[null, {\"url\": \"about:blank\", \"pinned\": true}]", + browser()))); + // The url is stripped since the extension does not have tab permissions. + EXPECT_FALSE(result->HasKey("url")); + EXPECT_TRUE(utils::GetBoolean(result.get(), "pinned")); } IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, @@ -278,7 +298,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(), IncognitoModePrefs::FORCED); // Run without an explicit "incognito" param. - scoped_refptr<CreateWindowFunction> function = new CreateWindowFunction(); + scoped_refptr<CreateWindowFunction> function(new CreateWindowFunction()); + scoped_refptr<extensions::Extension> extension(utils::CreateEmptyExtension()); + function->set_extension(extension.get()); scoped_ptr<base::DictionaryValue> result(utils::ToDictionary( utils::RunFunctionAndReturnSingleResult( function.get(), @@ -296,6 +318,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, Browser* incognito_browser = CreateIncognitoBrowser(); // Run without an explicit "incognito" param. function = new CreateWindowFunction(); + function->set_extension(extension.get()); result.reset(utils::ToDictionary( utils::RunFunctionAndReturnSingleResult( function.get(), @@ -317,6 +340,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, IncognitoModePrefs::FORCED); // Run without an explicit "incognito" param. scoped_refptr<CreateWindowFunction> function = new CreateWindowFunction(); + scoped_refptr<extensions::Extension> extension(utils::CreateEmptyExtension()); + function->set_extension(extension.get()); scoped_ptr<base::DictionaryValue> result(utils::ToDictionary( utils::RunFunctionAndReturnSingleResult(function.get(), kEmptyArgs, @@ -333,6 +358,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, Browser* incognito_browser = CreateIncognitoBrowser(); // Run without an explicit "incognito" param. function = new CreateWindowFunction(); + function->set_extension(extension.get()); result.reset(utils::ToDictionary( utils::RunFunctionAndReturnSingleResult(function.get(), kEmptyArgs, @@ -355,6 +381,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, // Run with an explicit "incognito" param. scoped_refptr<CreateWindowFunction> function = new CreateWindowFunction(); + scoped_refptr<extensions::Extension> extension(utils::CreateEmptyExtension()); + function->set_extension(extension.get()); EXPECT_TRUE(MatchPattern( utils::RunFunctionAndReturnError(function.get(), kArgsWithExplicitIncognitoParam, @@ -365,6 +393,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, Browser* incognito_browser = CreateIncognitoBrowser(); // Run with an explicit "incognito" param. function = new CreateWindowFunction(); + function->set_extension(extension.get()); EXPECT_TRUE(MatchPattern( utils::RunFunctionAndReturnError(function.get(), kArgsWithExplicitIncognitoParam, @@ -383,6 +412,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, IncognitoModePrefs::DISABLED); // Run in normal window. scoped_refptr<CreateWindowFunction> function = new CreateWindowFunction(); + scoped_refptr<extensions::Extension> extension(utils::CreateEmptyExtension()); + function->set_extension(extension.get()); EXPECT_TRUE(MatchPattern( utils::RunFunctionAndReturnError(function.get(), kArgs, @@ -391,6 +422,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, // Run in incognito window. function = new CreateWindowFunction(); + function->set_extension(extension.get()); EXPECT_TRUE(MatchPattern( utils::RunFunctionAndReturnError(function.get(), kArgs, @@ -409,6 +441,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, QueryCurrentWindowTabs) { // Get tabs in the 'current' window called from non-focused browser. scoped_refptr<QueryTabsFunction> function = new QueryTabsFunction(); + function->set_extension(utils::CreateEmptyExtension().get()); scoped_ptr<base::ListValue> result(utils::ToList( utils::RunFunctionAndReturnSingleResult(function.get(), "[{\"currentWindow\":true}]", @@ -425,6 +458,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, QueryCurrentWindowTabs) { // Get tabs NOT in the 'current' window called from non-focused browser. function = new QueryTabsFunction(); + function->set_extension(utils::CreateEmptyExtension().get()); result.reset(utils::ToList( utils::RunFunctionAndReturnSingleResult(function.get(), "[{\"currentWindow\":false}]", @@ -506,6 +540,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, DontCreateTabInClosingPopupWindow) { chrome::CloseWindow(popup_browser); scoped_refptr<CreateTabFunction> create_tab_function(new CreateTabFunction()); + create_tab_function->set_extension(utils::CreateEmptyExtension().get()); // Without a callback the function will not generate a result. create_tab_function->set_has_callback(true); @@ -527,6 +562,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, InvalidUpdateWindowState) { static const char kArgsMinimizedWithFocus[] = "[%u, {\"state\": \"minimized\", \"focused\": true}]"; scoped_refptr<UpdateWindowFunction> function = new UpdateWindowFunction(); + scoped_refptr<extensions::Extension> extension(utils::CreateEmptyExtension()); + function->set_extension(extension.get()); EXPECT_TRUE(MatchPattern( utils::RunFunctionAndReturnError( function.get(), @@ -537,6 +574,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, InvalidUpdateWindowState) { static const char kArgsMaximizedWithoutFocus[] = "[%u, {\"state\": \"maximized\", \"focused\": false}]"; function = new UpdateWindowFunction(); + function->set_extension(extension.get()); EXPECT_TRUE(MatchPattern( utils::RunFunctionAndReturnError( function.get(), @@ -547,6 +585,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, InvalidUpdateWindowState) { static const char kArgsMinimizedWithBounds[] = "[%u, {\"state\": \"minimized\", \"width\": 500}]"; function = new UpdateWindowFunction(); + function->set_extension(extension.get()); EXPECT_TRUE(MatchPattern( utils::RunFunctionAndReturnError( function.get(), @@ -557,6 +596,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, InvalidUpdateWindowState) { static const char kArgsMaximizedWithBounds[] = "[%u, {\"state\": \"maximized\", \"width\": 500}]"; function = new UpdateWindowFunction(); + function->set_extension(extension.get()); EXPECT_TRUE(MatchPattern( utils::RunFunctionAndReturnError( function.get(), diff --git a/chrome/browser/extensions/browser_event_router.cc b/chrome/browser/extensions/browser_event_router.cc index 1aa89c5..af5cf9b 100644 --- a/chrome/browser/extensions/browser_event_router.cc +++ b/chrome/browser/extensions/browser_event_router.cc @@ -384,18 +384,35 @@ void BrowserEventRouter::DispatchEventWithTab( const char* event_name, const WebContents* web_contents, bool active, - EventRouter::UserGestureState user_gesture) { + EventRouter::UserGestureState user_gesture, + scoped_ptr<ListValue> event_args) { if (!profile_->IsSameProfile(profile)) return; - scoped_ptr<ListValue> args(new ListValue()); - args->Append(ExtensionTabUtil::CreateTabValueActive( - web_contents, active)); if (!extension_id.empty()) { - DispatchEventToExtension(profile, extension_id, event_name, args.Pass(), - user_gesture); + event_args->Append(ExtensionTabUtil::CreateTabValueActive( + web_contents, + active, + profile->GetExtensionService()->extensions()->GetByID(extension_id))); + DispatchEventToExtension(profile, extension_id, event_name, + event_args.Pass(), user_gesture); } else { - DispatchEvent(profile, event_name, args.Pass(), user_gesture); + const EventListenerMap::ListenerList& listeners( + ExtensionSystem::Get(profile)->event_router()-> + listeners().GetEventListenersByName(event_name)); + + for (EventListenerMap::ListenerList::const_iterator it = listeners.begin(); + it != listeners.end(); + ++it) { + scoped_ptr<ListValue> args(event_args->DeepCopy()); + args->Append(ExtensionTabUtil::CreateTabValueActive( + web_contents, + active, + profile->GetExtensionService()->extensions()->GetByID( + (*it)->extension_id))); + DispatchEventToExtension(profile, (*it)->extension_id, event_name, + args.Pass(), user_gesture); + } } } @@ -427,11 +444,10 @@ void BrowserEventRouter::DispatchTabUpdatedEvent( args->Append(changed_properties); // Third arg: An object containing the state of the tab. - args->Append(ExtensionTabUtil::CreateTabValue(contents)); - Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); - DispatchEvent(profile, events::kOnTabUpdated, args.Pass(), - EventRouter::USER_GESTURE_UNKNOWN); + + DispatchEventWithTab(profile, "", events::kOnTabUpdated, contents, true, + EventRouter::USER_GESTURE_UNKNOWN, args.Pass()); } BrowserEventRouter::TabEntry* BrowserEventRouter::GetTabEntry( diff --git a/chrome/browser/extensions/browser_event_router.h b/chrome/browser/extensions/browser_event_router.h index c9edaee..69732c2 100644 --- a/chrome/browser/extensions/browser_event_router.h +++ b/chrome/browser/extensions/browser_event_router.h @@ -127,7 +127,20 @@ class BrowserEventRouter : public TabStripModelObserver, const char* event_name, const content::WebContents* web_contents, bool active, - EventRouter::UserGestureState user_gesture); + EventRouter::UserGestureState user_gesture, + scoped_ptr<ListValue> event_args); + + // DispatchEvent with a tab value appended as the last argument. + void DispatchEventWithTab(Profile* profile, + const std::string& extension_id, + const char* event_name, + const content::WebContents* web_contents, + bool active, + EventRouter::UserGestureState user_gesture) { + DispatchEventWithTab(profile, extension_id, event_name, web_contents, + active, user_gesture, + scoped_ptr<ListValue>(new ListValue).Pass()); + } void DispatchSimpleBrowserEvent(Profile* profile, const int window_id, diff --git a/chrome/browser/extensions/browser_extension_window_controller.cc b/chrome/browser/extensions/browser_extension_window_controller.cc index 54792bc..817971d 100644 --- a/chrome/browser/extensions/browser_extension_window_controller.cc +++ b/chrome/browser/extensions/browser_extension_window_controller.cc @@ -48,10 +48,12 @@ BrowserExtensionWindowController::CreateWindowValue() const { } base::DictionaryValue* -BrowserExtensionWindowController::CreateWindowValueWithTabs() const { +BrowserExtensionWindowController::CreateWindowValueWithTabs( + const extensions::Extension* extension) const { DictionaryValue* result = CreateWindowValue(); - result->Set(keys::kTabsKey, ExtensionTabUtil::CreateTabList(browser_)); + result->Set(keys::kTabsKey, ExtensionTabUtil::CreateTabList(browser_, + extension)); return result; } diff --git a/chrome/browser/extensions/browser_extension_window_controller.h b/chrome/browser/extensions/browser_extension_window_controller.h index 9837422..a1e220a 100644 --- a/chrome/browser/extensions/browser_extension_window_controller.h +++ b/chrome/browser/extensions/browser_extension_window_controller.h @@ -9,6 +9,10 @@ class Browser; +namespace extensions { +class Extension; +} + class BrowserExtensionWindowController : public extensions::WindowController { public: explicit BrowserExtensionWindowController(Browser* browser); @@ -18,7 +22,8 @@ class BrowserExtensionWindowController : public extensions::WindowController { virtual int GetWindowId() const OVERRIDE; virtual std::string GetWindowTypeText() const OVERRIDE; virtual base::DictionaryValue* CreateWindowValue() const OVERRIDE; - virtual base::DictionaryValue* CreateWindowValueWithTabs() const OVERRIDE; + virtual base::DictionaryValue* CreateWindowValueWithTabs( + const extensions::Extension* extension) const OVERRIDE; virtual bool CanClose(Reason* reason) const OVERRIDE; virtual void SetFullscreenMode(bool is_fullscreen, const GURL& extension_url) const OVERRIDE; diff --git a/chrome/browser/extensions/event_listener_map.h b/chrome/browser/extensions/event_listener_map.h index 6c5c304..d252900 100644 --- a/chrome/browser/extensions/event_listener_map.h +++ b/chrome/browser/extensions/event_listener_map.h @@ -93,8 +93,11 @@ class EventListenerMap { bool RemoveListener(const EventListener* listener); // Returns the set of listeners that want to be notified of |event|. - std::set<const EventListener*> GetEventListeners( - const Event& event); + std::set<const EventListener*> GetEventListeners(const Event& event); + + const ListenerList& GetEventListenersByName(const std::string& event_name) { + return listeners_[event_name]; + } // Removes all listeners with process equal to |process|. void RemoveListenersForProcess(const content::RenderProcessHost* process); diff --git a/chrome/browser/extensions/event_router.cc b/chrome/browser/extensions/event_router.cc index 8be11a6..4e65e6d 100644 --- a/chrome/browser/extensions/event_router.cc +++ b/chrome/browser/extensions/event_router.cc @@ -523,9 +523,10 @@ void EventRouter::DispatchPendingEvent(const linked_ptr<Event>& event, return; if (listeners_.HasProcessListener(host->render_process_host(), - host->extension()->id())) + host->extension()->id())) { DispatchEventToProcess(host->extension()->id(), host->render_process_host(), event); + } } void EventRouter::Observe(int type, diff --git a/chrome/browser/extensions/event_router.h b/chrome/browser/extensions/event_router.h index 97d2254..891f34d 100644 --- a/chrome/browser/extensions/event_router.h +++ b/chrome/browser/extensions/event_router.h @@ -68,6 +68,8 @@ class EventRouter : public content::NotificationObserver, content::RenderProcessHost* process, const std::string& extension_id); + EventListenerMap& listeners() { return listeners_; } + // Add or remove the extension as having a lazy background page that listens // to the event. The difference from the above methods is that these will be // remembered even after the process goes away. We use this list to decide diff --git a/chrome/browser/extensions/execute_script_apitest.cc b/chrome/browser/extensions/execute_script_apitest.cc index 1edb440..c441644 100644 --- a/chrome/browser/extensions/execute_script_apitest.cc +++ b/chrome/browser/extensions/execute_script_apitest.cc @@ -36,8 +36,7 @@ IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest, ExecuteScriptPermissions) { } // If failing, mark disabled and update http://crbug.com/84760. -IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest, - ExecuteScriptFileAfterClose) { +IN_PROC_BROWSER_TEST_F(ExecuteScriptApiTest, ExecuteScriptFileAfterClose) { host_resolver()->AddRule("b.com", "127.0.0.1"); ASSERT_TRUE(StartTestServer()); ASSERT_TRUE(RunExtensionTest("executescript/file_after_close")) << message_; diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc index 8d49ea7..7af6607 100644 --- a/chrome/browser/extensions/extension_tab_util.cc +++ b/chrome/browser/extensions/extension_tab_util.cc @@ -20,6 +20,7 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_manifest_constants.h" +#include "chrome/common/extensions/permissions/api_permission.h" #include "chrome/common/url_constants.h" #include "content/public/browser/favicon_status.h" #include "content/public/browser/navigation_entry.h" @@ -30,6 +31,8 @@ namespace keys = extensions::tabs_constants; using content::NavigationEntry; using content::WebContents; +using extensions::APIPermission; +using extensions::Extension; int ExtensionTabUtil::GetWindowId(const Browser* browser) { return browser->session_id().id(); @@ -58,38 +61,49 @@ int ExtensionTabUtil::GetWindowIdOfTab(const WebContents* web_contents) { TabContents::FromWebContents(web_contents)); } -DictionaryValue* ExtensionTabUtil::CreateTabValue(const WebContents* contents) { +DictionaryValue* ExtensionTabUtil::CreateTabValue( + const WebContents* contents, + const Extension* extension) { // Find the tab strip and index of this guy. TabStripModel* tab_strip = NULL; int tab_index; - if (ExtensionTabUtil::GetTabStripModel(contents, &tab_strip, &tab_index)) - return ExtensionTabUtil::CreateTabValue(contents, tab_strip, tab_index); + if (ExtensionTabUtil::GetTabStripModel(contents, &tab_strip, &tab_index)) { + return ExtensionTabUtil::CreateTabValue(contents, + tab_strip, + tab_index, + extension); + } // Couldn't find it. This can happen if the tab is being dragged. - return ExtensionTabUtil::CreateTabValue(contents, NULL, -1); + return ExtensionTabUtil::CreateTabValue(contents, NULL, -1, extension); } -ListValue* ExtensionTabUtil::CreateTabList(const Browser* browser) { +ListValue* ExtensionTabUtil::CreateTabList( + const Browser* browser, + const Extension* extension) { ListValue* tab_list = new ListValue(); TabStripModel* tab_strip = browser->tab_strip_model(); for (int i = 0; i < tab_strip->count(); ++i) { - tab_list->Append(ExtensionTabUtil::CreateTabValue( - tab_strip->GetTabContentsAt(i)->web_contents(), tab_strip, i)); + tab_list->Append(CreateTabValue( + tab_strip->GetTabContentsAt(i)->web_contents(), + tab_strip, + i, + extension)); } return tab_list; } -DictionaryValue* ExtensionTabUtil::CreateTabValue(const WebContents* contents, - TabStripModel* tab_strip, - int tab_index) { +DictionaryValue* ExtensionTabUtil::CreateTabValue( + const WebContents* contents, + TabStripModel* tab_strip, + int tab_index, + const Extension* extension) { DictionaryValue* result = new DictionaryValue(); bool is_loading = contents->IsLoading(); - result->SetInteger(keys::kIdKey, ExtensionTabUtil::GetTabId(contents)); + result->SetInteger(keys::kIdKey, GetTabId(contents)); result->SetInteger(keys::kIndexKey, tab_index); - result->SetInteger(keys::kWindowIdKey, - ExtensionTabUtil::GetWindowIdOfTab(contents)); - result->SetString(keys::kUrlKey, contents->GetURL().spec()); + result->SetInteger(keys::kWindowIdKey, GetWindowIdOfTab(contents)); result->SetString(keys::kStatusKey, GetTabStatusText(is_loading)); result->SetBoolean(keys::kActiveKey, tab_strip && tab_index == tab_strip->active_index()); @@ -99,24 +113,42 @@ DictionaryValue* ExtensionTabUtil::CreateTabValue(const WebContents* contents, tab_strip && tab_strip->IsTabSelected(tab_index)); result->SetBoolean(keys::kPinnedKey, tab_strip && tab_strip->IsTabPinned(tab_index)); - result->SetString(keys::kTitleKey, contents->GetTitle()); result->SetBoolean(keys::kIncognitoKey, contents->GetBrowserContext()->IsOffTheRecord()); + // Only add privacy-sensitive data if the requesting extension has the tabs + // permission. + bool has_permission = false; + if (extension) { + if (tab_index >= 0) { + has_permission = + extension->HasAPIPermissionForTab( + tab_index, APIPermission::kTab) || + extension->HasAPIPermissionForTab( + tab_index, APIPermission::kWebNavigation); + } else { + has_permission = + extension->HasAPIPermission(APIPermission::kTab) || + extension->HasAPIPermission(APIPermission::kWebNavigation); + } + } + + if (has_permission) { + result->SetString(keys::kUrlKey, contents->GetURL().spec()); + result->SetString(keys::kTitleKey, contents->GetTitle()); + if (!is_loading) { + NavigationEntry* entry = contents->GetController().GetActiveEntry(); + if (entry && entry->GetFavicon().valid) + result->SetString(keys::kFaviconUrlKey, entry->GetFavicon().url.spec()); + } + } + if (tab_strip) { content::NavigationController* opener = tab_strip->GetOpenerOfTabContentsAt(tab_index); if (opener) { result->SetInteger(keys::kOpenerTabIdKey, - ExtensionTabUtil::GetTabId(opener->GetWebContents())); - } - } - - if (!is_loading) { - NavigationEntry* entry = contents->GetController().GetActiveEntry(); - if (entry) { - if (entry->GetFavicon().valid) - result->SetString(keys::kFaviconUrlKey, entry->GetFavicon().url.spec()); + GetTabId(opener->GetWebContents())); } } @@ -125,8 +157,9 @@ DictionaryValue* ExtensionTabUtil::CreateTabValue(const WebContents* contents, DictionaryValue* ExtensionTabUtil::CreateTabValueActive( const WebContents* contents, - bool active) { - DictionaryValue* result = ExtensionTabUtil::CreateTabValue(contents); + bool active, + const extensions::Extension* extension) { + DictionaryValue* result = CreateTabValue(contents, extension); result->SetBoolean(keys::kSelectedKey, active); return result; } @@ -161,7 +194,7 @@ bool ExtensionTabUtil::GetDefaultTab(Browser* browser, *contents = chrome::GetActiveTabContents(browser); if (*contents) { if (tab_id) - *tab_id = ExtensionTabUtil::GetTabId((*contents)->web_contents()); + *tab_id = GetTabId((*contents)->web_contents()); return true; } diff --git a/chrome/browser/extensions/extension_tab_util.h b/chrome/browser/extensions/extension_tab_util.h index ec87b26..0261164 100644 --- a/chrome/browser/extensions/extension_tab_util.h +++ b/chrome/browser/extensions/extension_tab_util.h @@ -42,17 +42,22 @@ class ExtensionTabUtil { static int GetTabId(const content::WebContents* web_contents); static std::string GetTabStatusText(bool is_loading); static int GetWindowIdOfTab(const content::WebContents* web_contents); - static base::ListValue* CreateTabList(const Browser* browser); + static base::ListValue* CreateTabList( + const Browser* browser, + const extensions::Extension* extension); static base::DictionaryValue* CreateTabValue( - const content::WebContents* web_contents); + const content::WebContents* web_contents, + const extensions::Extension* extension); static base::DictionaryValue* CreateTabValue( const content::WebContents* web_contents, TabStripModel* tab_strip, - int tab_index); + int tab_index, + const extensions::Extension* extension); // Create a tab value, overriding its kSelectedKey to the provided boolean. static base::DictionaryValue* CreateTabValueActive( const content::WebContents* web_contents, - bool active); + bool active, + const extensions::Extension* extension); // Gets the |tab_strip_model| and |tab_index| for the given |web_contents|. static bool GetTabStripModel(const content::WebContents* web_contents, diff --git a/chrome/browser/extensions/extension_tab_util_android.cc b/chrome/browser/extensions/extension_tab_util_android.cc index 2d8d641..2e0b51a 100644 --- a/chrome/browser/extensions/extension_tab_util_android.cc +++ b/chrome/browser/extensions/extension_tab_util_android.cc @@ -32,26 +32,33 @@ int ExtensionTabUtil::GetWindowIdOfTab(const WebContents* web_contents) { return -1; } -DictionaryValue* ExtensionTabUtil::CreateTabValue(const WebContents* contents) { +DictionaryValue* ExtensionTabUtil::CreateTabValue( + const WebContents* contents, + const extensions::Extension* extension) { NOTIMPLEMENTED(); return NULL; } -ListValue* ExtensionTabUtil::CreateTabList(const Browser* browser) { +ListValue* ExtensionTabUtil::CreateTabList( + const Browser* browser, + const extensions::Extension* extension) { NOTIMPLEMENTED(); return NULL; } -DictionaryValue* ExtensionTabUtil::CreateTabValue(const WebContents* contents, - TabStripModel* tab_strip, - int tab_index) { +DictionaryValue* ExtensionTabUtil::CreateTabValue( + const WebContents* contents, + TabStripModel* tab_strip, + int tab_index, + const extensions::Extension* extension) { NOTIMPLEMENTED(); return NULL; } DictionaryValue* ExtensionTabUtil::CreateTabValueActive( const WebContents* contents, - bool active) { + bool active, + const extensions::Extension* extension) { NOTIMPLEMENTED(); return NULL; } diff --git a/chrome/browser/extensions/extension_tabs_apitest.cc b/chrome/browser/extensions/extension_tabs_apitest.cc index f08f8ef..4c921aa 100644 --- a/chrome/browser/extensions/extension_tabs_apitest.cc +++ b/chrome/browser/extensions/extension_tabs_apitest.cc @@ -237,6 +237,5 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_GetViewsOfCreatedWindow) { } // Adding a new test? Awesome. But API tests are the old hotness. The -// new hotness is extension_test_utils. See extension_tabs_test.cc for -// an example. We are trying to phase out many uses of API tests as -// they tend to be flaky. +// new hotness is extension_test_utils. See tabs_test.cc for an example. +// We are trying to phase out many uses of API tests as they tend to be flaky. diff --git a/chrome/browser/extensions/menu_manager.cc b/chrome/browser/extensions/menu_manager.cc index 9e29835..e8d3689 100644 --- a/chrome/browser/extensions/menu_manager.cc +++ b/chrome/browser/extensions/menu_manager.cc @@ -644,7 +644,7 @@ void MenuManager::ExecuteCommand(Profile* profile, if (!extension || !extension->is_platform_app()) { // Note: web_contents only NULL in unit tests :( if (web_contents) - args->Append(ExtensionTabUtil::CreateTabValue(web_contents)); + args->Append(ExtensionTabUtil::CreateTabValue(web_contents, extension)); else args->Append(new DictionaryValue()); } diff --git a/chrome/browser/extensions/window_controller.h b/chrome/browser/extensions/window_controller.h index e6e4554..ec9f6e2 100644 --- a/chrome/browser/extensions/window_controller.h +++ b/chrome/browser/extensions/window_controller.h @@ -57,7 +57,8 @@ class WindowController { virtual base::DictionaryValue* CreateWindowValue() const; // Populates a dictionary for the Window object, including a list of tabs. - virtual base::DictionaryValue* CreateWindowValueWithTabs() const = 0; + virtual base::DictionaryValue* CreateWindowValueWithTabs( + const extensions::Extension* extension) const = 0; // Returns false if the window is in a state where closing the window is not // permitted and sets |reason| if not NULL. diff --git a/chrome/browser/ui/panels/panel.cc b/chrome/browser/ui/panels/panel.cc index af6adf1..0dac7b5 100644 --- a/chrome/browser/ui/panels/panel.cc +++ b/chrome/browser/ui/panels/panel.cc @@ -38,6 +38,10 @@ using content::RenderViewHost; using content::UserMetricsAction; +namespace extensions { +class Extension; +} + namespace panel_internal { class PanelExtensionWindowController : public extensions::WindowController { @@ -48,7 +52,8 @@ class PanelExtensionWindowController : public extensions::WindowController { // Overridden from extensions::WindowController. virtual int GetWindowId() const OVERRIDE; virtual std::string GetWindowTypeText() const OVERRIDE; - virtual base::DictionaryValue* CreateWindowValueWithTabs() const OVERRIDE; + virtual base::DictionaryValue* CreateWindowValueWithTabs( + const extensions::Extension* extension) const OVERRIDE; virtual bool CanClose(Reason* reason) const OVERRIDE; virtual void SetFullscreenMode(bool is_fullscreen, const GURL& extension_url) const OVERRIDE; @@ -80,12 +85,11 @@ std::string PanelExtensionWindowController::GetWindowTypeText() const { } base::DictionaryValue* -PanelExtensionWindowController::CreateWindowValueWithTabs() const { +PanelExtensionWindowController::CreateWindowValueWithTabs( + const extensions::Extension* extension) const { base::DictionaryValue* result = CreateWindowValue(); - // Safe to include info about the web contents as this is only called - // by the extension that owns this window. See IsVisibleToExtension(). - // TODO(jennb): DCHECK this after chebert's patch 10829186 lands. + DCHECK(IsVisibleToExtension(extension)); content::WebContents* web_contents = panel_->GetWebContents(); if (web_contents) { DictionaryValue* tab_value = new DictionaryValue(); diff --git a/chrome/browser/ui/views/ash/panel_view_aura.cc b/chrome/browser/ui/views/ash/panel_view_aura.cc index bc5346d..cda8cab 100644 --- a/chrome/browser/ui/views/ash/panel_view_aura.cc +++ b/chrome/browser/ui/views/ash/panel_view_aura.cc @@ -189,7 +189,8 @@ class PanelExtensionWindowController : public extensions::WindowController { virtual int GetWindowId() const OVERRIDE; virtual std::string GetWindowTypeText() const OVERRIDE; virtual base::DictionaryValue* CreateWindowValue() const OVERRIDE; - virtual base::DictionaryValue* CreateWindowValueWithTabs() const OVERRIDE; + virtual base::DictionaryValue* CreateWindowValueWithTabs( + const extensions::Extension* extension) const OVERRIDE; virtual bool CanClose(Reason* reason) const OVERRIDE; virtual void SetFullscreenMode(bool is_fullscreen, const GURL& extension_url) const OVERRIDE; @@ -231,7 +232,8 @@ PanelExtensionWindowController::CreateWindowValue() const { } base::DictionaryValue* -PanelExtensionWindowController::CreateWindowValueWithTabs() const { +PanelExtensionWindowController::CreateWindowValueWithTabs( + const extensions::Extension* extension) const { DictionaryValue* result = CreateWindowValue(); // TODO(stevenjb): Implement tab interface for Aura panels. |