diff options
18 files changed, 190 insertions, 92 deletions
diff --git a/chrome/browser/extensions/extension_browser_event_router.cc b/chrome/browser/extensions/extension_browser_event_router.cc index 3bd807a..c7a5b33 100644 --- a/chrome/browser/extensions/extension_browser_event_router.cc +++ b/chrome/browser/extensions/extension_browser_event_router.cc @@ -329,6 +329,7 @@ void ExtensionBrowserEventRouter::TabChangedAt(TabContents* contents, void ExtensionBrowserEventRouter::TabStripEmpty() { } void ExtensionBrowserEventRouter::PageActionExecuted(Profile* profile, + std::string extension_id, std::string page_action_id, int tab_id, std::string url) { @@ -346,5 +347,6 @@ void ExtensionBrowserEventRouter::PageActionExecuted(Profile* profile, std::string json_args; JSONWriter::Write(&args, false, &json_args); - DispatchEvent(profile, events::kOnPageActionExecuted, json_args); + std::string event_name = extension_id + std::string("/") + page_action_id; + DispatchEvent(profile, event_name.c_str(), json_args); } diff --git a/chrome/browser/extensions/extension_browser_event_router.h b/chrome/browser/extensions/extension_browser_event_router.h index 0cfd075..d2f7613 100644 --- a/chrome/browser/extensions/extension_browser_event_router.h +++ b/chrome/browser/extensions/extension_browser_event_router.h @@ -50,6 +50,7 @@ class ExtensionBrowserEventRouter : public TabStripModelObserver, // PageActions. void PageActionExecuted(Profile* profile, + std::string extension_id, std::string page_action_id, int tab_id, std::string url); diff --git a/chrome/browser/extensions/extension_event_names.cc b/chrome/browser/extensions/extension_event_names.cc index f4fd6e7..214d37b 100644 --- a/chrome/browser/extensions/extension_event_names.cc +++ b/chrome/browser/extensions/extension_event_names.cc @@ -6,7 +6,6 @@ namespace extension_event_names { -const char kOnPageActionExecuted[] = "page-action-executed"; const char kOnTabAttached[] = "tab-attached"; const char kOnTabCreated[] = "tab-created"; const char kOnTabDetached[] = "tab-detached"; diff --git a/chrome/browser/extensions/extension_event_names.h b/chrome/browser/extensions/extension_event_names.h index 9b9e3f2..3e3673a 100644 --- a/chrome/browser/extensions/extension_event_names.h +++ b/chrome/browser/extensions/extension_event_names.h @@ -9,7 +9,6 @@ namespace extension_event_names { -extern const char kOnPageActionExecuted[]; extern const char kOnTabAttached[]; extern const char kOnTabCreated[]; extern const char kOnTabDetached[]; diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index 8238595..43aca30 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -13,6 +13,7 @@ #include "chrome/browser/extensions/extension_message_service.h" #include "chrome/browser/extensions/extension_page_actions_module.h" #include "chrome/browser/extensions/extension_page_actions_module_constants.h" +#include "chrome/browser/extensions/extension_process_manager.h" #include "chrome/browser/extensions/extension_tabs_module.h" #include "chrome/browser/extensions/extension_tabs_module_constants.h" #include "chrome/browser/profile.h" @@ -188,6 +189,11 @@ ExtensionFunctionDispatcher::ExtensionFunctionDispatcher( // Ensure the message service is initialized. ExtensionMessageService::GetInstance(profile()->GetRequestContext())->Init(); + + // Notify the ExtensionProcessManager that the view was created. + ExtensionProcessManager* epm = profile()->GetExtensionProcessManager(); + epm->RegisterExtensionProcess(extension_id(), + render_view_host->process()->pid()); } ExtensionFunctionDispatcher::~ExtensionFunctionDispatcher() { diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc index 4c2047b..3018ea8 100644 --- a/chrome/browser/extensions/extension_process_manager.cc +++ b/chrome/browser/extensions/extension_process_manager.cc @@ -9,9 +9,11 @@ #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/site_instance.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/notification_service.h" #include "chrome/common/notification_type.h" +#include "chrome/common/render_messages.h" static void CreateBackgroundHosts( ExtensionProcessManager* manager, const ExtensionList* extensions) { @@ -33,6 +35,10 @@ ExtensionProcessManager::ExtensionProcessManager(Profile* profile) NotificationService::AllSources()); registrar_.Add(this, NotificationType::EXTENSION_HOST_DESTROYED, Source<Profile>(profile)); + registrar_.Add(this, NotificationType::RENDERER_PROCESS_TERMINATED, + NotificationService::AllSources()); + registrar_.Add(this, NotificationType::RENDERER_PROCESS_CLOSED, + NotificationService::AllSources()); } ExtensionProcessManager::~ExtensionProcessManager() { @@ -78,6 +84,39 @@ ExtensionHost* ExtensionProcessManager::CreateBackgroundHost( return host; } +void ExtensionProcessManager::RegisterExtensionProcess( + std::string extension_id, int process_id) { + ProcessIDMap::const_iterator it = process_ids_.find(extension_id); + if (it != process_ids_.end() && (*it).second == process_id) + return; + + process_ids_[extension_id] = process_id; + + ExtensionsService* extension_service = + browsing_instance_->profile()->GetExtensionsService(); + + std::vector<std::string> page_action_ids; + Extension* extension = extension_service->GetExtensionById(extension_id); + for (PageActionMap::const_iterator i = extension->page_actions().begin(); + i != extension->page_actions().end(); ++i) { + page_action_ids.push_back(i->first); + } + + RenderProcessHost* rph = RenderProcessHost::FromID(process_id); + rph->Send(new ViewMsg_Extension_UpdatePageActions(extension_id, + page_action_ids)); +} + +void ExtensionProcessManager::UnregisterExtensionProcess(int process_id) { + ProcessIDMap::iterator it = process_ids_.begin(); + while (it != process_ids_.end()) { + if (it->second == process_id) + process_ids_.erase(it++); + else + ++it; + } +} + SiteInstance* ExtensionProcessManager::GetSiteInstanceForURL(const GURL& url) { return browsing_instance_->GetSiteInstanceForURL(url); } @@ -122,6 +161,13 @@ void ExtensionProcessManager::Observe(NotificationType type, break; } + case NotificationType::RENDERER_PROCESS_TERMINATED: + case NotificationType::RENDERER_PROCESS_CLOSED: { + RenderProcessHost* host = Source<RenderProcessHost>(source).ptr(); + UnregisterExtensionProcess(host->pid()); + break; + } + default: NOTREACHED(); } diff --git a/chrome/browser/extensions/extension_process_manager.h b/chrome/browser/extensions/extension_process_manager.h index 58f6639..e3d6b76 100644 --- a/chrome/browser/extensions/extension_process_manager.h +++ b/chrome/browser/extensions/extension_process_manager.h @@ -5,7 +5,9 @@ #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_PROCESS_MANAGER_H_ #define CHROME_BROWSER_EXTENSIONS_EXTENSION_PROCESS_MANAGER_H_ +#include <map> #include <set> +#include <string> #include "base/ref_counted.h" #include "chrome/common/notification_registrar.h" @@ -43,6 +45,13 @@ class ExtensionProcessManager : public NotificationObserver { // Returns the SiteInstance that the given URL belongs to. SiteInstance* GetSiteInstanceForURL(const GURL& url); + // Register an extension process by |extension_id| and specifying which + // |process_id| it belongs to. + void RegisterExtensionProcess(std::string extension_id, int process_id); + + // Unregister an extension process with specified |process_id|. + void UnregisterExtensionProcess(int process_id); + // NotificationObserver: virtual void Observe(NotificationType type, const NotificationSource& source, @@ -69,6 +78,10 @@ class ExtensionProcessManager : public NotificationObserver { // controls process grouping. scoped_refptr<BrowsingInstance> browsing_instance_; + // A map of extension ID to the render_process_id that the extension lives in. + typedef std::map<std::string, int> ProcessIDMap; + ProcessIDMap process_ids_; + DISALLOW_COPY_AND_ASSIGN(ExtensionProcessManager); }; diff --git a/chrome/browser/views/location_bar_view.cc b/chrome/browser/views/location_bar_view.cc index eb6d629..d92b5b4 100644 --- a/chrome/browser/views/location_bar_view.cc +++ b/chrome/browser/views/location_bar_view.cc @@ -1277,7 +1277,8 @@ bool LocationBarView::PageActionImageView::OnMousePressed( const views::MouseEvent& event) { // Our PageAction icon was clicked on, notify proper authorities. ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted( - profile_, page_action_->id(), current_tab_id_, current_url_.spec()); + profile_, page_action_->extension_id(), page_action_->id(), + current_tab_id_, current_url_.spec()); return true; } diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 5410091..e28eb51 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -562,6 +562,12 @@ IPC_BEGIN_MESSAGES(View) IPC_MESSAGE_CONTROL1(ViewMsg_Extension_SetFunctionNames, std::vector<std::string>) + // Tell the renderer process all known page action ids for a particular + // extension. + IPC_MESSAGE_CONTROL2(ViewMsg_Extension_UpdatePageActions, + std::string /* extension_id */, + std::vector<std::string> /* page_action_ids */) + // Changes the text direction of a selected input field. // * direction (int) // Represents the new text direction. diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc index e68fb82..49b12b9 100644 --- a/chrome/renderer/extensions/extension_process_bindings.cc +++ b/chrome/renderer/extensions/extension_process_bindings.cc @@ -25,6 +25,9 @@ using bindings_utils::ExtensionBase; namespace { +// A map of extension ID to vector of page action ids. +typedef std::map< std::string, std::vector<std::string> > PageActionIdMap; + const char kExtensionName[] = "chrome/ExtensionProcessBindings"; const char* kExtensionDeps[] = { BaseJsV8Extension::kName, @@ -35,12 +38,17 @@ const char* kExtensionDeps[] = { struct SingletonData { std::set<std::string> function_names_; + PageActionIdMap page_action_ids_; }; static std::set<std::string>* GetFunctionNameSet() { return &Singleton<SingletonData>()->function_names_; } +static PageActionIdMap* GetPageActionMap() { + return &Singleton<SingletonData>()->page_action_ids_; +} + class ExtensionImpl : public ExtensionBase { public: ExtensionImpl() : ExtensionBase( @@ -62,6 +70,8 @@ class ExtensionImpl : public ExtensionBase { return v8::FunctionTemplate::New(GetViews); } else if (name->Equals(v8::String::New("GetNextRequestId"))) { return v8::FunctionTemplate::New(GetNextRequestId); + } else if (name->Equals(v8::String::New("GetCurrentPageActions"))) { + return v8::FunctionTemplate::New(GetCurrentPageActions); } else if (names->find(*v8::String::AsciiValue(name)) != names->end()) { return v8::FunctionTemplate::New(StartRequest, name); } @@ -70,11 +80,15 @@ class ExtensionImpl : public ExtensionBase { } private: - static v8::Handle<v8::Value> GetViews(const v8::Arguments& args) { + static std::string ExtensionIdFromCurrentContext() { RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext(); DCHECK(renderview); GURL url = renderview->webview()->GetMainFrame()->GetURL(); - std::string extension_id = url.host(); + return url.host(); + } + + static v8::Handle<v8::Value> GetViews(const v8::Arguments& args) { + std::string extension_id = ExtensionIdFromCurrentContext(); ContextList contexts = bindings_utils::GetContextsForExtension(extension_id); @@ -97,7 +111,30 @@ class ExtensionImpl : public ExtensionBase { static int next_request_id = 0; return v8::Integer::New(next_request_id++); } - + + static v8::Handle<v8::Value> GetCurrentPageActions( + const v8::Arguments& args) { + std::string extension_id = ExtensionIdFromCurrentContext(); + PageActionIdMap* page_action_map = GetPageActionMap(); + PageActionIdMap::const_iterator it = page_action_map->find(extension_id); + + const std::vector<std::string>* page_actions = NULL; + size_t size = 0; + if (it != page_action_map->end()) { + page_actions = &it->second; + size = page_actions->size(); + } + + v8::Local<v8::Array> page_action_array = v8::Array::New(size); + for (size_t i = 0; i < size; ++i) { + const std::string& page_action_id = (*page_actions)[i]; + page_action_array->Set(v8::Integer::New(i), + v8::String::New(page_action_id.c_str())); + } + + return page_action_array; + } + // Starts an API request to the browser, with an optional callback. The // callback will be dispatched to EventBindings::HandleResponse. static v8::Handle<v8::Value> StartRequest(const v8::Arguments& args) { @@ -159,3 +196,16 @@ void ExtensionProcessBindings::HandleResponse(int request_id, bool success, GetPendingRequestMap().erase(request_id); } + +// static +void ExtensionProcessBindings::SetPageActions( + const std::string& extension_id, + const std::vector<std::string>& page_actions) { + PageActionIdMap& page_action_map = *GetPageActionMap(); + if (!page_actions.empty()) { + page_action_map[extension_id] = page_actions; + } else { + if (page_action_map.find(extension_id) != page_action_map.end()) + page_action_map.erase(extension_id); + } +} diff --git a/chrome/renderer/extensions/extension_process_bindings.h b/chrome/renderer/extensions/extension_process_bindings.h index 9e2c814..1ce6b47 100644 --- a/chrome/renderer/extensions/extension_process_bindings.h +++ b/chrome/renderer/extensions/extension_process_bindings.h @@ -7,6 +7,7 @@ #ifndef CHROME_RENDERER_EXTENSIONS_EXTENSION_PROCESS_BINDINGS_H_ #define CHROME_RENDERER_EXTENSIONS_EXTENSION_PROCESS_BINDINGS_H_ +#include <map> #include <string> #include <vector> @@ -21,6 +22,10 @@ class ExtensionProcessBindings { static void HandleResponse(int request_id, bool success, const std::string& response, const std::string& error); + + // Sets the page action ids for a particular extension. + static void SetPageActions(const std::string& extension_id, + const std::vector<std::string>& page_actions); }; #endif // CHROME_RENDERER_EXTENSIONS_EXTENSION_PROCESS_BINDINGS_H_ diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index 16b4d45..3debfac 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -214,6 +214,12 @@ void RenderThread::OnSetExtensionFunctionNames( ExtensionProcessBindings::SetFunctionNames(names); } +void RenderThread::OnPageActionsUpdated( + const std::string& extension_id, + const std::vector<std::string>& page_actions) { + ExtensionProcessBindings::SetPageActions(extension_id, page_actions); +} + void RenderThread::OnControlMessageReceived(const IPC::Message& msg) { // App cache messages are handled by a delegate. if (app_cache_dispatcher_->OnMessageReceived(msg)) @@ -242,6 +248,8 @@ void RenderThread::OnControlMessageReceived(const IPC::Message& msg) { OnSetExtensionFunctionNames) IPC_MESSAGE_HANDLER(ViewMsg_PurgePluginListCache, OnPurgePluginListCache) + IPC_MESSAGE_HANDLER(ViewMsg_Extension_UpdatePageActions, + OnPageActionsUpdated) IPC_END_MESSAGE_MAP() } diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h index 733887e..5ced914 100644 --- a/chrome/renderer/render_thread.h +++ b/chrome/renderer/render_thread.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -70,7 +70,7 @@ class RenderThread : public RenderThreadBase, // be accessed when running on the render thread itself static RenderThread* current(); - // Overridded from RenderThreadBase. + // Overridden from RenderThreadBase. virtual bool Send(IPC::Message* msg) { return ChildThread::Send(msg); } @@ -114,7 +114,7 @@ class RenderThread : public RenderThreadBase, private: virtual void OnControlMessageReceived(const IPC::Message& msg); - // Called by the thread base class + // Called by the thread base class. virtual void Init(); virtual void CleanUp(); @@ -124,6 +124,8 @@ class RenderThread : public RenderThreadBase, void OnUpdateUserScripts(base::SharedMemoryHandle table); void OnSetExtensionFunctionNames(const std::vector<std::string>& names); + void OnPageActionsUpdated(const std::string& extension_id, + const std::vector<std::string>& page_actions); void OnSetNextPageID(int32 next_page_id); void OnCreateNewView(gfx::NativeViewId parent_hwnd, ModalDialogEvent modal_dialog_event, diff --git a/chrome/renderer/renderer_resources.grd b/chrome/renderer/renderer_resources.grd index bdba06d..fe9b91e 100644 --- a/chrome/renderer/renderer_resources.grd +++ b/chrome/renderer/renderer_resources.grd @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- This comment is only here because changes to resources are not picked up -without changes to the corresponding grd file. mp1 --> +without changes to the corresponding grd file. Zorglub1 --> <grit latest_public_release="0" current_release="1"> <outputs> <output filename="grit/renderer_resources.h" type="rc_header"> diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js index 1c8fc9c4..e0dba27 100644 --- a/chrome/renderer/resources/extension_process_bindings.js +++ b/chrome/renderer/resources/extension_process_bindings.js @@ -30,6 +30,7 @@ var chrome = chrome || {}; native function GetTabLanguage(); native function EnablePageAction(); native function DisablePageAction(); + native function GetCurrentPageActions(); native function GetBookmarks(); native function GetBookmarkChildren(); native function GetBookmarkTree(); @@ -397,9 +398,16 @@ var chrome = chrome || {}; } ]; - // Sends ({pageActionId, tabId, tabUrl}). - chrome.pageActions.onExecute = - new chrome.Event("page-action-executed"); + // Page action events send (pageActionId, {tabId, tabUrl}). + function setupPageActionEvents(extensionId) { + var pageActions = GetCurrentPageActions(); + var eventName = ""; + for (var i = 0; i < pageActions.length; ++i) { + eventName = extensionId + "/" + pageActions[i]; + // Setup events for each extension_id/page_action_id string we find. + chrome.pageActions[pageActions[i]] = new chrome.Event(eventName); + } + } //---------------------------------------------------------------------------- // Bookmarks @@ -548,6 +556,8 @@ var chrome = chrome || {}; // TODO(mpcomplete): self.onConnect is deprecated. Remove it at 1.0. // http://code.google.com/p/chromium/issues/detail?id=16356 chrome.self.onConnect = new chrome.Event("channel-connect:" + extensionId); + + setupPageActionEvents(extensionId); }); chrome.self.getViews = function() { diff --git a/chrome/test/data/extensions/samples/subscribe_page_action/background.html b/chrome/test/data/extensions/samples/subscribe_page_action/background.html index 94761ff..4d14440 100644 --- a/chrome/test/data/extensions/samples/subscribe_page_action/background.html +++ b/chrome/test/data/extensions/samples/subscribe_page_action/background.html @@ -4,53 +4,14 @@ // The Page Action ID. var pageActionId = "RssPageAction"; - // The icons to use. These correspond to the icons listed in the manifest. + // The icon to use. This corresponds to the icon listed in the manifest. var subscribeId = 0; - var alreadySubscribedId = 1; - // The window this Page Action is associated with. - var windowId = -1; - - // The TabId this Page Action is associated with. - var tabId = -1; - - // The URL of the page that contains the feed. - var pageUrl = ""; - - // The feed URL found on the page. - var feedUrl = ""; - - // The URL to use to check if user is subscribed already. - var subscribedUrl = "http://www.google.com/reader/api/0/subscribed?s=feed%2F"; - - // The XMLHttpRequest object that checks if you are already subscribed. - var req; - - // The status of whether you have already subscribed to this feed or not. - var alreadySubscribed = false; - - function EnableIcon(subscribed) { - alreadySubscribed = subscribed; - if (!alreadySubscribed) { - chrome.pageActions.enableForTab( - pageActionId, {tabId: tabId, - url: pageUrl, - title: "Click to subscribe...", - iconId: subscribeId}); - } else { - chrome.pageActions.enableForTab( - pageActionId, {tabId: tabId, - url: pageUrl, - title: "You are already subscribed to this feed", - iconId: alreadySubscribedId}); - } - } + // A dictionary keyed off of tabId that keeps track of data per tab (for + // example what feedUrl was detected in the tab). + var feedData = {}; chrome.self.onConnect.addListener(function(port) { - windowId = port.tab.windowId; - tabId = port.tab.id; - pageUrl = port.tab.url; - // This will get called from the content script using PostMessage. // |feedUrls| is a list of URL feeds found on the page. We only need 1 to // enable the PageAction icon in the Omnibox. @@ -59,49 +20,39 @@ // Let Chrome know that the PageAction needs to be enabled for this tabId // and for the url of this page. if (feedUrl) { - EnableIcon(false); // Not subscribed (as far as we know, might change). - - // But also check the server to see if we have already subscribed so - // that we can update the status. - feedUrl = encodeURIComponent(feedUrl); - req = new XMLHttpRequest(); - req.onload = handleResponse; - req.open("GET", subscribedUrl + feedUrl, false); - req.send(null); + feedData[port.tab.id] = {pageUrl: port.tab.url, + feedUrl: feedUrl}; + + chrome.pageActions.enableForTab( + pageActionId, {tabId: port.tab.id, + url: port.tab.url, + title: "Click to subscribe...", + iconId: subscribeId}); } }); }); - function handleResponse() { - if (req.responseText == "true") - EnableIcon(true); // true == Already suscribed. - } - // Chrome will call into us when the user clicks on the icon in the OmniBox. - chrome.pageActions.onExecute.addListener(function(reply) { + chrome.pageActions["RssPageAction"].addListener(function(reply) { chrome.windows.getCurrent(function(window) { chrome.tabs.get(reply.data.tabId, function(tab) { - if (!alreadySubscribed && window.focused) { - // We need to know if we are the active window, because the tab may - // have moved to another window and we don't want to execute this - // action multiple times. - if (reply.pageActionId == pageActionId && - reply.data.tabUrl == pageUrl) { - // Create a new tab showing the subscription page with the right - // feed URL. - chrome.tabs.create({url: "subscribe.html?" + feedUrl, - windowId: windowId}); - } else { - console.log("Ignoring execute event."); - console.log("PageActionId: " + reply.pageActionId + " == " + - pageActionId); - console.log("TabUrl : " + reply.data.tabUrl + " == " + - pageUrl); - } + // We need to know if we are the active window, because the tab may + // have moved to another window and we don't want to execute this + // action multiple times. + if (window.focused) { + // Create a new tab showing the subscription page with the right + // feed URL. + chrome.tabs.create({url: "subscribe.html?" + + feedData[reply.data.tabId].feedUrl, + windowId: window.windowId}); } }); }); }); + + chrome.tabs.onRemoved.addListener(function(reply) { + feedData[reply.tabId] = null; + }); </script> </head> </html> diff --git a/chrome/test/data/extensions/samples/subscribe_page_action/feed-icon-16x16-subscribed.png b/chrome/test/data/extensions/samples/subscribe_page_action/feed-icon-16x16-subscribed.png Binary files differdeleted file mode 100644 index 0369a6b37..0000000 --- a/chrome/test/data/extensions/samples/subscribe_page_action/feed-icon-16x16-subscribed.png +++ /dev/null diff --git a/chrome/test/data/extensions/samples/subscribe_page_action/manifest.json b/chrome/test/data/extensions/samples/subscribe_page_action/manifest.json index 5807816..7adaf8f 100644 --- a/chrome/test/data/extensions/samples/subscribe_page_action/manifest.json +++ b/chrome/test/data/extensions/samples/subscribe_page_action/manifest.json @@ -17,8 +17,7 @@ "id": "RssPageAction", "name": "Subscribe to this feed", "icons": [ - "feed-icon-16x16.png", - "feed-icon-16x16-subscribed.png" + "feed-icon-16x16.png" ] } ] |