Commit 0fc14344 authored by David Black's avatar David Black Committed by Commit Bot

Create Chrome Settings deep link.

Used to launch a specific Chrome Settings page, or top level Settings,
in a new browser tab.

Bug: b:115675454
Change-Id: I7bc6bf0e9b5e950e23c1ec2f4ad8b801d7b54958
Reviewed-on: https://chromium-review.googlesource.com/1226206
Commit-Queue: David Black <dmblack@google.com>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#592554}
parent 8415014c
......@@ -183,9 +183,16 @@ void AssistantController::DownloadImage(
void AssistantController::OnDeepLinkReceived(
assistant::util::DeepLinkType type,
const std::map<std::string, std::string>& params) {
using assistant::util::DeepLinkParam;
using assistant::util::DeepLinkType;
switch (type) {
case DeepLinkType::kChromeSettings: {
// Chrome Settings deep links are opened in a new browser tab.
OpenUrl(assistant::util::GetChromeSettingsUrl(
assistant::util::GetDeepLinkParam(params, DeepLinkParam::kPage)));
break;
}
case DeepLinkType::kFeedback:
// TODO(dmblack): Possibly use a new FeedbackSource (this method defaults
// to kFeedbackSourceAsh). This may be useful for differentiating feedback
......
......@@ -4,6 +4,7 @@
#include "ash/assistant/util/deep_link_util.h"
#include <array>
#include <set>
#include "base/i18n/rtl.h"
......@@ -22,10 +23,12 @@ namespace {
// Supported deep link param keys. These values must be kept in sync with the
// server. See more details at go/cros-assistant-deeplink.
constexpr char kQueryParamKey[] = "q";
constexpr char kPageParamKey[] = "page";
constexpr char kRelaunchParamKey[] = "relaunch";
// Supported deep link prefixes. These values must be kept in sync with the
// server. See more details at go/cros-assistant-deeplink.
constexpr char kChromeSettingsPrefix[] = "googleassistant://chrome-settings";
constexpr char kAssistantFeedbackPrefix[] = "googleassistant://send-feedback";
constexpr char kAssistantOnboardingPrefix[] = "googleassistant://onboarding";
constexpr char kAssistantQueryPrefix[] = "googleassistant://send-query";
......@@ -36,12 +39,6 @@ constexpr char kAssistantSettingsPrefix[] = "googleassistant://settings";
constexpr char kAssistantWhatsOnMyScreenPrefix[] =
"googleassistant://whats-on-my-screen";
// TODO(b/113357196): Make these URLs configurable for development purposes.
constexpr char kAssistantRemindersWebUrl[] =
"https://assistant.google.com/reminders/mainview?hl=";
constexpr char kAssistantSettingsWebUrl[] =
"https://assistant.google.com/settings/mainpage?hl=";
} // namespace
GURL CreateAssistantSettingsDeepLink() {
......@@ -80,6 +77,7 @@ base::Optional<std::string> GetDeepLinkParam(
DeepLinkParam param) {
// Map of supported deep link params to their keys.
static const std::map<DeepLinkParam, std::string> kDeepLinkParamKeys = {
{DeepLinkParam::kPage, kPageParamKey},
{DeepLinkParam::kQuery, kQueryParamKey},
{DeepLinkParam::kRelaunch, kRelaunchParamKey}};
......@@ -107,6 +105,7 @@ base::Optional<bool> GetDeepLinkParamAsBool(
DeepLinkType GetDeepLinkType(const GURL& url) {
// Map of supported deep link types to their prefixes.
static const std::map<DeepLinkType, std::string> kSupportedDeepLinks = {
{DeepLinkType::kChromeSettings, kChromeSettingsPrefix},
{DeepLinkType::kFeedback, kAssistantFeedbackPrefix},
{DeepLinkType::kOnboarding, kAssistantOnboardingPrefix},
{DeepLinkType::kQuery, kAssistantQueryPrefix},
......@@ -132,11 +131,32 @@ bool IsDeepLinkUrl(const GURL& url) {
return GetDeepLinkType(url) != DeepLinkType::kUnsupported;
}
GURL GetChromeSettingsUrl(const base::Optional<std::string>& page) {
static constexpr char kChromeSettingsUrl[] = "chrome://settings/";
// Note that we only allow deep linking to a subset of pages. If a deep link
// requests a page not contained in this array, we fallback gracefully to
// top-level Chrome Settings.
static constexpr std::array<char[16], 2> kAllowedPages = {"googleAssistant",
"languages"};
return page && std::find(kAllowedPages.begin(), kAllowedPages.end(),
page.value()) != kAllowedPages.end()
? GURL(kChromeSettingsUrl + page.value())
: GURL(kChromeSettingsUrl);
}
base::Optional<GURL> GetWebUrl(const GURL& deep_link) {
return GetWebUrl(GetDeepLinkType(deep_link));
}
base::Optional<GURL> GetWebUrl(DeepLinkType type) {
// TODO(b/113357196): Make these URLs configurable for development purposes.
static constexpr char kAssistantRemindersWebUrl[] =
"https://assistant.google.com/reminders/mainview?hl=";
static constexpr char kAssistantSettingsWebUrl[] =
"https://assistant.google.com/settings/mainpage?hl=";
if (!IsWebDeepLinkType(type))
return base::nullopt;
......@@ -147,6 +167,7 @@ base::Optional<GURL> GetWebUrl(DeepLinkType type) {
case DeepLinkType::kSettings:
return GURL(kAssistantSettingsWebUrl + base::i18n::GetConfiguredLocale());
case DeepLinkType::kUnsupported:
case DeepLinkType::kChromeSettings:
case DeepLinkType::kFeedback:
case DeepLinkType::kOnboarding:
case DeepLinkType::kQuery:
......
......@@ -20,6 +20,7 @@ namespace util {
// Enumeration of deep link types.
enum class DeepLinkType {
kUnsupported,
kChromeSettings,
kFeedback,
kOnboarding,
kQuery,
......@@ -31,6 +32,7 @@ enum class DeepLinkType {
// Enumeration of deep link parameters.
enum class DeepLinkParam {
kPage,
kQuery,
kRelaunch,
};
......@@ -69,6 +71,10 @@ ASH_EXPORT bool IsDeepLinkType(const GURL& url, DeepLinkType type);
// Returns true if the specified |url| is a deep link, false otherwise.
ASH_EXPORT bool IsDeepLinkUrl(const GURL& url);
// Returns the URL for the specified Chrome Settings |page|. If page is absent
// or not allowed, the URL will be for top-level Chrome Settings.
ASH_EXPORT GURL GetChromeSettingsUrl(const base::Optional<std::string>& page);
// Returns the web URL for the specified |deep_link|. A return value will only
// be present if |deep_link| is a web deep link as identified by the
// IsWebDeepLink(GURL) API.
......
......@@ -68,8 +68,8 @@ TEST_F(DeepLinkUnitTest, GetDeepLinkParams) {
}
TEST_F(DeepLinkUnitTest, GetDeepLinkParam) {
std::map<std::string, std::string> params = {{"q", "query"},
{"relaunch", "true"}};
std::map<std::string, std::string> params = {
{"page", "main"}, {"q", "query"}, {"relaunch", "true"}};
auto AssertDeepLinkParamEq = [&params](
const base::Optional<std::string>& expected,
......@@ -78,6 +78,7 @@ TEST_F(DeepLinkUnitTest, GetDeepLinkParam) {
};
// Case: Deep link parameters present.
AssertDeepLinkParamEq("main", DeepLinkParam::kPage);
AssertDeepLinkParamEq("query", DeepLinkParam::kQuery);
AssertDeepLinkParamEq("true", DeepLinkParam::kRelaunch);
......@@ -87,6 +88,7 @@ TEST_F(DeepLinkUnitTest, GetDeepLinkParam) {
// Case: Deep link parameters absent.
params.clear();
AssertDeepLinkParamEq(base::nullopt, DeepLinkParam::kPage);
AssertDeepLinkParamEq(base::nullopt, DeepLinkParam::kQuery);
AssertDeepLinkParamEq(base::nullopt, DeepLinkParam::kRelaunch);
}
......@@ -127,6 +129,7 @@ TEST_F(DeepLinkUnitTest, GetDeepLinkParamAsBool) {
TEST_F(DeepLinkUnitTest, GetDeepLinkType) {
const std::map<std::string, DeepLinkType> test_cases = {
// OK: Supported deep links.
{"googleassistant://chrome-settings", DeepLinkType::kChromeSettings},
{"googleassistant://onboarding", DeepLinkType::kOnboarding},
{"googleassistant://reminders", DeepLinkType::kReminders},
{"googleassistant://send-feedback", DeepLinkType::kFeedback},
......@@ -136,6 +139,8 @@ TEST_F(DeepLinkUnitTest, GetDeepLinkType) {
{"googleassistant://whats-on-my-screen", DeepLinkType::kWhatsOnMyScreen},
// OK: Parameterized deep links.
{"googleassistant://chrome-settings?param=true",
DeepLinkType::kChromeSettings},
{"googleassistant://onboarding?param=true", DeepLinkType::kOnboarding},
{"googleassistant://reminders?param=true", DeepLinkType::kReminders},
{"googleassistant://send-feedback?param=true", DeepLinkType::kFeedback},
......@@ -147,6 +152,7 @@ TEST_F(DeepLinkUnitTest, GetDeepLinkType) {
DeepLinkType::kWhatsOnMyScreen},
// UNSUPPORTED: Deep links are case sensitive.
{"GOOGLEASSISTANT://CHROME-SETTINGS", DeepLinkType::kUnsupported},
{"GOOGLEASSISTANT://ONBOARDING", DeepLinkType::kUnsupported},
{"GOOGLEASSISTANT://REMINDERS", DeepLinkType::kUnsupported},
{"GOOGLEASSISTANT://SEND-FEEDBACK", DeepLinkType::kUnsupported},
......@@ -171,6 +177,7 @@ TEST_F(DeepLinkUnitTest, GetDeepLinkType) {
TEST_F(DeepLinkUnitTest, IsDeepLinkType) {
const std::map<std::string, DeepLinkType> test_cases = {
// OK: Supported deep link types.
{"googleassistant://chrome-settings", DeepLinkType::kChromeSettings},
{"googleassistant://onboarding", DeepLinkType::kOnboarding},
{"googleassistant://reminders", DeepLinkType::kReminders},
{"googleassistant://send-feedback", DeepLinkType::kFeedback},
......@@ -180,6 +187,8 @@ TEST_F(DeepLinkUnitTest, IsDeepLinkType) {
{"googleassistant://whats-on-my-screen", DeepLinkType::kWhatsOnMyScreen},
// OK: Parameterized deep link types.
{"googleassistant://chrome-settings?param=true",
DeepLinkType::kChromeSettings},
{"googleassistant://onboarding?param=true", DeepLinkType::kOnboarding},
{"googleassistant://reminders?param=true", DeepLinkType::kReminders},
{"googleassistant://send-feedback?param=true", DeepLinkType::kFeedback},
......@@ -191,6 +200,7 @@ TEST_F(DeepLinkUnitTest, IsDeepLinkType) {
DeepLinkType::kWhatsOnMyScreen},
// UNSUPPORTED: Deep links are case sensitive.
{"GOOGLEASSISTANT://CHROME-SETTINGS", DeepLinkType::kUnsupported},
{"GOOGLEASSISTANT://ONBOARDING", DeepLinkType::kUnsupported},
{"GOOGLEASSISTANT://REMINDERS", DeepLinkType::kUnsupported},
{"GOOGLEASSISTANT://SEND-FEEDBACK", DeepLinkType::kUnsupported},
......@@ -212,6 +222,7 @@ TEST_F(DeepLinkUnitTest, IsDeepLinkType) {
TEST_F(DeepLinkUnitTest, IsDeepLinkUrl) {
const std::map<std::string, bool> test_cases = {
// OK: Supported deep links.
{"googleassistant://chrome-settings", true},
{"googleassistant://onboarding", true},
{"googleassistant://reminders", true},
{"googleassistant://send-feedback", true},
......@@ -221,6 +232,7 @@ TEST_F(DeepLinkUnitTest, IsDeepLinkUrl) {
{"googleassistant://whats-on-my-screen", true},
// OK: Parameterized deep links.
{"googleassistant://chrome-settings?param=true", true},
{"googleassistant://onboarding?param=true", true},
{"googleassistant://reminders?param=true", true},
{"googleassistant://send-feedback?param=true", true},
......@@ -230,6 +242,7 @@ TEST_F(DeepLinkUnitTest, IsDeepLinkUrl) {
{"googleassistant://whats-on-my-screen?param=true", true},
// FAIL: Deep links are case sensitive.
{"GOOGLEASSISTANT://CHROME-SETTINGS", false},
{"GOOGLEASSISTANT://ONBOARDING", false},
{"GOOGLEASSISTANT://REMINDERS", false},
{"GOOGLEASSISTANT://SEND-FEEDBACK", false},
......@@ -250,6 +263,28 @@ TEST_F(DeepLinkUnitTest, IsDeepLinkUrl) {
ASSERT_EQ(test_case.second, IsDeepLinkUrl(GURL(test_case.first)));
}
TEST_F(DeepLinkUnitTest, GetChromeSettingsUrl) {
const std::map<base::Optional<std::string>, std::string> test_cases = {
// OK: Absent/empty page.
{base::nullopt, "chrome://settings/"},
{base::Optional<std::string>(std::string()), "chrome://settings/"},
// OK: Allowed pages.
{base::Optional<std::string>("googleAssistant"),
"chrome://settings/googleAssistant"},
{base::Optional<std::string>("languages"), "chrome://settings/languages"},
// FALLBACK: Allowed pages are case sensitive.
{base::Optional<std::string>("GOOGLEASSISTANT"), "chrome://settings/"},
{base::Optional<std::string>("LANGUAGES"), "chrome://settings/"},
// FALLBACK: Any page not explicitly allowed.
{base::Optional<std::string>("search"), "chrome://settings/"}};
for (const auto& test_case : test_cases)
ASSERT_EQ(test_case.second, GetChromeSettingsUrl(test_case.first));
}
// TODO(dmblack): Assert actual web URLs when available.
TEST_F(DeepLinkUnitTest, GetWebUrl) {
const std::map<std::string, bool> test_cases = {
......@@ -266,6 +301,7 @@ TEST_F(DeepLinkUnitTest, GetWebUrl) {
{"GOOGLEASSISTANT://SETTINGS", false},
// FAIL: Non-web deep links.
{"googleassistant://chrome-settings", false},
{"googleassistant://onboarding", false},
{"googleassistant://send-feedback", false},
{"googleassistant://send-query", false},
......@@ -288,6 +324,7 @@ TEST_F(DeepLinkUnitTest, GetWebUrlByType) {
{DeepLinkType::kSettings, true},
// FAIL: Non-web deep link types.
{DeepLinkType::kChromeSettings, false},
{DeepLinkType::kFeedback, false},
{DeepLinkType::kOnboarding, false},
{DeepLinkType::kQuery, false},
......@@ -316,6 +353,7 @@ TEST_F(DeepLinkUnitTest, IsWebDeepLink) {
{"GOOGLEASSISTANT://SETTINGS", false},
// FAIL: Non-web deep links.
{"googleassistant://chrome-settings", false},
{"googleassistant://onboarding", false},
{"googleassistant://send-feedback", false},
{"googleassistant://send-query", false},
......@@ -337,6 +375,7 @@ TEST_F(DeepLinkUnitTest, IsWebDeepLinkType) {
{DeepLinkType::kSettings, true},
// FAIL: Non-web deep link types.
{DeepLinkType::kChromeSettings, false},
{DeepLinkType::kFeedback, false},
{DeepLinkType::kOnboarding, false},
{DeepLinkType::kQuery, false},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment