diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-02-02 12:21:57 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-02-12 08:13:00 +0000 |
commit | 606d85f2a5386472314d39923da28c70c60dc8e7 (patch) | |
tree | a8f4d7bf997f349f45605e6058259fba0630e4d7 /chromium/chrome/browser/extensions/api/extension_action | |
parent | 5786336dda477d04fb98483dca1a5426eebde2d7 (diff) |
BASELINE: Update Chromium to 96.0.4664.181
Change-Id: I762cd1da89d73aa6313b4a753fe126c34833f046
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/chrome/browser/extensions/api/extension_action')
8 files changed, 264 insertions, 230 deletions
diff --git a/chromium/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc b/chromium/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc index 93cd9dfd4b4..064063e51fb 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc +++ b/chromium/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc @@ -8,8 +8,6 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" -#include "base/run_loop.h" -#include "base/scoped_observation.h" #include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" #include "base/test/metrics/histogram_tester.h" @@ -52,7 +50,7 @@ #include "extensions/browser/extension_action.h" #include "extensions/browser/extension_action_manager.h" #include "extensions/browser/extension_host.h" -#include "extensions/browser/extension_host_observer.h" +#include "extensions/browser/extension_host_test_helper.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/process_manager.h" @@ -65,11 +63,11 @@ #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" +#include "ui/gfx/geometry/skia_conversions.h" #include "ui/gfx/image/canvas_image_source.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/image/image_unittest_util.h" -#include "ui/gfx/skia_util.h" using content::WebContents; @@ -102,9 +100,12 @@ void VerifyIconsMatch(const gfx::Image& bar_rendering, .GetBitmap())); } +using ContextType = ExtensionBrowserTest::ContextType; + class BrowserActionApiTest : public ExtensionApiTest { public: - BrowserActionApiTest() = default; + explicit BrowserActionApiTest(ContextType context_type = ContextType::kNone) + : ExtensionApiTest(context_type) {} ~BrowserActionApiTest() override = default; BrowserActionApiTest(const BrowserActionApiTest&) = delete; BrowserActionApiTest& operator=(const BrowserActionApiTest&) = delete; @@ -149,13 +150,11 @@ class BrowserActionApiCanvasTest : public BrowserActionApiTest { } }; -using ContextType = ExtensionBrowserTest::ContextType; - class BrowserActionApiTestWithContextType : public BrowserActionApiTest, public testing::WithParamInterface<ContextType> { public: - BrowserActionApiTestWithContextType() = default; + BrowserActionApiTestWithContextType() : BrowserActionApiTest(GetParam()) {} ~BrowserActionApiTestWithContextType() override = default; BrowserActionApiTestWithContextType( const BrowserActionApiTestWithContextType&) = delete; @@ -163,17 +162,11 @@ class BrowserActionApiTestWithContextType const BrowserActionApiTestWithContextType&) = delete; protected: - const extensions::Extension* LoadExtensionWithParamOptions( - const base::FilePath& path) { - return LoadExtension(path, {.load_as_service_worker = - GetParam() == ContextType::kServiceWorker}); - } - void RunUpdateTest(base::StringPiece path, bool expect_failure) { ExtensionTestMessageListener ready_listener("ready", true); ASSERT_TRUE(embedded_test_server()->Start()); const Extension* extension = - LoadExtensionWithParamOptions(test_data_dir_.AppendASCII(path)); + LoadExtension(test_data_dir_.AppendASCII(path)); ASSERT_TRUE(extension) << message_; // Test that there is a browser action in the toolbar. ASSERT_EQ(1, GetBrowserActionsBar()->NumberOfBrowserActions()); @@ -210,7 +203,7 @@ class BrowserActionApiTestWithContextType void RunEnableTest(base::StringPiece path, bool start_enabled) { ExtensionTestMessageListener ready_listener("ready", true); const Extension* extension = - LoadExtensionWithParamOptions(test_data_dir_.AppendASCII(path)); + LoadExtension(test_data_dir_.AppendASCII(path)); ASSERT_TRUE(extension) << message_; // Test that there is a browser action in the toolbar. ASSERT_EQ(1, GetBrowserActionsBar()->NumberOfBrowserActions()); @@ -235,12 +228,6 @@ class BrowserActionApiTestWithContextType action->GetIsVisible(ExtensionAction::kDefaultTabId)); } - bool RunTest(const char* name) WARN_UNUSED_RESULT { - return RunExtensionTest( - name, {}, - {.load_as_service_worker = GetParam() == ContextType::kServiceWorker}); - } - private: base::test::ScopedFeatureList feature_list_; }; @@ -248,8 +235,8 @@ class BrowserActionApiTestWithContextType IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, Basic) { ExtensionTestMessageListener ready_listener("ready", false); ASSERT_TRUE(embedded_test_server()->Start()); - const Extension* extension = LoadExtensionWithParamOptions( - test_data_dir_.AppendASCII("browser_action/basics")); + const Extension* extension = + LoadExtension(test_data_dir_.AppendASCII("browser_action/basics")); ASSERT_TRUE(extension) << message_; // Test that there is a browser action in the toolbar. @@ -259,8 +246,8 @@ IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, Basic) { // Open a URL in the tab, so the event handler can check the tab's // "url" and "title" properties. - ui_test_utils::NavigateToURL( - browser(), embedded_test_server()->GetURL("/extensions/test_file.txt")); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), embedded_test_server()->GetURL("/extensions/test_file.txt"))); ResultCatcher catcher; // Simulate the browser action being clicked. @@ -305,8 +292,8 @@ IN_PROC_BROWSER_TEST_F(BrowserActionApiCanvasTest, DynamicBrowserAction) { // We need this on mac so we don't loose 2x representations from browser icon // in transformations gfx::ImageSkia -> NSImage -> gfx::ImageSkia. std::vector<ui::ResourceScaleFactor> supported_scale_factors; - supported_scale_factors.push_back(ui::SCALE_FACTOR_100P); - supported_scale_factors.push_back(ui::SCALE_FACTOR_200P); + supported_scale_factors.push_back(ui::k100Percent); + supported_scale_factors.push_back(ui::k200Percent); ui::SetSupportedResourceScaleFactors(supported_scale_factors); #endif @@ -541,7 +528,8 @@ IN_PROC_BROWSER_TEST_F(BrowserActionApiCanvasTest, InvisibleIconBrowserAction) { IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, TabSpecificBrowserActionState) { - ASSERT_TRUE(RunTest("browser_action/tab_specific_state")) << message_; + ASSERT_TRUE(RunExtensionTest("browser_action/tab_specific_state")) + << message_; const Extension* extension = GetSingleLoadedExtension(); ASSERT_TRUE(extension) << message_; @@ -567,14 +555,14 @@ IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, GetBrowserActionsBar()->GetTooltip(extension->id())); // Reload that tab, default title should come back. - ui_test_utils::NavigateToURL(browser(), GURL("about:blank")); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("about:blank"))); EXPECT_EQ("hi!", GetBrowserActionsBar()->GetTooltip(extension->id())); } // Test that calling chrome.browserAction.setIcon() can set the icon for // extension. IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, SetIcon) { - ASSERT_TRUE(RunTest("browser_action/set_icon")) << message_; + ASSERT_TRUE(RunExtensionTest("browser_action/set_icon")) << message_; const Extension* extension = GetSingleLoadedExtension(); ASSERT_TRUE(extension) << message_; @@ -608,7 +596,7 @@ IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, SetIcon) { // Test that calling chrome.browserAction.setPopup() can enable and change // a popup. IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, AddPopup) { - ASSERT_TRUE(RunTest("browser_action/add_popup")) << message_; + ASSERT_TRUE(RunExtensionTest("browser_action/add_popup")) << message_; const Extension* extension = GetSingleLoadedExtension(); ASSERT_TRUE(extension) << message_; @@ -647,9 +635,8 @@ IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, AddPopup) { // a page which removes the popup using chrome.browserAction.setPopup(). { ResultCatcher catcher; - ui_test_utils::NavigateToURL( - browser(), - GURL(extension->GetResourceURL("change_popup.html"))); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), GURL(extension->GetResourceURL("change_popup.html")))); ASSERT_TRUE(catcher.GetNextResult()); } @@ -664,7 +651,7 @@ IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, AddPopup) { // Test that calling chrome.browserAction.setPopup() can remove a popup. IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, RemovePopup) { // Load the extension, which has a browser action with a default popup. - ASSERT_TRUE(RunTest("browser_action/remove_popup")) << message_; + ASSERT_TRUE(RunExtensionTest("browser_action/remove_popup")) << message_; const Extension* extension = GetSingleLoadedExtension(); ASSERT_TRUE(extension) << message_; @@ -683,9 +670,8 @@ IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, RemovePopup) { // Load a page which removes the popup using chrome.browserAction.setPopup(). { ResultCatcher catcher; - ui_test_utils::NavigateToURL( - browser(), - GURL(extension->GetResourceURL("remove_popup.html"))); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), GURL(extension->GetResourceURL("remove_popup.html")))); ASSERT_TRUE(catcher.GetNextResult()); } @@ -699,8 +685,8 @@ IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, RemovePopup) { IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, IncognitoBasic) { ExtensionTestMessageListener ready_listener("ready", false); ASSERT_TRUE(embedded_test_server()->Start()); - scoped_refptr<const Extension> extension = LoadExtensionWithParamOptions( - test_data_dir_.AppendASCII("browser_action/basics")); + scoped_refptr<const Extension> extension = + LoadExtension(test_data_dir_.AppendASCII("browser_action/basics")); ASSERT_TRUE(extension) << message_; // Test that there is a browser action in the toolbar. @@ -733,9 +719,9 @@ IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, IncognitoBasic) { // Open a URL in the tab, so the event handler can check the tab's // "url" and "title" properties. - ui_test_utils::NavigateToURL( + ASSERT_TRUE(ui_test_utils::NavigateToURL( incognito_browser, - embedded_test_server()->GetURL("/extensions/test_file.txt")); + embedded_test_server()->GetURL("/extensions/test_file.txt"))); ResultCatcher catcher; // Simulate the browser action being clicked. @@ -748,8 +734,8 @@ IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, IncognitoUpdate) { ASSERT_TRUE(embedded_test_server()->Start()); ExtensionTestMessageListener incognito_not_allowed_listener( "incognito not allowed", false); - scoped_refptr<const Extension> extension = LoadExtensionWithParamOptions( - test_data_dir_.AppendASCII("browser_action/update")); + scoped_refptr<const Extension> extension = + LoadExtension(test_data_dir_.AppendASCII("browser_action/update")); ASSERT_TRUE(extension) << message_; ASSERT_TRUE(incognito_not_allowed_listener.WaitUntilSatisfied()); // Test that there is a browser action in the toolbar. @@ -807,25 +793,34 @@ IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, IncognitoUpdate) { // Tests that events are dispatched to the correct profile for split mode // extensions. -// TODO(https://crbug.com/1212866): Crashes or times out when running as a -// Service Worker-based extension. When fixed, make this a -// BrowserActionApiTestWithContextType test. -IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, IncognitoSplit) { +IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, IncognitoSplit) { + ExtensionTestMessageListener listener_ready("regular ready", false); + ExtensionTestMessageListener incognito_ready("incognito ready", false); + + // Open an incognito browser. + // Note: It is important that we create incognito profile before loading + // |extension| below. "event_page" based test fails otherwise. + Browser* incognito_browser = CreateIncognitoBrowser(browser()->profile()); + ResultCatcher catcher; const Extension* extension = LoadExtension(test_data_dir_.AppendASCII("browser_action/split_mode"), {.allow_in_incognito = true}); ASSERT_TRUE(extension) << message_; - // Open an incognito browser. - Browser* incognito_browser = CreateIncognitoBrowser(browser()->profile()); ASSERT_EQ(1, ExtensionActionTestHelper::Create(incognito_browser) ->NumberOfBrowserActions()); + // NOTE: It is necessary to ensure that browser.onClicked listener was + // registered from the extension. Otherwise SW based extension occasionally + // times out. + EXPECT_TRUE(listener_ready.WaitUntilSatisfied()); + // A click in the regular profile should open a tab in the regular profile. ExecuteExtensionAction(browser(), extension); ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); + EXPECT_TRUE(incognito_ready.WaitUntilSatisfied()); // A click in the incognito profile should open a tab in the // incognito profile. ExecuteExtensionAction(incognito_browser, extension); @@ -851,40 +846,13 @@ IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, CloseBackgroundPage) { ASSERT_EQ("", action->GetExplicitlySetBadgeText(ExtensionAction::kDefaultTabId)); - // A helper class to wait for the ExtensionHost to shut down. - // TODO(devlin): Hoist this somewhere more common and track down other similar - // usages. - class ExtensionHostDestructionObserver : public ExtensionHostObserver { - public: - explicit ExtensionHostDestructionObserver(ExtensionHost* host) { - host_observation_.Observe(host); - } - ExtensionHostDestructionObserver( - const ExtensionHostDestructionObserver& other) = delete; - ExtensionHostDestructionObserver& operator=( - const ExtensionHostDestructionObserver& other) = delete; - ~ExtensionHostDestructionObserver() override = default; - - void OnExtensionHostDestroyed(ExtensionHost* host) override { - ASSERT_TRUE(host_observation_.IsObservingSource(host)); - host_observation_.Reset(); - run_loop_.QuitWhenIdle(); - } - - void Wait() { run_loop_.Run(); } - - private: - base::RunLoop run_loop_; - base::ScopedObservation<ExtensionHost, ExtensionHostObserver> - host_observation_{this}; - }; - - ExtensionHostDestructionObserver host_destroyed_observer(extension_host); + ExtensionHostTestHelper host_destroyed_observer(profile()); + host_destroyed_observer.RestrictToHost(extension_host); // Click the browser action. ExecuteExtensionAction(browser(), extension); - host_destroyed_observer.Wait(); + host_destroyed_observer.WaitForHostDestroyed(); EXPECT_FALSE(manager->GetBackgroundHostForExtension(extension->id())); EXPECT_EQ("X", @@ -894,7 +862,7 @@ IN_PROC_BROWSER_TEST_F(BrowserActionApiTest, CloseBackgroundPage) { IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, BadgeBackgroundColor) { ASSERT_TRUE(embedded_test_server()->Start()); - ASSERT_TRUE(RunTest("browser_action/color")) << message_; + ASSERT_TRUE(RunExtensionTest("browser_action/color")) << message_; const Extension* extension = GetSingleLoadedExtension(); ASSERT_TRUE(extension) << message_; @@ -908,24 +876,24 @@ IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, // Tell the extension to update the browser action state. ResultCatcher catcher; - ui_test_utils::NavigateToURL(browser(), - GURL(extension->GetResourceURL("update.html"))); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), GURL(extension->GetResourceURL("update.html")))); ASSERT_TRUE(catcher.GetNextResult()); // Test that CSS values (#0F0) set color correctly. ASSERT_EQ(SkColorSetARGB(255, 0, 255, 0), action->GetBadgeBackgroundColor(ExtensionAction::kDefaultTabId)); - ui_test_utils::NavigateToURL(browser(), - GURL(extension->GetResourceURL("update2.html"))); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), GURL(extension->GetResourceURL("update2.html")))); ASSERT_TRUE(catcher.GetNextResult()); // Test that array values set color correctly. ASSERT_EQ(SkColorSetARGB(255, 255, 255, 255), action->GetBadgeBackgroundColor(ExtensionAction::kDefaultTabId)); - ui_test_utils::NavigateToURL(browser(), - GURL(extension->GetResourceURL("update3.html"))); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), GURL(extension->GetResourceURL("update3.html")))); ASSERT_TRUE(catcher.GetNextResult()); // Test that hsl() values 'hsl(120, 100%, 50%)' set color correctly. @@ -933,8 +901,8 @@ IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, action->GetBadgeBackgroundColor(ExtensionAction::kDefaultTabId)); // Test basic color keyword set correctly. - ui_test_utils::NavigateToURL(browser(), - GURL(extension->GetResourceURL("update4.html"))); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), GURL(extension->GetResourceURL("update4.html")))); ASSERT_TRUE(catcher.GetNextResult()); ASSERT_EQ(SkColorSetARGB(255, 0, 0, 255), @@ -942,7 +910,7 @@ IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, } IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, Getters) { - ASSERT_TRUE(RunTest("browser_action/getters")) << message_; + ASSERT_TRUE(RunExtensionTest("browser_action/getters")) << message_; const Extension* extension = GetSingleLoadedExtension(); ASSERT_TRUE(extension) << message_; @@ -951,13 +919,13 @@ IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, Getters) { // Test the getters for defaults. ResultCatcher catcher; - ui_test_utils::NavigateToURL(browser(), - GURL(extension->GetResourceURL("update.html"))); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), GURL(extension->GetResourceURL("update.html")))); ASSERT_TRUE(catcher.GetNextResult()); // Test the getters for a specific tab. - ui_test_utils::NavigateToURL(browser(), - GURL(extension->GetResourceURL("update2.html"))); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), GURL(extension->GetResourceURL("update2.html")))); ASSERT_TRUE(catcher.GetNextResult()); } @@ -966,15 +934,15 @@ IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, TestTriggerBrowserAction) { ASSERT_TRUE(embedded_test_server()->Start()); - ASSERT_TRUE(RunTest("trigger_actions/browser_action")) << message_; + ASSERT_TRUE(RunExtensionTest("trigger_actions/browser_action")) << message_; const Extension* extension = GetSingleLoadedExtension(); ASSERT_TRUE(extension) << message_; // Test that there is a browser action in the toolbar. ASSERT_EQ(1, GetBrowserActionsBar()->NumberOfBrowserActions()); - ui_test_utils::NavigateToURL(browser(), - embedded_test_server()->GetURL("/simple.html")); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), embedded_test_server()->GetURL("/simple.html"))); ExtensionAction* browser_action = GetBrowserAction(browser(), *extension); EXPECT_TRUE(browser_action); @@ -1003,7 +971,7 @@ IN_PROC_BROWSER_TEST_P(BrowserActionApiTestWithContextType, WithRectangularIcon) { ExtensionTestMessageListener ready_listener("ready", true); - const Extension* extension = LoadExtensionWithParamOptions( + const Extension* extension = LoadExtension( test_data_dir_.AppendASCII("browser_action").AppendASCII("rect_icon")); ASSERT_TRUE(extension); EXPECT_TRUE(ready_listener.WaitUntilSatisfied()); diff --git a/chromium/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc b/chromium/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc index 2d7dc883530..6bb6ddcc3b0 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc +++ b/chromium/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc @@ -5,6 +5,7 @@ #include <memory> #include "base/run_loop.h" +#include "base/scoped_observation.h" #include "base/test/test_timeouts.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" @@ -34,8 +35,9 @@ #include "extensions/browser/extension_action.h" #include "extensions/browser/extension_action_manager.h" #include "extensions/browser/extension_host.h" +#include "extensions/browser/extension_host_registry.h" +#include "extensions/browser/extension_host_test_helper.h" #include "extensions/browser/extension_registry.h" -#include "extensions/browser/notification_types.h" #include "extensions/common/extension.h" #include "extensions/common/extension_set.h" #include "extensions/common/mojom/view_type.mojom.h" @@ -59,18 +61,20 @@ namespace { // Helper to ensure all extension hosts are destroyed during the test. If a host // is still alive, the Profile can not be destroyed in -// BrowserProcessImpl::StartTearDown(). TODO(tapted): The existence of this -// helper is probably a bug. Extension hosts do not currently block shutdown the -// way a browser tab does. Maybe they should. See http://crbug.com/729476. -class PopupHostWatcher : public content::NotificationObserver { +// BrowserProcessImpl::StartTearDown(). +// TODO(tapted): The existence of this helper is probably a bug. Extension +// hosts do not currently block shutdown the way a browser tab does. Maybe they +// should. See http://crbug.com/729476. +class PopupHostWatcher : public ExtensionHostRegistry::Observer { public: - PopupHostWatcher() { - registrar_.Add(this, NOTIFICATION_EXTENSION_HOST_CREATED, - content::NotificationService::AllSources()); - registrar_.Add(this, NOTIFICATION_EXTENSION_HOST_DESTROYED, - content::NotificationService::AllSources()); + explicit PopupHostWatcher(content::BrowserContext* browser_context) { + host_registry_observation_.Observe( + ExtensionHostRegistry::Get(browser_context)); } + PopupHostWatcher(const PopupHostWatcher&) = delete; + PopupHostWatcher& operator=(const PopupHostWatcher&) = delete; + void Wait() { if (created_ == destroyed_) return; @@ -85,29 +89,40 @@ class PopupHostWatcher : public content::NotificationObserver { int created() const { return created_; } int destroyed() const { return destroyed_; } - // NotificationObserver: - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override { + // ExtensionHostRegistry::Observer: + void OnExtensionHostRenderProcessReady( + content::BrowserContext* browser_context, + ExtensionHost* host) override { + // Only track lifetimes for popup window ExtensionHost instances. + if (host->extension_host_type() != mojom::ViewType::kExtensionPopup) + return; + + ++created_; + QuitIfSatisfied(); + } + + void OnExtensionHostDestroyed(content::BrowserContext* browser_context, + ExtensionHost* host) override { // Only track lifetimes for popup window ExtensionHost instances. - const ExtensionHost* host = - content::Details<const ExtensionHost>(details).ptr(); - DCHECK(host); if (host->extension_host_type() != mojom::ViewType::kExtensionPopup) return; - ++(type == NOTIFICATION_EXTENSION_HOST_CREATED ? created_ : destroyed_); + ++destroyed_; + QuitIfSatisfied(); + } + + private: + void QuitIfSatisfied() { if (!quit_closure_.is_null() && created_ == destroyed_) quit_closure_.Run(); } - private: - content::NotificationRegistrar registrar_; base::RepeatingClosure quit_closure_; int created_ = 0; int destroyed_ = 0; - - DISALLOW_COPY_AND_ASSIGN(PopupHostWatcher); + base::ScopedObservation<ExtensionHostRegistry, + ExtensionHostRegistry::Observer> + host_registry_observation_{this}; }; // chrome.browserAction API tests that interact with the UI in such a way that @@ -116,12 +131,17 @@ class PopupHostWatcher : public content::NotificationObserver { class BrowserActionInteractiveTest : public ExtensionApiTest { public: BrowserActionInteractiveTest() {} + + BrowserActionInteractiveTest(const BrowserActionInteractiveTest&) = delete; + BrowserActionInteractiveTest& operator=(const BrowserActionInteractiveTest&) = + delete; + ~BrowserActionInteractiveTest() override {} // BrowserTestBase: void SetUpOnMainThread() override { - host_watcher_ = std::make_unique<PopupHostWatcher>(); ExtensionApiTest::SetUpOnMainThread(); + host_watcher_ = std::make_unique<PopupHostWatcher>(profile()); host_resolver()->AddRule("*", "127.0.0.1"); EXPECT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); } @@ -131,9 +151,11 @@ class BrowserActionInteractiveTest : public ExtensionApiTest { // called after this. But relying on the window close to close the // extension host can cause flakes. See http://crbug.com/729476. // Waiting here requires individual tests to ensure their popup has closed. - ExtensionApiTest::TearDownOnMainThread(); host_watcher_->Wait(); EXPECT_EQ(host_watcher_->created(), host_watcher_->destroyed()); + // Destroy the PopupHostWatcher to ensure it stops watching the profile. + host_watcher_.reset(); + ExtensionApiTest::TearDownOnMainThread(); } protected: @@ -191,9 +213,8 @@ class BrowserActionInteractiveTest : public ExtensionApiTest { // Trigger a focus loss to close the popup. void ClosePopupViaFocusLoss() { EXPECT_TRUE(ExtensionActionTestHelper::Create(browser())->HasPopup()); - content::WindowedNotificationObserver observer( - extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, - content::NotificationService::AllSources()); + + ExtensionHostTestHelper host_helper(profile()); #if defined(OS_MAC) // ClickOnView() in an inactive window is not robust on Mac. The click does @@ -213,7 +234,7 @@ class BrowserActionInteractiveTest : public ExtensionApiTest { // Wait for the notification to achieve a consistent state and verify that // the popup was properly torn down. - observer.Wait(); + host_helper.WaitForHostDestroyed(); base::RunLoop().RunUntilIdle(); } @@ -221,8 +242,6 @@ class BrowserActionInteractiveTest : public ExtensionApiTest { private: std::unique_ptr<PopupHostWatcher> host_watcher_; - - DISALLOW_COPY_AND_ASSIGN(BrowserActionInteractiveTest); }; // Tests opening a popup using the chrome.browserAction.openPopup API. This test @@ -390,13 +409,11 @@ IN_PROC_BROWSER_TEST_F(BrowserActionInteractiveTest, TabSwitchClosesPopup) { browser()->tab_strip_model()->GetActiveWebContents()); OpenPopupViaAPI(false); - content::WindowedNotificationObserver observer( - extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, - content::NotificationService::AllSources()); + ExtensionHostTestHelper host_helper(profile()); // Change active tabs, the extension popup should close. browser()->tab_strip_model()->ActivateTabAt( 0, {TabStripModel::GestureType::kOther}); - observer.Wait(); + host_helper.WaitForHostDestroyed(); EXPECT_FALSE(ExtensionActionTestHelper::Create(browser())->HasPopup()); } @@ -430,8 +447,8 @@ IN_PROC_BROWSER_TEST_F(BrowserActionInteractiveTest, PopupZoomsIndependently) { ASSERT_TRUE(extension) << message_; // Navigate to one of the extension's pages in a tab. - ui_test_utils::NavigateToURL(browser(), - extension->GetResourceURL("popup.html")); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), extension->GetResourceURL("popup.html"))); content::WebContents* tab_contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -448,13 +465,10 @@ IN_PROC_BROWSER_TEST_F(BrowserActionInteractiveTest, PopupZoomsIndependently) { zoom_change_watcher.Wait(); // Open the extension's popup. - content::WindowedNotificationObserver popup_observer( - NOTIFICATION_EXTENSION_HOST_CREATED, - content::NotificationService::AllSources()); + ExtensionHostTestHelper host_helper(profile(), extension->id()); OpenPopupViaToolbar(extension->id()); - popup_observer.Wait(); - ExtensionHost* extension_host = - content::Details<ExtensionHost>(popup_observer.details()).ptr(); + ExtensionHost* extension_host = host_helper.WaitForRenderProcessReady(); + ASSERT_TRUE(extension_host); content::WebContents* popup_contents = extension_host->host_contents(); // The popup should not use the per-origin zoom level that was set by zooming @@ -494,10 +508,13 @@ IN_PROC_BROWSER_TEST_F(BrowserActionInteractiveTest, PopupZoomsIndependently) { class BrowserActionInteractiveViewsTest : public BrowserActionInteractiveTest { public: BrowserActionInteractiveViewsTest() = default; - ~BrowserActionInteractiveViewsTest() override = default; - private: - DISALLOW_COPY_AND_ASSIGN(BrowserActionInteractiveViewsTest); + BrowserActionInteractiveViewsTest(const BrowserActionInteractiveViewsTest&) = + delete; + BrowserActionInteractiveViewsTest& operator=( + const BrowserActionInteractiveViewsTest&) = delete; + + ~BrowserActionInteractiveViewsTest() override = default; }; // Test closing the browser while inspecting an extension popup with dev tools. @@ -573,7 +590,13 @@ class MainFrameSizeWaiter : public content::WebContentsObserver { base::RunLoop run_loop_; }; -IN_PROC_BROWSER_TEST_F(BrowserActionInteractiveTest, BrowserActionPopup) { +// TODO(crbug.com/1249851): Test crashes on Windows +#if defined(OS_WIN) +#define MAYBE_BrowserActionPopup DISABLED_BrowserActionPopup +#else +#define MAYBE_BrowserActionPopup BrowserActionPopup +#endif +IN_PROC_BROWSER_TEST_F(BrowserActionInteractiveTest, MAYBE_BrowserActionPopup) { ASSERT_TRUE( LoadExtension(test_data_dir_.AppendASCII("browser_action/popup"))); const Extension* extension = GetSingleLoadedExtension(); diff --git a/chromium/chrome/browser/extensions/api/extension_action/extension_action_api.cc b/chromium/chrome/browser/extensions/api/extension_action/extension_action_api.cc index 6463c89b6e4..7b30965ec9d 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/extension_action_api.cc +++ b/chromium/chrome/browser/extensions/api/extension_action/extension_action_api.cc @@ -30,7 +30,6 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/toolbar/toolbar_actions_model.h" #include "components/sessions/content/session_tab_helper.h" -#include "content/public/browser/notification_service.h" #include "extensions/browser/api/declarative_net_request/constants.h" #include "extensions/browser/api/declarative_net_request/utils.h" #include "extensions/browser/event_router.h" @@ -39,7 +38,6 @@ #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_util.h" -#include "extensions/browser/notification_types.h" #include "extensions/common/api/extension_action/action_info.h" #include "extensions/common/error_utils.h" #include "extensions/common/feature_switch.h" @@ -283,18 +281,19 @@ bool ExtensionActionFunction::ExtractDataFromArguments() { // The tabId might appear in details (if it exists), as the first // argument besides the action type (depends on the function), or be omitted // entirely. - base::Value* first_arg = NULL; - if (!args_->Get(0, &first_arg)) + if (args().empty()) return true; - switch (first_arg->type()) { + base::Value& first_arg = mutable_args()[0]; + + switch (first_arg.type()) { case base::Value::Type::INTEGER: - tab_id_ = first_arg->GetInt(); + tab_id_ = first_arg.GetInt(); break; case base::Value::Type::DICTIONARY: { // Found the details argument. - details_ = static_cast<base::DictionaryValue*>(first_arg); + details_ = static_cast<base::DictionaryValue*>(&first_arg); // Still need to check for the tabId within details. base::Value* tab_id_value = NULL; if (details_->Get("tabId", &tab_id_value)) { @@ -540,10 +539,10 @@ ExtensionFunction::ResponseAction ExtensionActionGetBadgeBackgroundColorFunction::RunExtensionAction() { std::unique_ptr<base::ListValue> list(new base::ListValue()); SkColor color = extension_action_->GetBadgeBackgroundColor(tab_id_); - list->AppendInteger(static_cast<int>(SkColorGetR(color))); - list->AppendInteger(static_cast<int>(SkColorGetG(color))); - list->AppendInteger(static_cast<int>(SkColorGetB(color))); - list->AppendInteger(static_cast<int>(SkColorGetA(color))); + list->Append(static_cast<int>(SkColorGetR(color))); + list->Append(static_cast<int>(SkColorGetG(color))); + list->Append(static_cast<int>(SkColorGetB(color))); + list->Append(static_cast<int>(SkColorGetA(color))); return RespondNow( OneArgument(base::Value::FromUniquePtrValue(std::move(list)))); } @@ -577,6 +576,7 @@ ExtensionFunction::ResponseAction ActionGetUserSettingsFunction::Run() { } BrowserActionOpenPopupFunction::BrowserActionOpenPopupFunction() = default; +BrowserActionOpenPopupFunction::~BrowserActionOpenPopupFunction() = default; ExtensionFunction::ResponseAction BrowserActionOpenPopupFunction::Run() { // We only allow the popup in the active window. @@ -608,8 +608,7 @@ ExtensionFunction::ResponseAction BrowserActionOpenPopupFunction::Run() { // If the extension is spanning, then extension hosts are created with the // original profile, and if it's split, then we know the api call came from // the right profile. - registrar_.Add(this, NOTIFICATION_EXTENSION_HOST_DID_STOP_FIRST_LOAD, - content::Source<Profile>(profile)); + host_registry_observation_.Observe(ExtensionHostRegistry::Get(profile)); // Set a timeout for waiting for the notification that the popup is loaded. // Waiting is required so that the popup view can be retrieved by the custom @@ -618,10 +617,19 @@ ExtensionFunction::ResponseAction BrowserActionOpenPopupFunction::Run() { base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::BindOnce(&BrowserActionOpenPopupFunction::OpenPopupTimedOut, this), - base::TimeDelta::FromSeconds(10)); + base::Seconds(10)); return RespondLater(); } +void BrowserActionOpenPopupFunction::OnBrowserContextShutdown() { + // No point in responding at this point (the context is gone). However, we + // need to explicitly remove the ExtensionHostRegistry observation, since the + // ExtensionHostRegistry's lifetime is tied to the BrowserContext. Otherwise, + // this would cause a UAF when the observation is destructed as part of this + // instance's destruction. + host_registry_observation_.Reset(); +} + void BrowserActionOpenPopupFunction::OpenPopupTimedOut() { if (did_respond()) return; @@ -630,21 +638,18 @@ void BrowserActionOpenPopupFunction::OpenPopupTimedOut() { Respond(Error(kOpenPopupError)); } -void BrowserActionOpenPopupFunction::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - DCHECK_EQ(NOTIFICATION_EXTENSION_HOST_DID_STOP_FIRST_LOAD, type); +void BrowserActionOpenPopupFunction::OnExtensionHostCompletedFirstLoad( + content::BrowserContext* browser_context, + ExtensionHost* host) { if (did_respond()) return; - ExtensionHost* host = content::Details<ExtensionHost>(details).ptr(); if (host->extension_host_type() != mojom::ViewType::kExtensionPopup || host->extension()->id() != extension_->id()) return; Respond(NoArguments()); - registrar_.RemoveAll(); + host_registry_observation_.Reset(); } } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/extension_action/extension_action_api.h b/chromium/chrome/browser/extensions/api/extension_action/extension_action_api.h index 1fa5f9d74eb..501ed8759b8 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/extension_action_api.h +++ b/chromium/chrome/browser/extensions/api/extension_action/extension_action_api.h @@ -9,12 +9,12 @@ #include "base/macros.h" #include "base/observer_list.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" +#include "base/scoped_observation.h" #include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/extension_action.h" #include "extensions/browser/extension_event_histogram_value.h" #include "extensions/browser/extension_function.h" +#include "extensions/browser/extension_host_registry.h" #include "third_party/skia/include/core/SkColor.h" namespace base { @@ -29,6 +29,7 @@ class WebContents; class Browser; namespace extensions { +class ExtensionHost; class ExtensionPrefs; class ExtensionActionAPI : public BrowserContextKeyedAPI { @@ -55,6 +56,10 @@ class ExtensionActionAPI : public BrowserContextKeyedAPI { }; explicit ExtensionActionAPI(content::BrowserContext* context); + + ExtensionActionAPI(const ExtensionActionAPI&) = delete; + ExtensionActionAPI& operator=(const ExtensionActionAPI&) = delete; + ~ExtensionActionAPI() override; // Convenience method to get the instance for a profile. @@ -112,8 +117,6 @@ class ExtensionActionAPI : public BrowserContextKeyedAPI { content::BrowserContext* browser_context_; ExtensionPrefs* extension_prefs_; - - DISALLOW_COPY_AND_ASSIGN(ExtensionActionAPI); }; // Implementation of the browserAction and pageAction APIs. @@ -454,26 +457,34 @@ class BrowserActionDisableFunction : public ExtensionActionHideFunction { }; class BrowserActionOpenPopupFunction : public ExtensionFunction, - public content::NotificationObserver { + public ExtensionHostRegistry::Observer { public: DECLARE_EXTENSION_FUNCTION("browserAction.openPopup", BROWSERACTION_OPEN_POPUP) BrowserActionOpenPopupFunction(); + BrowserActionOpenPopupFunction(const BrowserActionOpenPopupFunction&) = + delete; + BrowserActionOpenPopupFunction& operator=( + const BrowserActionOpenPopupFunction&) = delete; + private: - ~BrowserActionOpenPopupFunction() override {} + ~BrowserActionOpenPopupFunction() override; // ExtensionFunction: ResponseAction Run() override; + void OnBrowserContextShutdown() override; - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; - void OpenPopupTimedOut(); + // ExtensionHostRegistry::Observer: + void OnExtensionHostCompletedFirstLoad( + content::BrowserContext* browser_context, + ExtensionHost* host) override; - content::NotificationRegistrar registrar_; + void OpenPopupTimedOut(); - DISALLOW_COPY_AND_ASSIGN(BrowserActionOpenPopupFunction); + base::ScopedObservation<ExtensionHostRegistry, + ExtensionHostRegistry::Observer> + host_registry_observation_{this}; }; } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc b/chromium/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc index 408ae9e0781..58715e01eb3 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc +++ b/chromium/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc @@ -12,6 +12,7 @@ #include "base/strings/strcat.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" #include "chrome/browser/extensions/api/extension_action/test_extension_action_api_observer.h" #include "chrome/browser/extensions/api/extension_action/test_icon_image_observer.h" #include "chrome/browser/extensions/extension_apitest.h" @@ -46,11 +47,16 @@ namespace { // A background script that allows for setting the icon dynamically. constexpr char kSetIconBackgroundJsTemplate[] = R"(function setIcon(details) { - chrome.%s.setIcon(details, () => { - chrome.test.assertNoLastError(); - chrome.test.notifyPass(); - }); - })"; + chrome.%s.setIcon(details, () => { + chrome.test.assertNoLastError(); + chrome.test.notifyPass(); + }); + } + function setIconPromise(details) { + chrome.%s.setIcon(details) + .then(chrome.test.notifyPass) + .catch(chrome.test.notifyFail); + })"; constexpr char kPageHtmlTemplate[] = R"(<html><script src="page.js"></script></html>)"; @@ -74,6 +80,10 @@ class TestStateStoreObserver : public StateStore::TestObserver { : extension_id_(extension_id) { scoped_observation_.Observe(ExtensionSystem::Get(context)->state_store()); } + + TestStateStoreObserver(const TestStateStoreObserver&) = delete; + TestStateStoreObserver& operator=(const TestStateStoreObserver&) = delete; + ~TestStateStoreObserver() override {} void WillSetExtensionValue(const std::string& extension_id, @@ -93,8 +103,6 @@ class TestStateStoreObserver : public StateStore::TestObserver { base::ScopedObservation<StateStore, StateStore::TestObserver> scoped_observation_{this}; - - DISALLOW_COPY_AND_ASSIGN(TestStateStoreObserver); }; // A helper class to handle setting or getting the values for an action from JS. @@ -110,6 +118,10 @@ class ActionTestHelper { get_method_name_(get_method_name), js_property_key_(js_property_key), web_contents_(web_contents) {} + + ActionTestHelper(const ActionTestHelper&) = delete; + ActionTestHelper& operator=(const ActionTestHelper&) = delete; + ~ActionTestHelper() = default; // Checks the value for the given |tab_id|. @@ -176,8 +188,6 @@ class ActionTestHelper { const char* const js_property_key_; // The WebContents to use to execute API calls. content::WebContents* const web_contents_; - - DISALLOW_COPY_AND_ASSIGN(ActionTestHelper); }; // Forces a flush of the StateStore, where action state is persisted. @@ -369,7 +379,7 @@ IN_PROC_BROWSER_TEST_P(MultiActionAPITest, // Navigating should clear the title. GURL second_url = embedded_test_server()->GetURL("/title2.html"); - ui_test_utils::NavigateToURL(browser(), second_url); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), second_url)); EXPECT_EQ(second_url, web_contents->GetLastCommittedURL()); EXPECT_FALSE(action->HasTitle(tab_id)); @@ -549,8 +559,16 @@ IN_PROC_BROWSER_TEST_P(MultiActionAPITest, PopupCreation) { // Tests that sessionStorage does not persist between closing and opening of a // popup. +// TODO(crbug/1256760): Flaky on Linux. +#if defined(OS_LINUX) +#define MAYBE_SessionStorageDoesNotPersistBetweenOpenings \ + DISABLED_SessionStorageDoesNotPersistBetweenOpenings +#else +#define MAYBE_SessionStorageDoesNotPersistBetweenOpenings \ + SessionStorageDoesNotPersistBetweenOpenings +#endif IN_PROC_BROWSER_TEST_P(MultiActionAPITest, - SessionStorageDoesNotPersistBetweenOpenings) { + MAYBE_SessionStorageDoesNotPersistBetweenOpenings) { constexpr char kManifestTemplate[] = R"({ "name": "Test sessionStorage", @@ -741,6 +759,7 @@ IN_PROC_BROWSER_TEST_P(MultiActionAPICanvasTest, DynamicSetIcon) { test_dir.WriteFile(FILE_PATH_LITERAL("page.html"), kPageHtmlTemplate); test_dir.WriteFile(FILE_PATH_LITERAL("page.js"), base::StringPrintf(kSetIconBackgroundJsTemplate, + GetAPINameForActionType(GetParam()), GetAPINameForActionType(GetParam()))); test_dir.CopyFileTo(test_data_dir_.AppendASCII("icon_rgb_0_0_255.png"), FILE_PATH_LITERAL("blue_icon.png")); @@ -834,6 +853,19 @@ IN_PROC_BROWSER_TEST_P(MultiActionAPICanvasTest, DynamicSetIcon) { EXPECT_FALSE(new_tab_icon.IsEmpty()); EXPECT_EQ(SK_ColorGREEN, new_tab_icon.AsBitmap().getColor(mid_x, mid_y)); + // Manifest V3 extensions using the action API should also be able to use a + // promise version of setIcon. + if (GetManifestVersionForActionType(GetParam()) == 3) { + constexpr char kSetIconPromiseScript[] = + "setIconPromise({tabId: %d, path: 'blue_icon.png'});"; + RunTestAndWaitForSuccess( + web_contents, base::StringPrintf(kSetIconPromiseScript, new_tab_id)); + + new_tab_icon = toolbar_helper->GetIcon(extension->id()); + EXPECT_FALSE(new_tab_icon.IsEmpty()); + EXPECT_EQ(SK_ColorBLUE, new_tab_icon.AsBitmap().getColor(mid_x, mid_y)); + } + // Switch back to the first tab. The icon should still be red, since the other // changes were for specific tabs. browser()->tab_strip_model()->ActivateTabAt(0); @@ -864,6 +896,7 @@ IN_PROC_BROWSER_TEST_P(MultiActionAPITest, SetIconWithJavascriptHooks) { test_dir.WriteFile(FILE_PATH_LITERAL("page.html"), kPageHtmlTemplate); test_dir.WriteFile(FILE_PATH_LITERAL("page.js"), base::StringPrintf(kSetIconBackgroundJsTemplate, + GetAPINameForActionType(GetParam()), GetAPINameForActionType(GetParam()))); test_dir.CopyFileTo(test_data_dir_.AppendASCII("icon_rgb_0_0_255.png"), FILE_PATH_LITERAL("blue_icon.png")); @@ -934,6 +967,7 @@ IN_PROC_BROWSER_TEST_P(MultiActionAPITest, SetIconWithSelfDefined) { test_dir.WriteFile(FILE_PATH_LITERAL("page.html"), kPageHtmlTemplate); test_dir.WriteFile(FILE_PATH_LITERAL("page.js"), base::StringPrintf(kSetIconBackgroundJsTemplate, + GetAPINameForActionType(GetParam()), GetAPINameForActionType(GetParam()))); test_dir.CopyFileTo(test_data_dir_.AppendASCII("icon_rgb_0_0_255.png"), FILE_PATH_LITERAL("blue_icon.png")); diff --git a/chromium/chrome/browser/extensions/api/extension_action/page_action_apitest.cc b/chromium/chrome/browser/extensions/api/extension_action/page_action_apitest.cc index 002338fa762..7c8ef6f371e 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/page_action_apitest.cc +++ b/chromium/chrome/browser/extensions/api/extension_action/page_action_apitest.cc @@ -36,7 +36,7 @@ using ContextType = ExtensionBrowserTest::ContextType; class PageActionApiTest : public ExtensionApiTest, public testing::WithParamInterface<ContextType> { public: - PageActionApiTest() = default; + PageActionApiTest() : ExtensionApiTest(GetParam()) {} ~PageActionApiTest() override = default; PageActionApiTest(const PageActionApiTest&) = delete; PageActionApiTest& operator=(const PageActionApiTest&) = delete; @@ -50,12 +50,6 @@ class PageActionApiTest : public ExtensionApiTest, ? extension_action : nullptr; } - - bool RunTest(const char* name) { - return RunExtensionTest( - name, {}, - {.load_as_service_worker = GetParam() == ContextType::kServiceWorker}); - } }; INSTANTIATE_TEST_SUITE_P(PersistentBackground, @@ -67,14 +61,14 @@ INSTANTIATE_TEST_SUITE_P(ServiceWorker, IN_PROC_BROWSER_TEST_P(PageActionApiTest, Basic) { ASSERT_TRUE(embedded_test_server()->Start()); - ASSERT_TRUE(RunTest("page_action/basics")) << message_; + ASSERT_TRUE(RunExtensionTest("page_action/basics")) << message_; const Extension* extension = GetSingleLoadedExtension(); ASSERT_TRUE(extension) << message_; { // Tell the extension to update the page action state. ResultCatcher catcher; - ui_test_utils::NavigateToURL(browser(), - GURL(extension->GetResourceURL("update.html"))); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), GURL(extension->GetResourceURL("update.html")))); ASSERT_TRUE(catcher.GetNextResult()); } @@ -99,8 +93,8 @@ IN_PROC_BROWSER_TEST_P(PageActionApiTest, Basic) { { // Tell the extension to update the page action state again. ResultCatcher catcher; - ui_test_utils::NavigateToURL(browser(), - GURL(extension->GetResourceURL("update2.html"))); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), GURL(extension->GetResourceURL("update2.html")))); ASSERT_TRUE(catcher.GetNextResult()); } @@ -119,7 +113,7 @@ IN_PROC_BROWSER_TEST_P(PageActionApiTest, Basic) { // Test that calling chrome.pageAction.setPopup() can enable a popup. IN_PROC_BROWSER_TEST_P(PageActionApiTest, AddPopup) { // Load the extension, which has no default popup. - ASSERT_TRUE(RunTest("page_action/add_popup")) << message_; + ASSERT_TRUE(RunExtensionTest("page_action/add_popup")) << message_; const Extension* extension = GetSingleLoadedExtension(); ASSERT_TRUE(extension) << message_; @@ -152,9 +146,8 @@ IN_PROC_BROWSER_TEST_P(PageActionApiTest, AddPopup) { // Load a page which removes the popup using chrome.pageAction.setPopup(). { ResultCatcher catcher; - ui_test_utils::NavigateToURL( - browser(), - GURL(extension->GetResourceURL("change_popup.html"))); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), GURL(extension->GetResourceURL("change_popup.html")))); ASSERT_TRUE(catcher.GetNextResult()); } @@ -166,7 +159,7 @@ IN_PROC_BROWSER_TEST_P(PageActionApiTest, AddPopup) { // Test that calling chrome.pageAction.setPopup() can remove a popup. IN_PROC_BROWSER_TEST_P(PageActionApiTest, RemovePopup) { // Load the extension, which has a page action with a default popup. - ASSERT_TRUE(RunTest("page_action/remove_popup")) << message_; + ASSERT_TRUE(RunExtensionTest("page_action/remove_popup")) << message_; const Extension* extension = GetSingleLoadedExtension(); ASSERT_TRUE(extension) << message_; @@ -183,9 +176,8 @@ IN_PROC_BROWSER_TEST_P(PageActionApiTest, RemovePopup) { // Load a page which removes the popup using chrome.pageAction.setPopup(). { ResultCatcher catcher; - ui_test_utils::NavigateToURL( - browser(), - GURL(extension->GetResourceURL("remove_popup.html"))); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), GURL(extension->GetResourceURL("remove_popup.html")))); ASSERT_TRUE(catcher.GetNextResult()); } @@ -196,29 +188,24 @@ IN_PROC_BROWSER_TEST_P(PageActionApiTest, RemovePopup) { // Test http://crbug.com/57333: that two page action extensions using the same // icon for the page action icon and the extension icon do not crash. IN_PROC_BROWSER_TEST_P(PageActionApiTest, TestCrash57333) { - const bool load_as_service_worker = GetParam() == ContextType::kServiceWorker; // Load extension A. - ASSERT_TRUE( - LoadExtension(test_data_dir_.AppendASCII("page_action") - .AppendASCII("crash_57333") - .AppendASCII("Extension1"), - {.load_as_service_worker = load_as_service_worker})); + ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("page_action") + .AppendASCII("crash_57333") + .AppendASCII("Extension1"))); // Load extension B. - ASSERT_TRUE( - LoadExtension(test_data_dir_.AppendASCII("page_action") - .AppendASCII("crash_57333") - .AppendASCII("Extension2"), - {.load_as_service_worker = load_as_service_worker})); + ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("page_action") + .AppendASCII("crash_57333") + .AppendASCII("Extension2"))); } IN_PROC_BROWSER_TEST_P(PageActionApiTest, Getters) { - ASSERT_TRUE(RunTest("page_action/getters")) << message_; + ASSERT_TRUE(RunExtensionTest("page_action/getters")) << message_; const Extension* extension = GetSingleLoadedExtension(); ASSERT_TRUE(extension) << message_; ResultCatcher catcher; - ui_test_utils::NavigateToURL(browser(), - GURL(extension->GetResourceURL("update.html"))); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), GURL(extension->GetResourceURL("update.html")))); ASSERT_TRUE(catcher.GetNextResult()); } @@ -226,13 +213,13 @@ IN_PROC_BROWSER_TEST_P(PageActionApiTest, Getters) { IN_PROC_BROWSER_TEST_P(PageActionApiTest, TestTriggerPageAction) { ASSERT_TRUE(embedded_test_server()->Start()); - ASSERT_TRUE(RunTest("trigger_actions/page_action")) << message_; + ASSERT_TRUE(RunExtensionTest("trigger_actions/page_action")) << message_; const Extension* extension = GetSingleLoadedExtension(); ASSERT_TRUE(extension) << message_; // Page action icon is displayed when a tab is created. - ui_test_utils::NavigateToURL(browser(), - embedded_test_server()->GetURL("/simple.html")); + ASSERT_TRUE(ui_test_utils::NavigateToURL( + browser(), embedded_test_server()->GetURL("/simple.html"))); chrome::NewTab(browser()); browser()->tab_strip_model()->ActivateTabAt( 0, {TabStripModel::GestureType::kOther}); diff --git a/chromium/chrome/browser/extensions/api/extension_action/test_extension_action_api_observer.h b/chromium/chrome/browser/extensions/api/extension_action/test_extension_action_api_observer.h index e2423448cf2..e55d1afec29 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/test_extension_action_api_observer.h +++ b/chromium/chrome/browser/extensions/api/extension_action/test_extension_action_api_observer.h @@ -29,6 +29,12 @@ class TestExtensionActionAPIObserver : public ExtensionActionAPI::Observer { content::BrowserContext* context, const ExtensionId& extension_id, const std::set<content::WebContents*>& contents_to_observe); + + TestExtensionActionAPIObserver(const TestExtensionActionAPIObserver&) = + delete; + TestExtensionActionAPIObserver& operator=( + const TestExtensionActionAPIObserver&) = delete; + ~TestExtensionActionAPIObserver() override; // Waits until the extension action is updated and the update is seen for all @@ -57,8 +63,6 @@ class TestExtensionActionAPIObserver : public ExtensionActionAPI::Observer { // An optional set of web contents to observe for extension action updates. std::set<content::WebContents*> contents_to_observe_; - - DISALLOW_COPY_AND_ASSIGN(TestExtensionActionAPIObserver); }; } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/extension_action/test_icon_image_observer.h b/chromium/chrome/browser/extensions/api/extension_action/test_icon_image_observer.h index 310eef3c44f..172f11e66f6 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/test_icon_image_observer.h +++ b/chromium/chrome/browser/extensions/api/extension_action/test_icon_image_observer.h @@ -19,6 +19,10 @@ class Extension; class TestIconImageObserver : public IconImage::Observer { public: TestIconImageObserver(); + + TestIconImageObserver(const TestIconImageObserver&) = delete; + TestIconImageObserver& operator=(const TestIconImageObserver&) = delete; + ~TestIconImageObserver() override; void Wait(IconImage* icon); @@ -33,8 +37,6 @@ class TestIconImageObserver : public IconImage::Observer { base::RunLoop run_loop_; base::ScopedObservation<IconImage, IconImage::Observer> observation_{this}; - - DISALLOW_COPY_AND_ASSIGN(TestIconImageObserver); }; } // namespace extensions |