// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <memory>

#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/test/metrics/histogram_tester.h"
#include "chrome/browser/extensions/extension_action_dispatcher.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "components/sessions/content/session_tab_helper.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "extensions/browser/api/file_system/file_system_api.h"
#include "extensions/browser/background_script_executor.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_action.h"
#include "extensions/browser/extension_action_manager.h"
#include "extensions/browser/extension_function_histogram_value.h"
#include "extensions/browser/extension_host_test_helper.h"
#include "extensions/browser/extension_util.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/script_result_queue.h"
#include "extensions/common/extension_features.h"
#include "extensions/common/mojom/view_type.mojom.h"
#include "extensions/common/switches.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h"
#include "extensions/test/test_extension_dir.h"
#include "net/dns/mock_host_resolver.h"

namespace extensions {

namespace {

// A script that can verify whether a developer-mode-restricted API is
// available. Note that we use separate verify methods here (as opposed to
// a boolean "is API available") so we can better verify expected errors and
// give more meaningful messages in the case of failure.
constexpr char kCheckApiAvailability[] =
    R"(
       async function verifyApiIsAvailable() {
         let message;
         try {
           const tabs = await chrome.tabs.query({});
           chrome.test.assertEq(1, tabs.length);
           const debuggee = {tabId: tabs[0].id};
           await chrome.debugger.attach(debuggee, '1.3');
           await chrome.debugger.detach(debuggee);
           message = 'success';
         } catch (e) {
           message = 'Unexpected error: ' + e.toString();
         }
         chrome.test.sendScriptResult(message);
       }

       async function verifyApiIsNotAvailable() {
         let message;
         try {
           // Note: we try to call a method on the API (and not just test
           // accessing it) since, if it was previously instantiated when the
           // API was available, it would still be present.
           await chrome.debugger.getTargets();
           message = 'API unexpectedly available.';
         } catch(e) {
           const expectedError =
               `Error: Failed to read the 'debugger' property from ` +
               `'Object': The 'debugger' API is only available for users ` +
               'in developer mode.';
           message = e.toString() == expectedError
               ? 'success'
               : 'Unexpected error: ' + e.toString();
         }
         chrome.test.sendScriptResult(message);
       })";

constexpr char kCheckApiAvailabilityUserScripts[] =
    R"(const script =
           {
             id: 'script',
             matches: ['*://*/*'],
             js: [{file: 'script.js'}]
           };
       async function verifyApiIsAvailable() {
         let message;
         try {
           await chrome.userScripts.register([script]);
           const registered = await chrome.userScripts.getScripts();
           message =
               (registered.length == 1 &&
                registered[0].id == 'script')
                   ? 'success'
                   : 'Unexpected registration result: ' +
                         JSON.stringify(registered);
           await chrome.userScripts.unregister();
         } catch (e) {
           message = 'Unexpected error: ' + e.toString();
         }
         chrome.test.sendScriptResult(message);
       }

       async function verifyApiIsNotAvailable() {
         let message;
         try {
           // Note: we try to call a method on the API (and not just test
           // accessing it) since, if it was previously instantiated when the
           // API was available, it would still be present.
           await chrome.userScripts.register([script]);
           message = 'API unexpectedly available.';
           await chrome.userScripts.unregister();
         } catch(e) {
           const expectedError =
               `Error: Failed to read the 'userScripts' property from ` +
               `'Object': The 'userScripts' API is only available for users ` +
               'in developer mode.';
           message = e.toString() == expectedError
               ? 'success'
               : 'Unexpected error: ' + e.toString();
         }
         chrome.test.sendScriptResult(message);
       })";

bool ApiExists(content::WebContents* web_contents,
               const std::string& api_name) {
  return content::EvalJs(web_contents,
                         base::StringPrintf("!!%s;", api_name.c_str()))
      .ExtractBool();
}

bool ObjectIsDefined(content::WebContents* web_contents,
                     const std::string& object_name) {
  return content::EvalJs(web_contents,
                         base::StringPrintf("self.hasOwnProperty('%s');",
                                            object_name.c_str()))
      .ExtractBool();
}

}  // namespace

// And end-to-end test for extension APIs using native bindings.
class NativeBindingsApiTest : public ExtensionApiTest {
 public:
  NativeBindingsApiTest() = default;

  NativeBindingsApiTest(const NativeBindingsApiTest&) = delete;
  NativeBindingsApiTest& operator=(const NativeBindingsApiTest&) = delete;

  ~NativeBindingsApiTest() override = default;

  void SetUpCommandLine(base::CommandLine* command_line) override {
    ExtensionApiTest::SetUpCommandLine(command_line);
    // We allowlist the extension so that it can use the cast.streaming.* APIs,
    // which are the only APIs that are prefixed twice.
    command_line->AppendSwitchASCII(switches::kAllowlistedExtensionID,
                                    "ddchlicdkolnonkihahngkmmmjnjlkkf");
  }

  void SetUpOnMainThread() override {
    ExtensionApiTest::SetUpOnMainThread();
    host_resolver()->AddRule("*", "127.0.0.1");
  }
};

IN_PROC_BROWSER_TEST_F(NativeBindingsApiTest, SimpleEndToEndTest) {
  embedded_test_server()->ServeFilesFromDirectory(test_data_dir_);
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(RunExtensionTest("native_bindings/extension")) << message_;
}

