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; ...@@ -20,13 +20,16 @@ class ChromeBrowserState;
@interface UserActivityHandler : NSObject @interface UserActivityHandler : NSObject
// If the userActivity is a Handoff or an opening from Spotlight, opens a new // If the userActivity is a Handoff or an opening from Spotlight, opens a new
// tab or setup startupParameters to open it later. // tab or setup startupParameters to open it later. If a new tab must be
// Returns wether it could continue userActivity. // 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 + (BOOL)continueUserActivity:(NSUserActivity*)userActivity
applicationIsActive:(BOOL)applicationIsActive applicationIsActive:(BOOL)applicationIsActive
tabOpener:(id<TabOpening>)tabOpener tabOpener:(id<TabOpening>)tabOpener
connectionInformation:(id<ConnectionInformation>)connectionInformation 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, // Handles the 3D touch application static items. If the First Run UI is active,
// |completionHandler| will be called with NO. // |completionHandler| will be called with NO.
......
...@@ -89,7 +89,8 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) { ...@@ -89,7 +89,8 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) {
applicationIsActive:(BOOL)applicationIsActive applicationIsActive:(BOOL)applicationIsActive
tabOpener:(id<TabOpening>)tabOpener tabOpener:(id<TabOpening>)tabOpener
connectionInformation:(id<ConnectionInformation>)connectionInformation connectionInformation:(id<ConnectionInformation>)connectionInformation
startupInformation:(id<StartupInformation>)startupInformation { startupInformation:(id<StartupInformation>)startupInformation
browserState:(ChromeBrowserState*)browserState {
NSURL* webpageURL = userActivity.webpageURL; NSURL* webpageURL = userActivity.webpageURL;
if ([userActivity.activityType if ([userActivity.activityType
...@@ -151,7 +152,8 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) { ...@@ -151,7 +152,8 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) {
applicationIsActive:isActive applicationIsActive:isActive
tabOpener:tabOpener tabOpener:tabOpener
connectionInformation:connectionInformation connectionInformation:connectionInformation
startupInformation:startupInformation]; startupInformation:startupInformation
browserState:browserState];
}); });
}); });
return YES; return YES;
...@@ -179,6 +181,7 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) { ...@@ -179,6 +181,7 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) {
[connectionInformation setStartupParameters:startupParams]; [connectionInformation setStartupParameters:startupParams];
webpageURL = webpageURL =
[NSURL URLWithString:base::SysUTF8ToNSString(kChromeUINewTabURL)]; [NSURL URLWithString:base::SysUTF8ToNSString(kChromeUINewTabURL)];
} else if ([userActivity.activityType } else if ([userActivity.activityType
isEqualToString:kSiriShortcutOpenInChrome]) { isEqualToString:kSiriShortcutOpenInChrome]) {
base::RecordAction(UserMetricsAction("IOSLaunchedByOpenInChromeIntent")); base::RecordAction(UserMetricsAction("IOSLaunchedByOpenInChromeIntent"));
...@@ -235,14 +238,16 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) { ...@@ -235,14 +238,16 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) {
applicationIsActive:applicationIsActive applicationIsActive:applicationIsActive
tabOpener:tabOpener tabOpener:tabOpener
connectionInformation:connectionInformation connectionInformation:connectionInformation
startupInformation:startupInformation]; startupInformation:startupInformation
browserState:browserState];
} }
+ (BOOL)continueUserActivityURL:(NSURL*)webpageURL + (BOOL)continueUserActivityURL:(NSURL*)webpageURL
applicationIsActive:(BOOL)applicationIsActive applicationIsActive:(BOOL)applicationIsActive
tabOpener:(id<TabOpening>)tabOpener tabOpener:(id<TabOpening>)tabOpener
connectionInformation:(id<ConnectionInformation>)connectionInformation connectionInformation:(id<ConnectionInformation>)connectionInformation
startupInformation:(id<StartupInformation>)startupInformation { startupInformation:(id<StartupInformation>)startupInformation
browserState:(ChromeBrowserState*)browserState {
if (!webpageURL) if (!webpageURL)
return NO; return NO;
...@@ -256,6 +261,15 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) { ...@@ -256,6 +261,15 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) {
ApplicationModeForTabOpening targetMode = ApplicationModeForTabOpening targetMode =
[[connectionInformation startupParameters] applicationMode]; [[connectionInformation startupParameters] applicationMode];
UrlLoadParams params = UrlLoadParams::InNewTab(webpageGURL); 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] && if (![[connectionInformation startupParameters] launchInIncognito] &&
[tabOpener URLIsOpenedInRegularMode:webpageGURL]) { [tabOpener URLIsOpenedInRegularMode:webpageGURL]) {
// Record metric. // Record metric.
...@@ -376,6 +390,25 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) { ...@@ -376,6 +390,25 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) {
[userActivityType isEqualToString:CSSearchableItemActionType]); [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 + (void)handleStartupParametersWithTabOpener:(id<TabOpening>)tabOpener
connectionInformation: connectionInformation:
(id<ConnectionInformation>)connectionInformation (id<ConnectionInformation>)connectionInformation
...@@ -442,19 +475,8 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) { ...@@ -442,19 +475,8 @@ std::vector<GURL> createGURLVectorFromIntentURLs(NSArray<NSURL*>* intentURLs) {
} else if (connectionInformation.startupParameters.textQuery) { } else if (connectionInformation.startupParameters.textQuery) {
NSString* query = connectionInformation.startupParameters.textQuery; NSString* query = connectionInformation.startupParameters.textQuery;
TemplateURLService* templateURLService = GURL result = [self generateResultGURLFromSearchQuery:query
ios::TemplateURLServiceFactory::GetForBrowserState(browserState); browserState: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()));
params.web_params.url = result; params.web_params.url = result;
} }
......
...@@ -330,11 +330,14 @@ ...@@ -330,11 +330,14 @@
BOOL applicationIsActive = BOOL applicationIsActive =
[application applicationState] == UIApplicationStateActive; [application applicationState] == UIApplicationStateActive;
return [UserActivityHandler continueUserActivity:userActivity return [UserActivityHandler
applicationIsActive:applicationIsActive continueUserActivity:userActivity
tabOpener:_tabOpener applicationIsActive:applicationIsActive
connectionInformation:self.sceneController tabOpener:_tabOpener
startupInformation:_startupInformation]; connectionInformation:self.sceneController
startupInformation:_startupInformation
browserState:_mainController.interfaceProvider.currentInterface
.browserState];
} }
- (void)application:(UIApplication*)application - (void)application:(UIApplication*)application
......
...@@ -395,11 +395,13 @@ const char kMultiWindowOpenInNewWindowHistogram[] = ...@@ -395,11 +395,13 @@ const char kMultiWindowOpenInNewWindowHistogram[] =
// Consider the scene as still not active at this point as the handling // 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 // of startup parameters is not yet done (and will be later in this
// function). // function).
[UserActivityHandler continueUserActivity:activityWithCompletion [UserActivityHandler
applicationIsActive:NO continueUserActivity:activityWithCompletion
tabOpener:self applicationIsActive:NO
connectionInformation:self tabOpener:self
startupInformation:self.mainController]; connectionInformation:self
startupInformation:self.mainController
browserState:self.currentInterface.browserState];
} }
self.sceneState.connectionOptions = nil; self.sceneState.connectionOptions = nil;
} }
...@@ -471,7 +473,8 @@ const char kMultiWindowOpenInNewWindowHistogram[] = ...@@ -471,7 +473,8 @@ const char kMultiWindowOpenInNewWindowHistogram[] =
applicationIsActive:sceneIsActive applicationIsActive:sceneIsActive
tabOpener:self tabOpener:self
connectionInformation:self connectionInformation:self
startupInformation:self.mainController]; startupInformation:self.mainController
browserState:self.currentInterface.browserState];
// It is necessary to reset the pendingUserActivity after handling it. // It is necessary to reset the pendingUserActivity after handling it.
// Handle the reset asynchronously to avoid interfering with other observers. // Handle the reset asynchronously to avoid interfering with other observers.
dispatch_async(dispatch_get_main_queue(), ^{ 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