1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/api/search/search_api.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/common/extensions/api/search.h"
#include "components/search_engines/util.h"
namespace extensions {
namespace {
void NavigateToURL(WindowOpenDisposition disposition,
Browser* browser,
const GURL& url) {
NavigateParams navigate_params(browser, url, ui::PAGE_TRANSITION_FROM_API);
navigate_params.window_action = NavigateParams::SHOW_WINDOW;
navigate_params.disposition = disposition;
Navigate(&navigate_params);
}
} // namespace
using extensions::api::search::Disposition;
ExtensionFunction::ResponseAction SearchQueryFunction::Run() {
std::optional<api::search::Query::Params> params =
api::search::Query::Params::Create(args());
EXTENSION_FUNCTION_VALIDATE(params);
// Convenience for input params.
const std::string& text = params->query_info.text;
const std::optional<int>& tab_id = params->query_info.tab_id;
Disposition disposition = params->query_info.disposition;
// Simple validation of input params.
if (text.empty()) {
return RespondNow(Error("Empty text parameter."));
}
if (tab_id && disposition != Disposition::kNone) {
return RespondNow(Error("Cannot set both 'disposition' and 'tabId'."));
}
Profile* profile = Profile::FromBrowserContext(browser_context());
// We need to find which tab to navigate, which may be a specific tab or a
// new tab.
content::WebContents* web_contents = nullptr;
// If the extension specified a tab, that takes priority.
// Get web_contents if tab_id is valid, or disposition.
if (tab_id) {
if (!ExtensionTabUtil::GetTabById(
*tab_id, profile, include_incognito_information(), &web_contents)) {
return RespondNow(
Error(base::StringPrintf("No tab with id: %d.", *tab_id)));
}
// If tab_id was specified, disposition couldn't have been (checked above).
DCHECK_EQ(Disposition::kNone, disposition);
}
// If the extension didn't specify a tab, we need to find a browser to use.
Browser* browser = nullptr;
if (!web_contents) {
// If the extension called the API from a tab, we can use that tab -
// find the associated browser.
web_contents = GetSenderWebContents();
if (web_contents) {
browser = chrome::FindBrowserWithTab(web_contents);
}
// Otherwise (e.g. when the extension calls the API from the background
// page or service worker), fall back to the last active browser.
if (!browser) {
browser = chrome::FindTabbedBrowser(
profile,
/*match_original_profiles=*/include_incognito_information());
if (!browser) {
return RespondNow(Error("No active browser."));
}
web_contents = browser->tab_strip_model()->GetActiveWebContents();
}
}
DCHECK(browser || (web_contents && disposition == Disposition::kNone));
// GURL for default search provider.
TemplateURLService* url_service =
TemplateURLServiceFactory::GetForProfile(profile);
DCHECK(url_service);
GURL url =
GetDefaultSearchURLForSearchTerms(url_service, base::UTF8ToUTF16(text));
if (!url.is_valid()) {
return RespondNow(Error("Missing default search provider."));
}
switch (disposition) {
case Disposition::kCurrentTab:
case Disposition::kNone:
DCHECK(url.is_valid());
web_contents->GetController().LoadURL(
url, content::Referrer(),
ui::PageTransition::PAGE_TRANSITION_FROM_API,
/*extra_headers=*/std::string());
break;
case Disposition::kNewTab:
NavigateToURL(WindowOpenDisposition::NEW_FOREGROUND_TAB, browser, url);
break;
case Disposition::kNewWindow:
NavigateToURL(WindowOpenDisposition::NEW_WINDOW, browser, url);
break;
}
return RespondNow(NoArguments());
}
} // namespace extensions
|