// A simplistic app test for app-specific APIs.
IN_PROC_BROWSER_TEST_F(NativeBindingsApiTest, SimpleAppTest) {
  ExtensionTestMessageListener ready_listener("ready",
                                              ReplyBehavior::kWillReply);
  ASSERT_TRUE(RunExtensionTest("native_bindings/platform_app",
                               {.launch_as_platform_app = true}))
      << message_;
  ASSERT_TRUE(ready_listener.WaitUntilSatisfied());

  // On reply, the extension will try to close the app window and send a
  // message.
  ExtensionTestMessageListener close_listener;
  ready_listener.Reply(std::string());
  ASSERT_TRUE(close_listener.WaitUntilSatisfied());
  EXPECT_EQ("success", close_listener.message());
}

// Tests the declarativeContent API and declarative events.
IN_PROC_BROWSER_TEST_F(NativeBindingsApiTest, DeclarativeEvents) {
  embedded_test_server()->ServeFilesFromDirectory(test_data_dir_);
  ASSERT_TRUE(StartEmbeddedTestServer());
  // Load an extension. On load, this extension will a) run a few simple tests
  // using chrome.test.runTests() and b) set up rules for declarative events for
  // a browser-driven test. Wait for both the tests to finish and the extension
  // to be ready.
  ExtensionTestMessageListener listener("ready");
  ResultCatcher catcher;
  const Extension* extension = LoadExtension(
      test_data_dir_.AppendASCII("native_bindings/declarative_content"));
  ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
  ASSERT_TRUE(extension);
  ASSERT_TRUE(listener.WaitUntilSatisfied());

  // The extension's page action should currently be hidden.
  ExtensionAction* action =
      ExtensionActionManager::Get(profile())->GetExtensionAction(*extension);
  content::WebContents* web_contents = GetActiveWebContents();
  int tab_id = sessions::SessionTabHelper::IdForTab(web_contents).id();
  EXPECT_FALSE(action->GetIsVisible(tab_id));
  EXPECT_TRUE(action->GetDeclarativeIcon(tab_id).IsEmpty());

  // Navigating to example.com should show the page action.
  ASSERT_TRUE(NavigateToURL(
      web_contents, embedded_test_server()->GetURL(
                        "example.com", "/native_bindings/simple.html")));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(action->GetIsVisible(tab_id));
  EXPECT_FALSE(action->GetDeclarativeIcon(tab_id).IsEmpty());

  // And the extension should be notified of the click.
  ExtensionTestMessageListener clicked_listener("clicked and removed");
  ExtensionActionDispatcher::Get(profile())->DispatchExtensionActionClicked(
      *action, web_contents, extension);
  ASSERT_TRUE(clicked_listener.WaitUntilSatisfied());
}

IN_PROC_BROWSER_TEST_F(NativeBindingsApiTest, LazyListeners) {
  ProcessManager::SetEventPageIdleTimeForTesting(1);
  ProcessManager::SetEventPageSuspendingTimeForTesting(1);

  ExtensionHostTestHelper background_page_done(profile());
  background_page_done.RestrictToType(
      mojom::ViewType::kExtensionBackgroundPage);
  const Extension* extension = LoadExtension(
      test_data_dir_.AppendASCII("native_bindings/lazy_listeners"));
  ASSERT_TRUE(extension);
  // Wait for the event page to cycle.
  background_page_done.WaitForDocumentElementAvailable();
  background_page_done.WaitForHostDestroyed();

  EventRouter* event_router = EventRouter::Get(profile());
  EXPECT_TRUE(event_router->ExtensionHasEventListener(extension->id(),
                                                      "tabs.onCreated"));
}

// End-to-end test for the fileSystem API, which includes parameters with
// instance-of requirements and a post-validation argument updater that violates
// the schema.
IN_PROC_BROWSER_TEST_F(NativeBindingsApiTest, FileSystemApiGetDisplayPath) {
  base::FilePath test_dir = test_data_dir_.AppendASCII("native_bindings");
  FileSystemChooseEntryFunction::RegisterTempExternalFileSystemForTest(
      "test_root", test_dir);
  base::FilePath test_file = test_dir.AppendASCII("text.txt");
  const FileSystemChooseEntryFunction::TestOptions test_options{
      .path_to_be_picked = &test_file};
  auto reset_options =
      FileSystemChooseEntryFunction::SetOptionsForTesting(test_options);
  ASSERT_TRUE(RunExtensionTest("native_bindings/instance_of",
                               {.launch_as_platform_app = true}))
      << message_;
}

// Tests the webRequest API, which requires IO thread requests and custom
// events.
IN_PROC_BROWSER_TEST_F(NativeBindingsApiTest, WebRequest) {
  embedded_test_server()->ServeFilesFromDirectory(test_data_dir_);
  ASSERT_TRUE(StartEmbeddedTestServer());
  // Load an extension and wait for it to be ready.
  ResultCatcher catcher;
  const Extension* extension =
      LoadExtension(test_data_dir_.AppendASCII("native_bindings/web_request"));
  ASSERT_TRUE(extension);
  ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();

  auto* web_contents = GetActiveWebContents();
  ASSERT_TRUE(NavigateToURL(
      web_contents, embedded_test_server()->GetURL(
                        "example.com", "/native_bindings/simple.html")));

  GURL expected_url = embedded_test_server()->GetURL(
      "example.com", "/native_bindings/simple2.html");
  EXPECT_EQ(expected_url, web_contents->GetLastCommittedURL());
}

// Tests the context menu API, which includes calling sendRequest with an
// different signature than specified and using functions as properties on an
// object.
IN_PROC_BROWSER_TEST_F(NativeBindingsApiTest, ContextMenusTest) {
  TestExtensionDir test_dir;
  test_dir.WriteManifest(
      R"({
           "name": "Context menus",
           "manifest_version": 2,
           "version": "0.1",
           "permissions": ["contextMenus"],
           "background": {
             "scripts": ["background.js"]
           }
         })");
  test_dir.WriteFile(
      FILE_PATH_LITERAL("background.js"),
      R"(chrome.contextMenus.create(
           {
             title: 'Context Menu Item',
             onclick: () => { chrome.test.sendMessage('clicked'); },
           }, () => { chrome.test.sendMessage('registered'); });)");

  const Extension* extension = nullptr;
  {
    ExtensionTestMessageListener listener("registered");
    extension = LoadExtension(test_dir.UnpackedPath());
    ASSERT_TRUE(extension);
    EXPECT_TRUE(listener.WaitUntilSatisfied());
  }

  content::WebContents* web_contents = GetActiveWebContents();
  std::unique_ptr<TestRenderViewContextMenu> menu(
      TestRenderViewContextMenu::Create(web_contents,
                                        GURL("https://www.example.com")));

  ExtensionTestMessageListener listener("clicked");
  int command_id = ContextMenuMatcher::ConvertToExtensionsCustomCommandId(0);
  EXPECT_TRUE(menu->IsCommandIdEnabled(command_id));
  menu->ExecuteCommand(command_id, 0);
  EXPECT_TRUE(listener.WaitUntilSatisfied());
}

// Tests that unchecked errors don't impede future calls.
IN_PROC_BROWSER_TEST_F(NativeBindingsApiTest, ErrorsInCallbackTest) {
  embedded_test_server()->ServeFilesFromDirectory(test_data_dir_);
  ASSERT_TRUE(StartEmbeddedTestServer());

  TestExtensionDir test_dir;
  test_dir.WriteManifest(
      R"({
           "name": "Errors In Callback",
           "manifest_version": 2,
           "version": "0.1",
           "permissions": ["contextMenus"],
           "background": {
             "scripts": ["background.js"]
           }
         })");
  test_dir.WriteFile(
      FILE_PATH_LITERAL("background.js"),
      R"(chrome.tabs.query({}, function(tabs) {
           chrome.tabs.executeScript(tabs[0].id, {code: 'x'}, function() {
             // There's an error here (we don't have permission to access the
             // host), but we don't check it so that it gets surfaced as an
             // unchecked runtime.lastError.
             // We should still be able to invoke other APIs and get correct
             // callbacks.
             chrome.tabs.query({}, function(tabs) {
               chrome.tabs.query({}, function(tabs) {
                 chrome.test.sendMessage('callback');
               });
             });
           });
         });)");

  ASSERT_TRUE(
      NavigateToURL(GetActiveWebContents(),
                    embedded_test_server()->GetURL(
                        "example.com", "/native_bindings/simple.html")));

  ExtensionTestMessageListener listener("callback");
  ASSERT_TRUE(LoadExtension(test_dir.UnpackedPath()));
  EXPECT_TRUE(listener.WaitUntilSatisfied());
}

// Tests that bindings are available in WebUI pages.
IN_PROC_BROWSER_TEST_F(NativeBindingsApiTest, WebUIBindings) {
  auto* web_contents = GetActiveWebContents();
  ASSERT_TRUE(NavigateToURL(web_contents, GURL("chrome://extensions")));

  EXPECT_TRUE(ApiExists(web_contents, "chrome.developerPrivate"));
  EXPECT_TRUE(ApiExists(web_contents,
                        "chrome.developerPrivate.getProfileConfiguration"));
  EXPECT_TRUE(ApiExists(web_contents, "chrome.management"));
  EXPECT_TRUE(ApiExists(web_contents, "chrome.management.setEnabled"));
  EXPECT_FALSE(ApiExists(web_contents, "chrome.networkingPrivate"));
  EXPECT_FALSE(ApiExists(web_contents, "chrome.sockets"));
  EXPECT_FALSE(ApiExists(web_contents, "chrome.browserAction"));
}

// Tests creating an API from a context that hasn't been initialized yet
// by doing so in a parent frame. Regression test for https://crbug.com/819968.
IN_PROC_BROWSER_TEST_F(NativeBindingsApiTest, APICreationFromNewContext) {
  embedded_test_server()->ServeFilesFromDirectory(test_data_dir_);
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(RunExtensionTest("native_bindings/context_initialization"))
      << message_;
}

