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

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

Issue 2852003002: Adds mailto: URL support to app launching. (Closed)
Patch Set: addressed comments from rohitrao and asvitkine Created 3 years, 7 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
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import "ios/chrome/browser/web/mailto_url_rewriter.h"
6
7 #import "base/logging.h"
8 #import "ios/chrome/browser/web/mailto_handler.h"
9 #import "ios/chrome/browser/web/mailto_handler_gmail.h"
10 #import "ios/chrome/browser/web/mailto_handler_system_mail.h"
11
12 #import <UIKit/UIKit.h>
13
14 #if !defined(__has_feature) || !__has_feature(objc_arc)
15 #error "This file requires ARC support."
16 #endif
17
18 namespace {
19 // The key for NSUserDefaults to store the Mail client selected to handle
20 // mailto: URL scheme.
21 NSString* const kMailtoDefaultHandlerKey = @"MailtoHandlerDefault";
22 } // namespace
23
24 @interface MailtoURLRewriter ()
25
26 // Dictionary keyed by the App Store ID of the Mail client and the value is
27 // the MailtoHandler object that can rewrite a mailto: URL.
28 @property(nonatomic, strong)
29 NSMutableDictionary<NSString*, MailtoHandler*>* handlers;
30
31 // Private method for testing to clear the default state.
32 + (void)resetDefaultHandlerID;
33
34 // Private method to add |handlerApp| to the list of know Mail client apps.
35 - (void)addMailtoApp:(MailtoHandler*)handlerApp;
36
37 // Custom logic to handle the migration from Google Native App Launcher options
38 // to this simplified mailto: URL only system. This must be called after
39 // -addMailtoApp: has been called to add all the known Mail client apps.
40 // TODO(crbug.com/718601): At some point in the future when almost all users
41 // have upgraded, this method can be removed.
42 - (void)convertLegacyOptions;
43
44 @end
45
46 @implementation MailtoURLRewriter
47 @synthesize handlers = _handlers;
48
49 + (NSString*)systemMailApp {
50 // This is the App Store ID for Apple Mail app.
51 // See https://itunes.apple.com/us/app/mail/id1108187098?mt=8
52 return @"1108187098";
53 }
54
55 - (instancetype)init {
56 self = [super init];
57 if (self) {
58 _handlers = [NSMutableDictionary dictionary];
59 }
60 return self;
61 }
62
63 - (instancetype)initWithStandardHandlers {
64 self = [self init];
65 if (self) {
66 [self addMailtoApp:[[MailtoHandlerSystemMail alloc] init]];
67 [self addMailtoApp:[[MailtoHandlerGmail alloc] init]];
68 [self convertLegacyOptions];
69 }
70 return self;
71 }
72
73 - (NSArray<MailtoHandler*>*)defaultHandlers {
74 return [_handlers allValues];
75 }
76
77 - (NSString*)defaultHandlerID {
78 NSString* value = [[NSUserDefaults standardUserDefaults]
79 stringForKey:kMailtoDefaultHandlerKey];
80 return value ? value : [[self class] systemMailApp];
81 }
82
83 - (void)setDefaultHandlerID:(NSString*)appStoreID {
84 DCHECK([appStoreID length]);
85 [[NSUserDefaults standardUserDefaults] setObject:appStoreID
86 forKey:kMailtoDefaultHandlerKey];
87 }
88
89 - (NSString*)rewriteMailtoURL:(const GURL&)gURL {
90 NSString* value = [self defaultHandlerID];
91 if ([value length]) {
92 MailtoHandler* handler = _handlers[value];
93 if (handler) {
94 return [handler rewriteMailtoURL:gURL];
95 }
96 }
97 return nil;
98 }
99
100 #pragma mark - Private
101
102 + (void)resetDefaultHandlerID {
103 [[NSUserDefaults standardUserDefaults]
104 removeObjectForKey:kMailtoDefaultHandlerKey];
105 }
106
107 - (void)addMailtoApp:(MailtoHandler*)handlerApp {
108 if ([handlerApp isAvailable])
109 [_handlers setObject:handlerApp forKey:[handlerApp appStoreID]];
110 }
111
112 // Implements the migration logic for users of previous versions of Google
113 // Chrome which supports Google Native App Launcher. The goal is to preserve
114 // the previous behavior and support user choice of non-system provided Mail
115 // client apps. System-provided Mail client app will be referred to as
116 // "System Mail". The migration goals are:
117 // - If a user has not made a choice for preferred mailto: handler in the past,
118 // the behavior after upgrading to this version should not change.
119 // - If a user had disabled Gmail app as the preferred mailto: handler in the
120 // past, System Mail should be selected as the default mailto: handler.
121 // - If a user installs Gmail app after the installation of Chrome, Gmail app
122 // will be chosen as the default mailto: handler, preserving the previous
123 // behavior.
124 // - If a user installs another 3rd party mail client app, assuming that the
125 // 3rd party mail client app is explicitly supported in Chrome, the new 3rd
126 // party mail client app can be set as the default mailto: handler through
127 // Tools > Settings > Content Settings.
128 - (void)convertLegacyOptions {
129 // If a default handler for mailto: has already been registered, this is not
130 // an upgrade case that needs to take legacy options into account.
131 NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
132 if ([defaults objectForKey:kMailtoDefaultHandlerKey])
133 return;
134
135 // The key used in NSUserDefaults is from legacy code when Native App
136 // Launcher was still in use. The general format is a string prefix,
137 // underscore, then followed by the App Store ID of the application.
138 NSString* const kGmailAppStoreID = @"422689480";
139 NSString* const kLegacyShouldAutoOpenKey =
140 [NSString stringWithFormat:@"ShouldAutoOpenLinks_%@", kGmailAppStoreID];
141
142 // If Gmail app is not installed, there is nothing to migrate.
143 MailtoHandler* gmailHandler = _handlers[kGmailAppStoreID];
144 if (!gmailHandler) {
145 // There is a stale legacy key around. This may mean that the user was using
146 // Gmail some time in the past but later uninstalled Gmail app. This clears
147 // the stale entry to start user from a clean slate again.
148 [defaults removeObjectForKey:kLegacyShouldAutoOpenKey];
149 return;
150 }
151
152 // If Gmail app is not installed or otherwise unavailable, do not make it the
153 // default mailto: handler app.
154 if (![gmailHandler isAvailable])
155 [defaults removeObjectForKey:kMailtoDefaultHandlerKey];
rohitrao (ping after 24h) 2017/05/08 18:57:50 In what cases could this line (and line 169) have
pkl (ping after 24h if needed) 2017/05/08 22:15:42 This and the previous if-clause can be merged to h
156
157 // User previously had a selection made for opening mailto: links with Gmail,
158 // upgrade will set Gmail app to be the default mailto: handler. If user had
159 // opted out to using Gmail app (even when it was installed), migrate user
160 // to use system-provided Mail client.
161 NSNumber* legacyValue = [defaults objectForKey:kLegacyShouldAutoOpenKey];
162 if (legacyValue) {
163 switch ([legacyValue intValue]) {
164 case 0: // kAutoOpenLinksNotSet
165 case 2: // kAutoOpenLinksYes
166 [defaults setObject:kGmailAppStoreID forKey:kMailtoDefaultHandlerKey];
167 break;
168 case 1: // kAutoOpenLinksNo
169 [defaults removeObjectForKey:kMailtoDefaultHandlerKey];
170 break;
171 default:
172 NOTREACHED();
173 break;
174 }
175 [defaults removeObjectForKey:kLegacyShouldAutoOpenKey];
176 } else {
177 // This is an unlikely (if not impossible) case of user not having the
178 // legacy key set at all. In this case, set the default to use Gmail app
179 // for mailto: handling.
180 [defaults setObject:kGmailAppStoreID forKey:kMailtoDefaultHandlerKey];
181 }
182 }
183
184 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/web/mailto_url_rewriter.h ('k') | ios/chrome/browser/web/mailto_url_rewriter_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698