Index: ios/chrome/browser/web/external_app_launcher.mm |
diff --git a/ios/chrome/browser/web/external_app_launcher.mm b/ios/chrome/browser/web/external_app_launcher.mm |
index 20b9664a179f3a04190345d615830351f03f521a..25522118172b309ab0e928fe49f58dd68f02d488 100644 |
--- a/ios/chrome/browser/web/external_app_launcher.mm |
+++ b/ios/chrome/browser/web/external_app_launcher.mm |
@@ -6,6 +6,7 @@ |
#include "base/ios/ios_util.h" |
#include "base/logging.h" |
+#include "base/mac/foundation_util.h" |
#include "base/metrics/histogram_macros.h" |
#include "base/strings/sys_string_conversions.h" |
#include "components/strings/grit/components_strings.h" |
@@ -31,12 +32,12 @@ NSSet<NSString*>* ITMSSchemes() { |
static NSSet<NSString*>* schemes; |
static dispatch_once_t once; |
dispatch_once(&once, ^{ |
- schemes = |
- [NSSet setWithObjects:@"itms", @"itmss", @"itms-apps", @"itms-appss", |
- // There's no evidence that itms-bookss is |
- // actually supported, but over-inclusion |
- // costs less than under-inclusion. |
- @"itms-books", @"itms-bookss", nil]; |
+ schemes = [NSSet<NSString*> |
+ setWithObjects:@"itms", @"itmss", @"itms-apps", @"itms-appss", |
+ // There's no evidence that itms-bookss is actually |
+ // supported, but over-inclusion costs less than |
+ // under-inclusion. |
+ @"itms-books", @"itms-bookss", nil]; |
}); |
return schemes; |
} |
@@ -70,15 +71,19 @@ NSString* PromptActionString(NSString* scheme) { |
return @""; |
} |
+// Keys for dictionary parameters passed into -openExternalAppWithPromptForURL:. |
+NSString* const kAlertPrompt = @"prompt"; |
+NSString* const kAlertAction = @"action"; |
+NSString* const kAlertURL = @"url"; |
+ |
} // namespace |
@interface ExternalAppLauncher () |
// Returns the Phone/FaceTime call argument from |URL|. |
+ (NSString*)formatCallArgument:(NSURL*)URL; |
-// Ask user for confirmation before dialing Phone or FaceTime destinations. |
-- (void)openPromptForURL:(NSURL*)URL; |
-// Ask user for confirmation before moving to external app. |
-- (void)openExternalAppWithPromptForURL:(NSURL*)URL; |
+// Asks user for confirmation before moving to external app. |params| is a |
+// dictionary keyed with values of kAlert* above. |
+- (void)openExternalAppWithPromptForURL:(NSDictionary<NSString*, id>*)params; |
Eugene But (OOO till 7-30)
2017/05/12 22:53:51
Do you use NSDictionary for passing the arguments,
pkl (ping after 24h if needed)
2017/05/12 23:16:11
As the first pass, I'm just adding the alert promp
Eugene But (OOO till 7-30)
2017/05/13 00:27:52
SG. In case if using GCD will not be possible, ple
pkl (ping after 24h if needed)
2017/05/17 22:23:02
Renamed now.
|
// Presents a configured alert controller on the root view controller. |
- (void)presentAlertControllerWithMessage:(NSString*)message |
openTitle:(NSString*)openTitle |
@@ -104,12 +109,13 @@ NSString* PromptActionString(NSString* scheme) { |
return prompt; |
} |
-- (void)openExternalAppWithPromptForURL:(NSURL*)URL { |
- NSString* message = l10n_util::GetNSString(IDS_IOS_OPEN_IN_ANOTHER_APP); |
- NSString* openTitle = |
- l10n_util::GetNSString(IDS_IOS_APP_LAUNCHER_OPEN_APP_BUTTON_LABEL); |
- [self presentAlertControllerWithMessage:message |
- openTitle:openTitle |
+- (void)openExternalAppWithPromptForURL:(NSDictionary<NSString*, id>*)params { |
+ NSURL* URL = base::mac::ObjCCastStrict<NSURL>(params[kAlertURL]); |
+ NSString* prompt = base::mac::ObjCCastStrict<NSString>(params[kAlertPrompt]); |
+ NSString* actionTitle = |
+ base::mac::ObjCCastStrict<NSString>(params[kAlertAction]); |
+ [self presentAlertControllerWithMessage:prompt |
+ openTitle:actionTitle |
openHandler:^(UIAlertAction* action) { |
RecordExternalApplicationOpened(true); |
OpenUrlWithCompletionHandler(URL, nil); |
@@ -119,15 +125,6 @@ NSString* PromptActionString(NSString* scheme) { |
}]; |
} |
-- (void)openPromptForURL:(NSURL*)URL { |
- [self presentAlertControllerWithMessage:[[self class] formatCallArgument:URL] |
- openTitle:PromptActionString(URL.scheme) |
- openHandler:^(UIAlertAction* action) { |
- OpenUrlWithCompletionHandler(URL, nil); |
- } |
- cancelHandler:nil]; |
-} |
- |
- (void)presentAlertControllerWithMessage:(NSString*)message |
openTitle:(NSString*)openTitle |
openHandler:(AlertHandler)openHandler |
@@ -156,32 +153,45 @@ NSString* PromptActionString(NSString* scheme) { |
- (BOOL)openURL:(const GURL&)gURL linkClicked:(BOOL)linkClicked { |
if (!gURL.is_valid() || !gURL.has_scheme()) |
return NO; |
- NSURL* URL = net::NSURLWithGURL(gURL); |
- |
- // iOS 10.3 introduced new prompts when facetime: and facetime-audio: |
- // URL schemes are opened. It is no longer necessary for Chrome to present |
- // another prompt before the system-provided prompt. |
- if (!base::ios::IsRunningOnOrLater(10, 3, 0) && UrlHasPhoneCallScheme(gURL)) { |
- // Showing an alert view immediately has a side-effect where focus is |
- // taken from the UIWebView so quickly that mouseup events are lost and |
- // buttons get 'stuck' in the on position. The solution is to defer |
- // showing the view. |
- [self performSelector:@selector(openPromptForURL:) |
- withObject:URL |
- afterDelay:0.0]; |
- return YES; |
- } |
// Don't open external application if chrome is not active. |
if ([[UIApplication sharedApplication] applicationState] != |
UIApplicationStateActive) |
return NO; |
- // Prompt user to open itunes when opening it is not a result of a link |
- // click. |
- if (!linkClicked && UrlHasAppStoreScheme(gURL)) { |
+ NSURL* URL = net::NSURLWithGURL(gURL); |
+ NSMutableDictionary<NSString*, id>* params = [NSMutableDictionary dictionary]; |
+ if (base::ios::IsRunningOnOrLater(10, 3, 0)) { |
+ if (UrlHasAppStoreScheme(gURL)) { |
+ params[kAlertPrompt] = |
+ l10n_util::GetNSString(IDS_IOS_OPEN_IN_ANOTHER_APP); |
+ params[kAlertAction] = |
+ l10n_util::GetNSString(IDS_IOS_APP_LAUNCHER_OPEN_APP_BUTTON_LABEL); |
+ } |
+ } else { |
rohitrao (ping after 24h)
2017/05/15 12:07:48
My understanding of this block is that:
1) On 10.3
pkl (ping after 24h if needed)
2017/05/17 22:23:02
Thank you! I've broken up the two if-statements so
|
+ // iOS 10.3 prompts user for permission when facetime: and facetime-audio: |
+ // URL schemes are opened. For pre-10.3 users, Chrome needs to present an |
+ // alert for phone calls. Prior iOS 10.3, Safari does not prompt when user |
+ // taps on an App Store links, so Chrome wouldn't prompt either. |
rohitrao (ping after 24h)
2017/05/15 12:07:48
Feature request: should we consider always prompti
pkl (ping after 24h if needed)
2017/05/17 22:23:02
I don't think it would matter, but I'd rather not
|
+ // This section can be deleted once iOS 10.3 support is dropped. |
+ if (UrlHasPhoneCallScheme(gURL)) { |
+ params[kAlertPrompt] = [[self class] formatCallArgument:URL]; |
+ params[kAlertAction] = PromptActionString([URL scheme]); |
+ } else if (!linkClicked && UrlHasAppStoreScheme(gURL)) { |
+ params[kAlertPrompt] = |
+ l10n_util::GetNSString(IDS_IOS_OPEN_IN_ANOTHER_APP); |
+ params[kAlertAction] = |
+ l10n_util::GetNSString(IDS_IOS_APP_LAUNCHER_OPEN_APP_BUTTON_LABEL); |
+ } |
+ } |
+ if ([params count] > 0) { |
+ params[kAlertURL] = URL; |
+ // Note: Showing an alert view immediately has a side-effect where focus is |
+ // taken from the UIWebView so quickly that mouseup events are lost and |
+ // buttons get 'stuck' in the on position. The solution is to defer |
+ // showing the view using -performSelector:withObject:afterDelay:. |
[self performSelector:@selector(openExternalAppWithPromptForURL:) |
- withObject:URL |
+ withObject:params |
afterDelay:0.0]; |
return YES; |
} |