Commit 7dc53d3b authored by Guillaume Jenkins's avatar Guillaume Jenkins Committed by Commit Bot

[iOS intents] Fix Search in Chrome shortcut when in foreground

The Search in Chrome intent wasn't doing anything if Chrome was in
the foreground, because in that case a separate code path is used and
that code path did not check for |searchQuery| in the startup
parameters.

The fix is to have that code path properly check for and handle
|searchQuery|. Because performing a search requires the user's default
search engine, the current BrowserState must now be passed to the
user activity handler.

The code that generates the search URL from the user's default search
engine has been refactored into a reusable function so it can be called
from the foreground code path.

Bug: 1115998
Change-Id: I88899ef8236584b0f69ea58362960abf6924650f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2356669
Commit-Queue: Guillaume Jenkins <gujen@google.com>
Reviewed-by: default avatarJustin Cohen <justincohen@chromium.org>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#800239}
parent 55905f76
......@@ -20,13 +20,16 @@ class ChromeBrowserState;
@interface UserActivityHandler : NSObject
// If the userActivity is a Handoff or an opening from Spotlight, opens a new
// tab or setup startupParameters to open it later.
// Returns wether it could continue userActivity.
// tab or setup startupParameters to open it later. If a new tab must be
// opened immediately (e.g. if a Siri Shortcut was triggered by the user while
// Chrome was already in the foreground), it will be done with the provided
// |browserState|. Returns wether it could continue userActivity.
+ (BOOL)continueUserActivity:(NSUserActivity*)userActivity
applicationIsActive:(BOOL)applicationIsActive
tabOpener:(id<TabOpening>)tabOpener
connectionInformation:(id<ConnectionInformation>)connectionInformation
startupInformation:(id<StartupInformation>)startupInformation;
startupInformation:(id<StartupInformation>)startupInformation
browserState:(ChromeBrowserState*)browserState;
// Handles the 3D touch application static items. If the First Run UI is active,
// |completionHandler| will be called with NO.
......
......@@ -89,7 +89,8 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) {
applicationIsActive:(BOOL)applicationIsActive
tabOpener:(id<TabOpening>)tabOpener
connectionInformation:(id<ConnectionInformation>)connectionInformation
startupInformation:(id<StartupInformation>)startupInformation {
startupInformation:(id<StartupInformation>)startupInformation
browserState:(ChromeBrowserState*)browserState {
NSURL* webpageURL = userActivity.webpageURL;
if ([userActivity.activityType
......@@ -151,7 +152,8 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) {
applicationIsActive:isActive
tabOpener:tabOpener
connectionInformation:connectionInformation
startupInformation:startupInformation];
startupInformation:startupInformation
browserState:browserState];
});
});
return YES;
......@@ -179,6 +181,7 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) {
[connectionInformation setStartupParameters:startupParams];
webpageURL =
[NSURL URLWithString:base::SysUTF8ToNSString(kChromeUINewTabURL)];
} else if ([userActivity.activityType
isEqualToString:kSiriShortcutOpenInChrome]) {
base::RecordAction(UserMetricsAction("IOSLaunchedByOpenInChromeIntent"));
......@@ -235,14 +238,16 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) {
applicationIsActive:applicationIsActive
tabOpener:tabOpener
connectionInformation:connectionInformation
startupInformation:startupInformation];
startupInformation:startupInformation
browserState:browserState];
}
+ (BOOL)continueUserActivityURL:(NSURL*)webpageURL
applicationIsActive:(BOOL)applicationIsActive
tabOpener:(id<TabOpening>)tabOpener
connectionInformation:(id<ConnectionInformation>)connectionInformation
startupInformation:(id<StartupInformation>)startupInformation {
startupInformation:(id<StartupInformation>)startupInformation
browserState:(ChromeBrowserState*)browserState {
if (!webpageURL)
return NO;
......@@ -256,6 +261,15 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) {
ApplicationModeForTabOpening targetMode =
[[connectionInformation startupParameters] applicationMode];
UrlLoadParams params = UrlLoadParams::InNewTab(webpageGURL);
if (connectionInformation.startupParameters.textQuery) {
NSString* query = connectionInformation.startupParameters.textQuery;
GURL result = [self generateResultGURLFromSearchQuery:query
browserState:browserState];
params.web_params.url = result;
}
if (![[connectionInformation startupParameters] launchInIncognito] &&
[tabOpener URLIsOpenedInRegularMode:webpageGURL]) {
// Record metric.
......@@ -376,6 +390,25 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) {
[userActivityType isEqualToString:CSSearchableItemActionType]);
}
+ (GURL)generateResultGURLFromSearchQuery:(NSString*)searchQuery
browserState:(ChromeBrowserState*)browserState {
TemplateURLService* templateURLService =
ios::TemplateURLServiceFactory::GetForBrowserState(browserState);
const TemplateURL* defaultURL =
templateURLService->GetDefaultSearchProvider();
DCHECK(!defaultURL->url().empty());
DCHECK(
defaultURL->url_ref().IsValid(templateURLService->search_terms_data()));
base::string16 queryString = base::SysNSStringToUTF16(searchQuery);
TemplateURLRef::SearchTermsArgs search_args(queryString);
GURL result(defaultURL->url_ref().ReplaceSearchTerms(
search_args, templateURLService->search_terms_data()));
return result;
}
+ (void)handleStartupParametersWithTabOpener:(id<TabOpening>)tabOpener
connectionInformation:
(id<ConnectionInformation>)connectionInformation
......@@ -442,19 +475,8 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) {
} else if (connectionInformation.startupParameters.textQuery) {
NSString* query = connectionInformation.startupParameters.textQuery;
TemplateURLService* templateURLService =
ios::TemplateURLServiceFactory::GetForBrowserState(browserState);
const TemplateURL* defaultURL =
templateURLService->GetDefaultSearchProvider();
DCHECK(!defaultURL->url().empty());
DCHECK(defaultURL->url_ref().IsValid(
templateURLService->search_terms_data()));
base::string16 queryString = base::SysNSStringToUTF16(query);
TemplateURLRef::SearchTermsArgs search_args(queryString);
GURL result(defaultURL->url_ref().ReplaceSearchTerms(
search_args, templateURLService->search_terms_data()));
GURL result = [self generateResultGURLFromSearchQuery:query
browserState:browserState];
params.web_params.url = result;
}
......
......@@ -330,11 +330,14 @@
BOOL applicationIsActive =
[application applicationState] == UIApplicationStateActive;
return [UserActivityHandler continueUserActivity:userActivity
return [UserActivityHandler
continueUserActivity:userActivity
applicationIsActive:applicationIsActive
tabOpener:_tabOpener
connectionInformation:self.sceneController
startupInformation:_startupInformation];
startupInformation:_startupInformation
browserState:_mainController.interfaceProvider.currentInterface
.browserState];
}
- (void)application:(UIApplication*)application
......
......@@ -395,11 +395,13 @@ const char kMultiWindowOpenInNewWindowHistogram[] =
// Consider the scene as still not active at this point as the handling
// of startup parameters is not yet done (and will be later in this
// function).
[UserActivityHandler continueUserActivity:activityWithCompletion
[UserActivityHandler
continueUserActivity:activityWithCompletion
applicationIsActive:NO
tabOpener:self
connectionInformation:self
startupInformation:self.mainController];
startupInformation:self.mainController
browserState:self.currentInterface.browserState];
}
self.sceneState.connectionOptions = nil;
}
......@@ -471,7 +473,8 @@ const char kMultiWindowOpenInNewWindowHistogram[] =
applicationIsActive:sceneIsActive
tabOpener:self
connectionInformation:self
startupInformation:self.mainController];
startupInformation:self.mainController
browserState:self.currentInterface.browserState];
// It is necessary to reset the pendingUserActivity after handling it.
// Handle the reset asynchronously to avoid interfering with other observers.
dispatch_async(dispatch_get_main_queue(), ^{
......
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