Commit e5e97fd7 authored by Justin Cohen's avatar Justin Cohen Committed by Commit Bot

[ios] Handle intents triggered in the foreground too.

The intent handler for SearchInChromeIntent and OpenInChromeIntent both
assumed the intents would only happen while the app was backgrounded.
This worked since that's usually true, and the startupInformation would
be processed when the app was foregrounded.

However, OpenInChromeIntents can be chained, and presumably this is also
true for SearchInChromeIntent, which means the first in the chain will
trigger while the app is backgrounded, and the remainder when the app is
in the foreground.

Instead of assuming the foregrounding step will process
startupInformation, let the logic flow to -continueUserActivityURL.

Bug: 1051783
Change-Id: Ia61334ac33995030744c1316f5accef2eae15b21
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2062097Reviewed-by: default avatarOlivier Robin <olivierrobin@chromium.org>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Commit-Queue: Justin Cohen <justincohen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#743160}
parent e059f26c
...@@ -38,6 +38,7 @@ source_set("unit_tests") { ...@@ -38,6 +38,7 @@ source_set("unit_tests") {
"//ios/chrome/app", "//ios/chrome/app",
"//ios/chrome/app:app_internal", "//ios/chrome/app:app_internal",
"//ios/chrome/app:mode", "//ios/chrome/app:mode",
"//ios/chrome/app/intents",
"//ios/chrome/app/spotlight", "//ios/chrome/app/spotlight",
"//ios/chrome/app/startup", "//ios/chrome/app/startup",
"//ios/chrome/browser", "//ios/chrome/browser",
......
...@@ -142,7 +142,8 @@ NSString* const kShortcutQRScanner = @"OpenQRScanner"; ...@@ -142,7 +142,8 @@ NSString* const kShortcutQRScanner = @"OpenQRScanner";
completeURL:GURL(kChromeUINewTabURL)]; completeURL:GURL(kChromeUINewTabURL)];
[startupParams setPostOpeningAction:FOCUS_OMNIBOX]; [startupParams setPostOpeningAction:FOCUS_OMNIBOX];
[startupInformation setStartupParameters:startupParams]; [startupInformation setStartupParameters:startupParams];
return YES; webpageURL =
[NSURL URLWithString:base::SysUTF8ToNSString(kChromeUINewTabURL)];
} else if ([userActivity.activityType } else if ([userActivity.activityType
isEqualToString:@"OpenInChromeIntent"]) { isEqualToString:@"OpenInChromeIntent"]) {
base::RecordAction(UserMetricsAction("IOSLaunchedByOpenInChromeIntent")); base::RecordAction(UserMetricsAction("IOSLaunchedByOpenInChromeIntent"));
...@@ -159,7 +160,7 @@ NSString* const kShortcutQRScanner = @"OpenQRScanner"; ...@@ -159,7 +160,7 @@ NSString* const kShortcutQRScanner = @"OpenQRScanner";
[[AppStartupParameters alloc] initWithExternalURL:webpageGURL [[AppStartupParameters alloc] initWithExternalURL:webpageGURL
completeURL:webpageGURL]; completeURL:webpageGURL];
[startupInformation setStartupParameters:startupParams]; [startupInformation setStartupParameters:startupParams];
return YES; webpageURL = intent.url;
} else { } else {
// Do nothing for unknown activity type. // Do nothing for unknown activity type.
return NO; return NO;
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "ios/chrome/app/application_delegate/startup_information.h" #include "ios/chrome/app/application_delegate/startup_information.h"
#include "ios/chrome/app/application_delegate/tab_opening.h" #include "ios/chrome/app/application_delegate/tab_opening.h"
#include "ios/chrome/app/application_mode.h" #include "ios/chrome/app/application_mode.h"
#import "ios/chrome/app/intents/OpenInChromeIntent.h"
#include "ios/chrome/app/main_controller.h" #include "ios/chrome/app/main_controller.h"
#include "ios/chrome/app/spotlight/actions_spotlight_manager.h" #include "ios/chrome/app/spotlight/actions_spotlight_manager.h"
#import "ios/chrome/app/spotlight/spotlight_util.h" #import "ios/chrome/app/spotlight/spotlight_util.h"
...@@ -46,6 +47,11 @@ ...@@ -46,6 +47,11 @@
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #endif
// Override readonly property for testing.
@interface NSUserActivity (IntentsTesting)
@property(readwrite, nullable, NS_NONATOMIC_IOSONLY) INInteraction* interaction;
@end
// Substitutes U2FTabHelper for testing. // Substitutes U2FTabHelper for testing.
class FakeU2FTabHelper : public U2FTabHelper { class FakeU2FTabHelper : public U2FTabHelper {
public: public:
...@@ -455,6 +461,85 @@ TEST_F(UserActivityHandlerTest, ContinueUserActivityShortcutActions) { ...@@ -455,6 +461,85 @@ TEST_F(UserActivityHandlerTest, ContinueUserActivityShortcutActions) {
} }
} }
// Tests that Chrome responds to open intents in the background.
TEST_F(UserActivityHandlerTest, ContinueUserActivityIntentBackground) {
NSUserActivity* userActivity =
[[NSUserActivity alloc] initWithActivityType:@"OpenInChromeIntent"];
OpenInChromeIntent* intent = [[OpenInChromeIntent alloc] init];
NSURL* nsurl = [NSURL URLWithString:@"http://www.google.com"];
intent.url = nsurl;
INInteraction* interaction = [[INInteraction alloc] initWithIntent:intent
response:nil];
userActivity.interaction = interaction;
id startupInformationMock =
[OCMockObject niceMockForProtocol:@protocol(StartupInformation)];
[[startupInformationMock expect]
setStartupParameters:[OCMArg checkWithBlock:^BOOL(id value) {
EXPECT_TRUE([value isKindOfClass:[AppStartupParameters class]]);
AppStartupParameters* startupParameters = (AppStartupParameters*)value;
const GURL calledURL = startupParameters.externalURL;
return calledURL == net::GURLWithNSURL(nsurl);
}]];
// The test will fail if a method of this object is called.
id tabOpenerMock = [OCMockObject mockForProtocol:@protocol(TabOpening)];
// Action.
BOOL result =
[UserActivityHandler continueUserActivity:userActivity
applicationIsActive:NO
tabOpener:tabOpenerMock
startupInformation:startupInformationMock];
// Test.
EXPECT_OCMOCK_VERIFY(startupInformationMock);
EXPECT_TRUE(result);
}
// Tests that Chrome responds to open intents in the foreground.
TEST_F(UserActivityHandlerTest, ContinueUserActivityIntentForeground) {
GURL gurl("http://www.google.com");
NSUserActivity* userActivity =
[[NSUserActivity alloc] initWithActivityType:@"OpenInChromeIntent"];
OpenInChromeIntent* intent = [[OpenInChromeIntent alloc] init];
intent.url = net::NSURLWithGURL(gurl);
INInteraction* interaction = [[INInteraction alloc] initWithIntent:intent
response:nil];
userActivity.interaction = interaction;
id startupInformationMock =
[OCMockObject niceMockForProtocol:@protocol(StartupInformation)];
[[startupInformationMock expect]
setStartupParameters:[OCMArg checkWithBlock:^BOOL(id value) {
EXPECT_TRUE([value isKindOfClass:[AppStartupParameters class]]);
AppStartupParameters* startupParameters = (AppStartupParameters*)value;
const GURL calledURL = startupParameters.externalURL;
return calledURL == net::GURLWithNSURL(intent.url);
}]];
[[[startupInformationMock stub] andReturnValue:@NO] isPresentingFirstRunUI];
MockTabOpener* tabOpener = [[MockTabOpener alloc] init];
AppStartupParameters* startupParams =
[[AppStartupParameters alloc] initWithExternalURL:gurl completeURL:gurl];
[[[startupInformationMock stub] andReturn:startupParams] startupParameters];
// Action.
BOOL result =
[UserActivityHandler continueUserActivity:userActivity
applicationIsActive:YES
tabOpener:tabOpener
startupInformation:startupInformationMock];
// Test.
EXPECT_EQ(gurl, tabOpener.urlLoadParams.web_params.url);
EXPECT_TRUE(tabOpener.urlLoadParams.web_params.virtual_url.is_empty());
EXPECT_TRUE(result);
}
// Tests that handleStartupParameters with a file url. "external URL" gets // Tests that handleStartupParameters with a file url. "external URL" gets
// rewritten to chrome://URL, while "complete URL" remains full local file URL. // rewritten to chrome://URL, while "complete URL" remains full local file URL.
TEST_F(UserActivityHandlerTest, HandleStartupParamsWithExternalFile) { TEST_F(UserActivityHandlerTest, HandleStartupParamsWithExternalFile) {
......
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