// End-to-end test for promise support on bindings for MV3 extensions, using a
// few tabs APIs. Also ensures callbacks still work for the API as expected.
IN_PROC_BROWSER_TEST_F(NativeBindingsApiTest, PromiseBasedAPI) {
  base::HistogramTester histogram_tester;
  ASSERT_TRUE(StartEmbeddedTestServer());

  TestExtensionDir test_dir;
  test_dir.WriteManifest(
      R"({
           "name": "Promises",
           "manifest_version": 3,
           "version": "0.1",
           "background": {
             "service_worker": "background.js"
           },
           "permissions": ["tabs", "storage", "contentSettings", "privacy"]
         })");
  constexpr char kBackgroundJs[] =
      R"(let tabIdExample;
         let tabIdGoogle;

         chrome.test.getConfig((config) => {
           let exampleUrl = `https://example.com:${config.testServer.port}/`;
           let googleUrl = `https://google.com:${config.testServer.port}/`

           chrome.test.runTests([
             function createNewTabPromise() {
               let promise = chrome.tabs.create({url: exampleUrl});
               chrome.test.assertNoLastError();
               chrome.test.assertTrue(promise instanceof Promise);
               promise.then((tab) => {
                 let url = tab.pendingUrl;
                 chrome.test.assertEq(exampleUrl, url);
                 tabIdExample = tab.id;
                 chrome.test.assertNoLastError();
                 chrome.test.succeed();
               });
             },
             function queryTabPromise() {
               let promise = chrome.tabs.query({url: exampleUrl});
               chrome.test.assertNoLastError();
               chrome.test.assertTrue(promise instanceof Promise);
               promise.then((tabs) => {
                 chrome.test.assertTrue(tabs instanceof Array);
                 chrome.test.assertEq(1, tabs.length);
                 chrome.test.assertEq(tabIdExample, tabs[0].id);
                 chrome.test.assertNoLastError();
                 chrome.test.succeed();
               });
             },
             async function storageAreaCustomTypeWithPromises() {
               await chrome.storage.local.set({foo: 'bar', alpha: 'beta'});
               {
                 const {foo} = await chrome.storage.local.get('foo');
                 chrome.test.assertEq('bar', foo);
               }
               await chrome.storage.local.remove('foo');
               {
                 const {foo} = await chrome.storage.local.get('foo');
                 chrome.test.assertEq(undefined, foo);
               }
               let allValues = await chrome.storage.local.get(null);
               chrome.test.assertEq({alpha: 'beta'}, allValues);
               await chrome.storage.local.clear();
               allValues = await chrome.storage.local.get(null);
               chrome.test.assertEq({}, allValues);
               chrome.test.succeed();
             },
             async function contentSettingsCustomTypesWithPromises() {
               await chrome.contentSettings.cookies.set({
                   primaryPattern: '<all_urls>', setting: 'block'});
               {
                 const {setting} = await chrome.contentSettings.cookies.get({
                     primaryUrl: exampleUrl});
                 chrome.test.assertEq('block', setting);
               }
               await chrome.contentSettings.cookies.clear({});
               {
                 const {setting} = await chrome.contentSettings.cookies.get({
                     primaryUrl: exampleUrl});
                 // 'allow' is the default value for the setting.
                 chrome.test.assertEq('allow', setting);
               }
               chrome.test.succeed();
             },
             async function chromeSettingCustomTypesWithPromises() {
               // Short alias for ease of calling.
               let doNotTrack = chrome.privacy.websites.doNotTrackEnabled;
               await doNotTrack.set({value: true});
               {
                 const {value} = await doNotTrack.get({});
                 chrome.test.assertEq(true, value);
               }
               await doNotTrack.clear({});
               {
                 const {value} = await doNotTrack.get({});
                 // false is the default value for the setting.
                 chrome.test.assertEq(false, value);
               }
               chrome.test.succeed();
             },


             function createNewTabCallback() {
               chrome.tabs.create({url: googleUrl}, (tab) => {
                 let url = tab.pendingUrl;
                 chrome.test.assertEq(googleUrl, url);
                 tabIdGoogle = tab.id;
                 chrome.test.assertNoLastError();
                 chrome.test.succeed();
               });
             },
             function queryTabCallback() {
               chrome.tabs.query({url: googleUrl}, (tabs) => {
                 chrome.test.assertTrue(tabs instanceof Array);
                 chrome.test.assertEq(1, tabs.length);
                 chrome.test.assertEq(tabIdGoogle, tabs[0].id);
                 chrome.test.assertNoLastError();
                 chrome.test.succeed();
               });
             },
             function storageAreaCustomTypeWithCallbacks() {
               // Lots of stuff would probably fail if the callback version of
               // storage failed, so this is mostly just a rough sanity check.
               chrome.storage.local.set({gamma: 'delta'}, () => {
                 chrome.storage.local.get('gamma', ({gamma}) => {
                   chrome.test.assertEq('delta', gamma);
                   chrome.storage.local.clear(() => {
                     chrome.storage.local.get(null, (allValues) => {
                       chrome.test.assertEq({}, allValues);
                       chrome.test.succeed();
                     });
                   });
                 });
               });
             },
           ]);
         });)";
  test_dir.WriteFile(FILE_PATH_LITERAL("background.js"), kBackgroundJs);
  ResultCatcher catcher;
  ASSERT_TRUE(LoadExtension(test_dir.UnpackedPath()));
  ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();

  // The above test makes 2 calls to chrome.tabs.create, so check that those
  // have been logged in the histograms we expect them to be.
  EXPECT_EQ(2, histogram_tester.GetBucketCount(
                   "Extensions.Functions.ExtensionCalls",
                   functions::HistogramValue::TABS_CREATE));
  EXPECT_EQ(2, histogram_tester.GetBucketCount(
                   "Extensions.Functions.ExtensionServiceWorkerCalls",
                   functions::HistogramValue::TABS_CREATE));
  EXPECT_EQ(2, histogram_tester.GetBucketCount(
                   "Extensions.Functions.ExtensionMV3Calls",
                   functions::HistogramValue::TABS_CREATE));
}

