Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(758)

Side by Side Diff: ios/chrome/browser/web/external_app_launcher.mm

Issue 2815403003: Don't double-prompt for uses of facetime:// and tel:// URLs. (Closed)
Patch Set: fixed typo Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ios/chrome/browser/web/external_app_launcher.h" 5 #import "ios/chrome/browser/web/external_app_launcher.h"
6 6
7 #include "base/ios/ios_util.h"
7 #include "base/ios/weak_nsobject.h" 8 #include "base/ios/weak_nsobject.h"
8 #include "base/logging.h" 9 #include "base/logging.h"
9 #include "base/metrics/histogram_macros.h" 10 #include "base/metrics/histogram_macros.h"
10 #include "base/strings/sys_string_conversions.h" 11 #include "base/strings/sys_string_conversions.h"
11 #include "components/strings/grit/components_strings.h" 12 #include "components/strings/grit/components_strings.h"
12 #include "ios/chrome/browser/experimental_flags.h" 13 #include "ios/chrome/browser/experimental_flags.h"
13 #import "ios/chrome/browser/open_url_util.h" 14 #import "ios/chrome/browser/open_url_util.h"
14 #include "ios/chrome/grit/ios_strings.h" 15 #include "ios/chrome/grit/ios_strings.h"
15 #import "net/base/mac/url_conversions.h" 16 #import "net/base/mac/url_conversions.h"
16 #include "ui/base/l10n/l10n_util.h" 17 #include "ui/base/l10n/l10n_util.h"
(...skipping 23 matching lines...) Expand all
40 return [ITMSSchemes() containsObject:base::SysUTF8ToNSString(scheme)]; 41 return [ITMSSchemes() containsObject:base::SysUTF8ToNSString(scheme)];
41 } 42 }
42 43
43 // Logs an entry for |Tab.ExternalApplicationOpened|. If the user decided to 44 // Logs an entry for |Tab.ExternalApplicationOpened|. If the user decided to
44 // open in an external app, pass true. Otherwise, if the user cancelled the 45 // open in an external app, pass true. Otherwise, if the user cancelled the
45 // opening, pass false. 46 // opening, pass false.
46 void RecordExternalApplicationOpened(bool opened) { 47 void RecordExternalApplicationOpened(bool opened) {
47 UMA_HISTOGRAM_BOOLEAN("Tab.ExternalApplicationOpened", opened); 48 UMA_HISTOGRAM_BOOLEAN("Tab.ExternalApplicationOpened", opened);
48 } 49 }
49 50
51 // Returns whether gURL has the scheme of a URL that initiates a call.
52 BOOL UrlHasPhoneCallScheme(const GURL& gURL) {
53 return gURL.SchemeIs("tel") || gURL.SchemeIs("facetime") ||
54 gURL.SchemeIs("facetime-audio");
55 }
56
57 // Returns a string to be used as the label for the prompt's action button.
58 NSString* PromptActionString(NSString* scheme) {
59 if ([scheme isEqualToString:@"facetime"])
60 return l10n_util::GetNSString(IDS_IOS_FACETIME_BUTTON);
61 else if ([scheme isEqualToString:@"tel"] ||
62 [scheme isEqualToString:@"facetime-audio"])
63 return l10n_util::GetNSString(IDS_IOS_PHONE_CALL_BUTTON);
64 NOTREACHED();
65 return @"";
66 }
67
50 } // namespace 68 } // namespace
51 69
52 @interface ExternalAppLauncher () 70 @interface ExternalAppLauncher ()
53 // Returns the Phone/FaceTime call argument from |URL|. 71 // Returns the Phone/FaceTime call argument from |URL|.
54 + (NSString*)formatCallArgument:(NSURL*)URL; 72 + (NSString*)formatCallArgument:(NSURL*)URL;
55 // Ask user for confirmation before dialing FaceTime destination. 73 // Ask user for confirmation before dialing Phone or FaceTime destinations.
56 - (void)openFaceTimePromptForURL:(NSURL*)telURL; 74 - (void)openPromptForURL:(NSURL*)URL;
57 // Ask user for confirmation before moving to external app. 75 // Ask user for confirmation before moving to external app.
58 - (void)openExternalAppWithPromptForURL:(NSURL*)URL; 76 - (void)openExternalAppWithPromptForURL:(NSURL*)URL;
59 // Presents a configured alert controller on the root view controller. 77 // Presents a configured alert controller on the root view controller.
60 - (void)presentAlertControllerWithMessage:(NSString*)message 78 - (void)presentAlertControllerWithMessage:(NSString*)message
61 openTitle:(NSString*)openTitle 79 openTitle:(NSString*)openTitle
62 openHandler:(AlertHandler)openHandler 80 openHandler:(AlertHandler)openHandler
63 cancelHandler:(AlertHandler)cancelHandler; 81 cancelHandler:(AlertHandler)cancelHandler;
64 @end 82 @end
65 83
66 @implementation ExternalAppLauncher 84 @implementation ExternalAppLauncher
(...skipping 22 matching lines...) Expand all
89 openTitle:openTitle 107 openTitle:openTitle
90 openHandler:^(UIAlertAction* action) { 108 openHandler:^(UIAlertAction* action) {
91 RecordExternalApplicationOpened(true); 109 RecordExternalApplicationOpened(true);
92 OpenUrlWithCompletionHandler(URL, nil); 110 OpenUrlWithCompletionHandler(URL, nil);
93 } 111 }
94 cancelHandler:^(UIAlertAction* action) { 112 cancelHandler:^(UIAlertAction* action) {
95 RecordExternalApplicationOpened(false); 113 RecordExternalApplicationOpened(false);
96 }]; 114 }];
97 } 115 }
98 116
99 - (void)openFaceTimePromptForURL:(NSURL*)URL { 117 - (void)openPromptForURL:(NSURL*)URL {
100 NSString* openTitle = l10n_util::GetNSString(IDS_IOS_FACETIME_BUTTON);
101 [self presentAlertControllerWithMessage:[[self class] formatCallArgument:URL] 118 [self presentAlertControllerWithMessage:[[self class] formatCallArgument:URL]
102 openTitle:openTitle 119 openTitle:PromptActionString(URL.scheme)
103 openHandler:^(UIAlertAction* action) { 120 openHandler:^(UIAlertAction* action) {
104 OpenUrlWithCompletionHandler(URL, nil); 121 OpenUrlWithCompletionHandler(URL, nil);
105 } 122 }
106 cancelHandler:nil]; 123 cancelHandler:nil];
107 } 124 }
108 125
109 - (void)presentAlertControllerWithMessage:(NSString*)message 126 - (void)presentAlertControllerWithMessage:(NSString*)message
110 openTitle:(NSString*)openTitle 127 openTitle:(NSString*)openTitle
111 openHandler:(AlertHandler)openHandler 128 openHandler:(AlertHandler)openHandler
112 cancelHandler:(AlertHandler)cancelHandler { 129 cancelHandler:(AlertHandler)cancelHandler {
(...skipping 16 matching lines...) Expand all
129 presentViewController:alertController 146 presentViewController:alertController
130 animated:YES 147 animated:YES
131 completion:nil]; 148 completion:nil];
132 } 149 }
133 150
134 - (BOOL)openURL:(const GURL&)gURL linkClicked:(BOOL)linkClicked { 151 - (BOOL)openURL:(const GURL&)gURL linkClicked:(BOOL)linkClicked {
135 if (!gURL.is_valid() || !gURL.has_scheme()) 152 if (!gURL.is_valid() || !gURL.has_scheme())
136 return NO; 153 return NO;
137 NSURL* URL = net::NSURLWithGURL(gURL); 154 NSURL* URL = net::NSURLWithGURL(gURL);
138 155
139 if (gURL.SchemeIs("facetime") || gURL.SchemeIs("facetime-audio")) { 156 // iOS 10.3.2 introduced new prompts when facetime: and facetime-audio:
157 // URL schemes are opened. It is no longer necessary for Chrome to present
158 // another prompt before the system-provided prompt.
159 if (!base::ios::IsRunningOnOrLater(10, 3, 2) && UrlHasPhoneCallScheme(gURL)) {
140 // Showing an alert view immediately has a side-effect where focus is 160 // Showing an alert view immediately has a side-effect where focus is
141 // taken from the UIWebView so quickly that mouseup events are lost and 161 // taken from the UIWebView so quickly that mouseup events are lost and
142 // buttons get 'stuck' in the on position. The solution is to defer 162 // buttons get 'stuck' in the on position. The solution is to defer
143 // showing the view. 163 // showing the view.
144 [self performSelector:@selector(openFaceTimePromptForURL:) 164 [self performSelector:@selector(openPromptForURL:)
145 withObject:URL 165 withObject:URL
146 afterDelay:0.0]; 166 afterDelay:0.0];
147 return YES; 167 return YES;
148 } 168 }
149 169
150 // Use telprompt instead of tel because telprompt returns user back to
151 // Chrome after phone call is completed/aborted.
152 if (gURL.SchemeIs("tel")) {
153 GURL::Replacements replacements;
154 replacements.SetSchemeStr("telprompt");
155 URL = net::NSURLWithGURL(gURL.ReplaceComponents(replacements));
156 DCHECK([[URL scheme] isEqualToString:@"telprompt"]);
157 }
158
159 // Don't open external application if chrome is not active. 170 // Don't open external application if chrome is not active.
160 if ([[UIApplication sharedApplication] applicationState] != 171 if ([[UIApplication sharedApplication] applicationState] !=
161 UIApplicationStateActive) 172 UIApplicationStateActive)
162 return NO; 173 return NO;
163 174
164 if (experimental_flags::IsExternalApplicationPromptEnabled()) { 175 if (experimental_flags::IsExternalApplicationPromptEnabled()) {
165 // Prompt user to open itunes when opening it is not a result of a link 176 // Prompt user to open itunes when opening it is not a result of a link
166 // click. 177 // click.
167 if (!linkClicked && UrlHasAppStoreScheme(gURL)) { 178 if (!linkClicked && UrlHasAppStoreScheme(gURL)) {
168 [self performSelector:@selector(openExternalAppWithPromptForURL:) 179 [self performSelector:@selector(openExternalAppWithPromptForURL:)
169 withObject:URL 180 withObject:URL
170 afterDelay:0.0]; 181 afterDelay:0.0];
171 return YES; 182 return YES;
172 } 183 }
173 } 184 }
174 185
175 // If the following call returns YES, an external application is about to be 186 // If the following call returns YES, an external application is about to be
176 // launched and Chrome will go into the background now. 187 // launched and Chrome will go into the background now.
177 // TODO(crbug.com/622735): This call still needs to be updated. 188 // TODO(crbug.com/622735): This call still needs to be updated.
178 // It's heavily nested so some refactoring is needed. 189 // It's heavily nested so some refactoring is needed.
179 return [[UIApplication sharedApplication] openURL:URL]; 190 return [[UIApplication sharedApplication] openURL:URL];
180 } 191 }
181 192
182 @end 193 @end
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698