// Tests that calling an API which supports promises using an MV2 extension does
// not get a promise based return and still needs to use callbacks when
// required.
IN_PROC_BROWSER_TEST_F(NativeBindingsApiTest, MV2PromisesNotSupported) {
  base::HistogramTester histogram_tester;
  ASSERT_TRUE(StartEmbeddedTestServer());

  TestExtensionDir test_dir;
  test_dir.WriteManifest(
      R"({
           "name": "Promises",
           "manifest_version": 2,
           "version": "0.1",
           "background": {
             "scripts": ["background.js"]
           },
           "permissions": ["tabs", "storage", "contentSettings", "privacy"]
         })");
  constexpr char kBackgroundJs[] =
      R"(let tabIdGooge;

         chrome.test.getConfig((config) => {
           let exampleUrl = `https://example.com:${config.testServer.port}/`;
           let googleUrl = `https://google.com:${config.testServer.port}/`

           chrome.test.runTests([
             function createNewTabPromise() {
               let result = chrome.tabs.create({url: exampleUrl});
               chrome.test.assertEq(undefined, result);
               chrome.test.assertNoLastError();
               chrome.test.succeed();
             },
             function queryTabPromise() {
               let expectedError = 'Error in invocation of tabs.query(object ' +
                   'queryInfo, function callback): No matching signature.';
               chrome.test.assertThrows(chrome.tabs.query,
                                        [{url: exampleUrl}],
                                        expectedError);
               chrome.test.succeed();
             },
             function storageAreaPromise() {
               let expectedError = 'Error in invocation of storage.get(' +
                   'optional [string|array|object] keys, function callback): ' +
                   'No matching signature.';
               chrome.test.assertThrows(chrome.storage.local.get,
                                        chrome.storage.local,
                                        ['foo'], expectedError);
               chrome.test.succeed();
             },
             function contentSettingPromise() {
               let expectedError = 'Error in invocation of contentSettings' +
                   '.ContentSetting.get(object details, function callback): ' +
                   'No matching signature.';
               chrome.test.assertThrows(chrome.contentSettings.cookies.get,
                                        chrome.contentSettings.cookies,
                                        [{primaryUrl: exampleUrl}],
                                        expectedError);
               chrome.test.succeed();
             },
             function chromeSettingPromise() {
               let expectedError = 'Error in invocation of types' +
                   '.ChromeSetting.get(object details, function callback): ' +
                   'No matching signature.';
               chrome.test.assertThrows(
                   chrome.privacy.websites.doNotTrackEnabled.get,
                   chrome.privacy.websites.doNotTrackEnabled,
                   [{}],
                   expectedError);
               chrome.test.succeed();
             },
             function createNewTabCallback() {
               chrome.tabs.create({url: googleUrl}, (tab) => {
                 let url = tab.pendingUrl;
                 chrome.test.assertEq(googleUrl, url);
                 tabIdGoogle = tab.id;
                 chrome.test.assertNoLastError();
                 chrome.test.succeed();
               });
             },
             function queryTabCallback() {
               chrome.tabs.query({url: googleUrl}, (tabs) => {
                 chrome.test.assertTrue(tabs instanceof Array);
                 chrome.test.assertEq(1, tabs.length);
                 chrome.test.assertEq(tabIdGoogle, tabs[0].id);
                 chrome.test.assertNoLastError();
                 chrome.test.succeed();
               });
             }
           ]);
         });)";
  test_dir.WriteFile(FILE_PATH_LITERAL("background.js"), kBackgroundJs);
  ResultCatcher catcher;
  ASSERT_TRUE(LoadExtension(test_dir.UnpackedPath()));
  ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();

  // The above test makes 2 calls to chrome.tabs.create, so check that those
  // have been logged in the histograms we expect, but not to the histograms
  // specifically tracking service worker and MV3 calls.
  EXPECT_EQ(2, histogram_tester.GetBucketCount(
                   "Extensions.Functions.ExtensionCalls",
                   functions::HistogramValue::TABS_CREATE));
  EXPECT_EQ(0, histogram_tester.GetBucketCount(
                   "Extensions.Functions.ExtensionServiceWorkerCalls",
                   functions::HistogramValue::TABS_CREATE));
  EXPECT_EQ(0, histogram_tester.GetBucketCount(
                   "Extensions.Functions.ExtensionMV3Calls",
                   functions::HistogramValue::TABS_CREATE));
}

class NativeBindingsBrowserNamespaceTest : public NativeBindingsApiTest {
 public:
  NativeBindingsBrowserNamespaceTest() {
    scoped_feature_list_.InitAndEnableFeature(
        extensions_features::kExtensionBrowserNamespaceAlternative);
  }

  NativeBindingsBrowserNamespaceTest(
      const NativeBindingsBrowserNamespaceTest&) = delete;
  const NativeBindingsBrowserNamespaceTest& operator=(
      const NativeBindingsBrowserNamespaceTest&) = delete;
  ~NativeBindingsBrowserNamespaceTest() override = default;

 protected:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Tests that extension background script contexts have access to
// `chrome.<extension_api>` and `browser.<extension_api>` objects.
IN_PROC_BROWSER_TEST_F(NativeBindingsBrowserNamespaceTest,
                       ChromeAndBrowserObjects_ExtensionBackground) {
  ASSERT_TRUE(RunExtensionTest("browser_object/background_context"))
      << message_;
}

// Tests that extension foreground script contexts (e.g. content script,
// extension page) have access to `chrome.<extension_api>` and
// `browser.<extension_api>` objects.
IN_PROC_BROWSER_TEST_F(NativeBindingsBrowserNamespaceTest,
                       ChromeAndBrowserObjects_ExtensionForeground) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  const GURL& test_website =
      embedded_test_server()->GetURL("a.com", "/title1.html");

  const Extension* extension = LoadExtension(
      test_data_dir_.AppendASCII("browser_object/foreground_context"));
  ASSERT_TRUE(extension);

  // Content script.
  ResultCatcher catcher;
  auto* web_contents = GetActiveWebContents();
  ASSERT_TRUE(NavigateToURL(web_contents, test_website));
  ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();

  // Extension page.
  ResultCatcher extension_resource_catcher;
  ASSERT_TRUE(NavigateToURL(
      web_contents,
      GURL(extension->GetResourceURL("extension_resource_page.html"))));
  ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
}

// Tests that an externally connectable webpage has access to
// `chrome.<extension_api>` and `browser.<extension_api>` objects. Additionally
// it tests that `chrome.app` is bound, but `browser.app` is not.
IN_PROC_BROWSER_TEST_F(NativeBindingsBrowserNamespaceTest,
                       ChromeAndBrowserObjects_ExternallyConnectableWebpage) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  const GURL& test_website =
      embedded_test_server()->GetURL("a.com", "/title1.html");

  TestExtensionDir test_dir;
  test_dir.WriteManifest(
      R"({
          "name": "Externally connectable test extension",
          "version": "0.1",
          "manifest_version": 3,
          "externally_connectable": {
            "matches": ["*://a.com/*"]
          }
        })");
  test_dir.WriteFile(FILE_PATH_LITERAL("background.js"), "");
  ASSERT_TRUE(LoadExtension(test_dir.UnpackedPath()));

  auto* web_contents = GetActiveWebContents();
  ASSERT_TRUE(NavigateToURL(web_contents, test_website));

  EXPECT_TRUE(ApiExists(web_contents, "chrome.runtime"));
  EXPECT_TRUE(ApiExists(web_contents, "browser.runtime"));
  EXPECT_TRUE(ApiExists(web_contents, "chrome.app"));
  EXPECT_FALSE(ApiExists(web_contents, "browser.app"));
}

// Tests that the `browser` namespace is not available in WebUI.
IN_PROC_BROWSER_TEST_F(NativeBindingsBrowserNamespaceTest, WebUIBindings) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  auto* web_contents = GetActiveWebContents();
  ASSERT_TRUE(NavigateToURL(web_contents, GURL("chrome://extensions")));

  EXPECT_TRUE(ObjectIsDefined(web_contents, "chrome"));
  EXPECT_FALSE(ObjectIsDefined(web_contents, "browser"));
}

// Tests that an arbitrary web page with no extension API access has access to
// the `chrome` namespace, but not the browser namespace.
IN_PROC_BROWSER_TEST_F(NativeBindingsBrowserNamespaceTest,
                       TestNonExtensionChromeAndBrowserObjects) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  const GURL& test_website =
      embedded_test_server()->GetURL("a.com", "/title1.html");
  auto* web_contents = GetActiveWebContents();
  ASSERT_TRUE(NavigateToURL(web_contents, test_website));

  EXPECT_TRUE(ObjectIsDefined(web_contents, "chrome"));
  EXPECT_FALSE(ObjectIsDefined(web_contents, "browser"));
}

// TODO(crbug.com/401226626): Test that the browser object also has dev mode
// restricted APIs set on correctly as well.

class DeveloperModeNativeBindingsApiTest
    : public NativeBindingsApiTest,
      public testing::WithParamInterface<bool> {
 public:
  DeveloperModeNativeBindingsApiTest() {
    if (GetParam()) {
      // Ensure chrome.debugger is controlled by Developer Mode.
      scoped_feature_list_.InitWithFeatures(
          /*enabled_features=*/
          {extensions_features::kUserScriptUserExtensionToggle,
           extensions_features::kDebuggerAPIRestrictedToDevMode},
          /*disabled_features=*/{});

    } else {
      // Ensure chrome.userScripts is controlled by Developer Mode.
      scoped_feature_list_.InitWithFeatures(
          /*enabled_features=*/{}, /*disabled_features=*/{
              extensions_features::kUserScriptUserExtensionToggle,
              extensions_features::kDebuggerAPIRestrictedToDevMode});
    }
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// TODO(crbug.com/390138269): Revert the user scripts specific testing once the
// extensions::kUserScriptUserExtensionToggle feature is launched.
IN_PROC_BROWSER_TEST_P(
    DeveloperModeNativeBindingsApiTest,
    DeveloperModeOnlyWithAPIPermissionUserIsNotInDeveloperMode) {
  // Developer mode-only APIs should not be available if the user is not in
  // developer mode.
  SetCustomArg("not_in_developer_mode");
  util::SetDeveloperModeForProfile(profile(), false);
  if (GetParam()) {
    ASSERT_TRUE(RunExtensionTest(
        "native_bindings/developer_mode_only_with_api_permission"))
        << message_;
  } else {
    ASSERT_TRUE(RunExtensionTest(
        "native_bindings/developer_mode_only_with_user_scripts_api_permission"))
        << message_;
  }
}

IN_PROC_BROWSER_TEST_P(
    DeveloperModeNativeBindingsApiTest,
    DeveloperModeOnlyWithAPIPermissionUserIsInDeveloperMode) {
  // Developer mode-only APIs should be available if the user is in developer
  // mode.
  SetCustomArg("in_developer_mode");
  util::SetDeveloperModeForProfile(profile(), true);
  if (GetParam()) {
    ASSERT_TRUE(RunExtensionTest(
        "native_bindings/developer_mode_only_with_api_permission"))
        << message_;
  } else {
    ASSERT_TRUE(RunExtensionTest(
        "native_bindings/developer_mode_only_with_user_scripts_api_permission"))
        << message_;
  }
}

IN_PROC_BROWSER_TEST_P(
    DeveloperModeNativeBindingsApiTest,
    DeveloperModeOnlyWithoutAPIPermissionUserIsNotInDeveloperMode) {
  util::SetDeveloperModeForProfile(profile(), false);
  if (GetParam()) {
    ASSERT_TRUE(RunExtensionTest(
        "native_bindings/developer_mode_only_without_api_permission"))
        << message_;
  } else {
    ASSERT_TRUE(RunExtensionTest(
        "native_bindings/"
        "developer_mode_only_without_user_scripts_api_permission"))
        << message_;
  }
}

IN_PROC_BROWSER_TEST_P(
    DeveloperModeNativeBindingsApiTest,
    DeveloperModeOnlyWithoutAPIPermissionUserIsInDeveloperMode) {
  util::SetDeveloperModeForProfile(profile(), true);
  if (GetParam()) {
    ASSERT_TRUE(RunExtensionTest(
        "native_bindings/developer_mode_only_without_api_permission"))
        << message_;
  } else {
    ASSERT_TRUE(RunExtensionTest(
        "native_bindings/"
        "developer_mode_only_without_user_scripts_api_permission"))
        << message_;
  }
}

// Tests that changing the developer mode setting affects existing renderers
// for page-based contexts (i.e., the main renderer thread).
IN_PROC_BROWSER_TEST_P(DeveloperModeNativeBindingsApiTest,
                       SwitchingDeveloperModeAffectsExistingRenderers_Pages) {
  static constexpr char kManifest[] =
      R"({
           "name": "Test",
           "manifest_version": 3,
           "version": "0.1",
           "permissions": ["%s"]
         })";
  static constexpr char kPageHtml[] =
      R"(<!doctype html>
         <html>
           <script src="page.js"></script>
         </html>)";

  TestExtensionDir test_dir;
  test_dir.WriteManifest(
      base::StringPrintf(kManifest, GetParam() ? "debugger" : "userScripts"));
  test_dir.WriteFile(FILE_PATH_LITERAL("page.html"), kPageHtml);
  test_dir.WriteFile(
      FILE_PATH_LITERAL("page.js"),
      GetParam() ? kCheckApiAvailability : kCheckApiAvailabilityUserScripts);
  test_dir.WriteFile(FILE_PATH_LITERAL("script.js"), "// blank");

  const Extension* extension = LoadExtension(test_dir.UnpackedPath());
  ASSERT_TRUE(extension);

  const GURL extension_url = extension->GetResourceURL("page.html");

  // Navigate to the extension page.
  auto* existing_tab = GetActiveWebContents();
  ASSERT_TRUE(NavigateToURL(existing_tab, extension_url));
  ASSERT_EQ(extension_url, existing_tab->GetLastCommittedURL());

  ScriptResultQueue result_queue;

  // By default, the API is unavailable.
  ASSERT_TRUE(content::ExecJs(existing_tab, "verifyApiIsNotAvailable();"));
  EXPECT_EQ("success", result_queue.GetNextResult());

  // Next, set the user in developer mode. Now the API should be available.
  util::SetDeveloperModeForProfile(profile(), true);
  ASSERT_TRUE(content::ExecJs(existing_tab, "verifyApiIsAvailable();"));
  EXPECT_EQ("success", result_queue.GetNextResult());

  // Toggle back to not in developer mode. The API should be unavailable again.
  util::SetDeveloperModeForProfile(profile(), false);
  ASSERT_TRUE(content::ExecJs(existing_tab, "verifyApiIsNotAvailable();"));
  EXPECT_EQ("success", result_queue.GetNextResult());
}

// Tests that incognito windows use the developer mode setting from the
// original, on-the-record profile (since incognito windows can't separately
// set developer mode).
IN_PROC_BROWSER_TEST_P(DeveloperModeNativeBindingsApiTest,
                       IncognitoRenderersUseOriginalProfilesDevModeSetting) {
  static constexpr char kManifest[] =
      R"({
           "name": "Test",
           "manifest_version": 3,
           "version": "0.1",
           "incognito": "split",
           "permissions": ["%s"]
         })";
  static constexpr char kPageHtml[] =
      R"(<!doctype html>
         <html>
           <script src="page.js"></script>
         </html>)";

  TestExtensionDir test_dir;
  test_dir.WriteManifest(
      base::StringPrintf(kManifest, GetParam() ? "debugger" : "userScripts"));
  test_dir.WriteFile(FILE_PATH_LITERAL("page.html"), kPageHtml);
  test_dir.WriteFile(
      FILE_PATH_LITERAL("page.js"),
      GetParam() ? kCheckApiAvailability : kCheckApiAvailabilityUserScripts);
  test_dir.WriteFile(FILE_PATH_LITERAL("script.js"), "// blank");

  const Extension* extension =
      LoadExtension(test_dir.UnpackedPath(), {.allow_in_incognito = true});
  ASSERT_TRUE(extension);

  const GURL extension_url = extension->GetResourceURL("page.html");

  Browser* incognito_browser = OpenURLOffTheRecord(profile(), extension_url);
  content::WebContents* incognito_tab =
      incognito_browser->tab_strip_model()->GetActiveWebContents();
  content::WaitForLoadStop(incognito_tab);

  ScriptResultQueue result_queue;

  // By default, the API is unavailable.
  ASSERT_TRUE(content::ExecJs(incognito_tab, "verifyApiIsNotAvailable();"));
  EXPECT_EQ("success", result_queue.GetNextResult());

  // Next, set the user in developer mode. Now the API should be available.
  util::SetDeveloperModeForProfile(profile(), true);
  ASSERT_TRUE(content::ExecJs(incognito_tab, "verifyApiIsAvailable();"));
  EXPECT_EQ("success", result_queue.GetNextResult());

  // Toggle back to not in developer mode. The API should be unavailable again.
  util::SetDeveloperModeForProfile(profile(), false);
  ASSERT_TRUE(content::ExecJs(incognito_tab, "verifyApiIsNotAvailable();"));
  EXPECT_EQ("success", result_queue.GetNextResult());
}

// Tests that changing the developer mode setting affects existing renderers
// for service worker contexts (which run off the main thread in the renderer).
// TODO(crbug.com/40946312): Test flaky on multiple platforms
IN_PROC_BROWSER_TEST_P(
    DeveloperModeNativeBindingsApiTest,
    DISABLED_SwitchingDeveloperModeAffectsExistingRenderers_ServiceWorkers) {
  static constexpr char kManifest[] =
      R"({
           "name": "Test",
           "manifest_version": 3,
           "version": "0.1",
           "permissions": ["%s"],
           "background": {"service_worker": "background.js"}
         })";

  TestExtensionDir test_dir;
  test_dir.WriteManifest(
      base::StringPrintf(kManifest, GetParam() ? "debugger" : "userScripts"));
  test_dir.WriteFile(
      FILE_PATH_LITERAL("background.js"),
      GetParam() ? kCheckApiAvailability : kCheckApiAvailabilityUserScripts);
  test_dir.WriteFile(FILE_PATH_LITERAL("script.js"), "// blank");

  const Extension* extension = LoadExtension(test_dir.UnpackedPath());
  ASSERT_TRUE(extension);

  auto call_in_service_worker = [this, extension](const std::string& script) {
    return BackgroundScriptExecutor::ExecuteScript(
        profile(), extension->id(), script,
        BackgroundScriptExecutor::ResultCapture::kSendScriptResult);
  };

  auto renderer_round_trip = [this, extension]() {
    EXPECT_EQ("success",
              BackgroundScriptExecutor::ExecuteScript(
                  profile(), extension->id(),
                  "chrome.test.sendScriptResult('success');",
                  BackgroundScriptExecutor::ResultCapture::kSendScriptResult));
  };

  // By default, the API is unavailable.
  EXPECT_EQ("success", call_in_service_worker("verifyApiIsNotAvailable();"));

  // Next, set the user in developer mode. Now the API should be available.
  util::SetDeveloperModeForProfile(profile(), true);
  // We need to give the renderer time to do a few thread hops since there are
  // multiple IPC channels at play (unlike the test above). Do a round-trip to
  // the renderer to allow it to process.
  renderer_round_trip();
  EXPECT_EQ("success", call_in_service_worker("verifyApiIsAvailable();"));

  // Toggle back to not in developer mode. The API should be unavailable again.
  util::SetDeveloperModeForProfile(profile(), false);
  renderer_round_trip();
  EXPECT_EQ("success", call_in_service_worker("verifyApiIsNotAvailable();"));
}

INSTANTIATE_TEST_SUITE_P(All,
                         DeveloperModeNativeBindingsApiTest,
                         // extensions_features::kDebuggerAPIRestrictedToDevMode
                         testing::Bool());

}  // namespace extensions
