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

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

Issue 2852003002: Adds mailto: URL support to app launching. (Closed)
Patch Set: s/convertLegacyOptions/migrateLegacyOptions/. Less code. 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. If this key is not set, user has not made an explicit
21 // choice for default mailto: handler and system-provided Mail client app will
22 // be used.
23 NSString* const kMailtoDefaultHandlerKey = @"MailtoHandlerDefault";
24 } // namespace
25
26 @interface MailtoURLRewriter ()
27
28 // Dictionary keyed by the App Store ID of the Mail client and the value is
29 // the MailtoHandler object that can rewrite a mailto: URL.
30 @property(nonatomic, strong)
31 NSMutableDictionary<NSString*, MailtoHandler*>* handlers;
32
33 // Private method for testing to clear the default state.
34 + (void)resetDefaultHandlerID;
35
36 // Private method to add one or more |handlerApp| objects to the list of known
37 // Mail client apps.
38 - (void)addMailtoApps:(NSArray<MailtoHandler*>*)handlerApps;
39
40 // Custom logic to handle the migration from Google Native App Launcher options
41 // to this simplified mailto: URL only system. This must be called after
42 // -addMailtoApp: has been called to add all the known Mail client apps.
43 // TODO(crbug.com/718601): At some point in the future when almost all users
44 // have upgraded, this method can be removed.
45 - (void)migrateLegacyOptions;
46
47 @end
48
49 @implementation MailtoURLRewriter
50 @synthesize handlers = _handlers;
51
52 + (NSString*)systemMailApp {
53 // This is the App Store ID for Apple Mail app.
54 // See https://itunes.apple.com/us/app/mail/id1108187098?mt=8
55 return @"1108187098";
56 }
57
58 - (instancetype)init {
59 self = [super init];
60 if (self) {
61 _handlers = [NSMutableDictionary dictionary];
62 }
63 return self;
64 }
65
66 - (instancetype)initWithStandardHandlers {
67 self = [self init];
68 if (self) {
69 [self addMailtoApps:@[
70 [[MailtoHandlerSystemMail alloc] init], [[MailtoHandlerGmail alloc] init]
71 ]];
72 }
73 return self;
74 }
75
76 - (NSArray<MailtoHandler*>*)defaultHandlers {
77 return [_handlers allValues];
78 }
79
80 - (NSString*)defaultHandlerID {
81 NSString* value = [[NSUserDefaults standardUserDefaults]
82 stringForKey:kMailtoDefaultHandlerKey];
83 return value ? value : [[self class] systemMailApp];
84 }
85
86 - (void)setDefaultHandlerID:(NSString*)appStoreID {
87 DCHECK([appStoreID length]);
88 [[NSUserDefaults standardUserDefaults] setObject:appStoreID
89 forKey:kMailtoDefaultHandlerKey];
90 }
91
92 - (NSString*)rewriteMailtoURL:(const GURL&)gURL {
93 NSString* value = [self defaultHandlerID];
94 if ([value length]) {
95 MailtoHandler* handler = _handlers[value];
96 if (handler) {
97 return [handler rewriteMailtoURL:gURL];
98 }
99 }
100 return nil;
101 }
102
103 #pragma mark - Private
104
105 + (void)resetDefaultHandlerID {
rohitrao (ping after 24h) 2017/05/10 00:09:18 What code will call this function and reset the ha
pkl (ping after 24h if needed) 2017/05/10 01:04:14 No. This is only used by unit tests. I renamed it
106 [[NSUserDefaults standardUserDefaults]
107 removeObjectForKey:kMailtoDefaultHandlerKey];
108 }
109
110 - (void)addMailtoApps:(NSArray<MailtoHandler*>*)handlerApps {
111 for (MailtoHandler* app in handlerApps) {
112 if ([app isAvailable])
113 [_handlers setObject:app forKey:[app appStoreID]];
114 }
115 [self migrateLegacyOptions];
116 }
117
118 //
119 // Implements the migration logic for users of previous versions of Google
120 // Chrome which supports Google Native App Launcher. The goal is to preserve
121 // the previous behavior and support user choice of non-system provided Mail
122 // client apps. System-provided Mail client app will be referred to as
123 // "System Mail". The migration goals are:
124 // - If a user has not made a choice for preferred mailto: handler in the past,
125 // the behavior after upgrading to this version should not change.
126 // - If a user had disabled Gmail app as the preferred mailto: handler in the
127 // past, System Mail should be selected as the default mailto: handler.
128 // - If a user installs Gmail app after the installation of Chrome, Gmail app
129 // will be chosen as the default mailto: handler, preserving the previous
130 // behavior.
131 // - If a user installs another 3rd party mail client app, assuming that the
132 // 3rd party mail client app is explicitly supported in Chrome, the new 3rd
133 // party mail client app can be set as the default mailto: handler through
134 // Tools > Settings > Content Settings.
135 //
136 // Two NSUserDefaults keys are interpreted with the following meanings:
137 // - kLegacyShouldAutoOpenKey: The existence of this key implies that the user
138 // has used Chrome in the past and had Gmail app installed. Gmail app may or
139 // may not be installed currently.
140 // - kMailtoDefaultHandlerKey: If this key is not set, System Mail app is used
141 // to handle mailto: URLs. If this key is set, the value is a string that is
142 // the key to |_handlers| which maps to a MailtoHandler object.
143 //
144 - (void)migrateLegacyOptions {
145 NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
146
147 // User previously had a selection made for opening mailto: links with Gmail,
148 // upgrade will set Gmail app to be the default mailto: handler. If user had
149 // opted out to using Gmail app (even when it was installed), migrate user
150 // to use system-provided Mail client.
151 // The key used in NSUserDefaults is from legacy code when Native App
152 // Launcher was still in use. The general format is a string prefix,
153 // underscore, then followed by the App Store ID of the application.
154 NSString* const kGmailAppStoreID = @"422689480";
155 NSString* const kLegacyShouldAutoOpenKey =
156 [NSString stringWithFormat:@"ShouldAutoOpenLinks_%@", kGmailAppStoreID];
157 NSNumber* legacyValue = [defaults objectForKey:kLegacyShouldAutoOpenKey];
158 if (legacyValue) {
159 switch ([legacyValue intValue]) {
160 case 0:
161 case 2: {
162 // If legacy user was using default (kAutoOpenLinksNotSet) or had
163 // explicitly chosen to use Gmail (kAutoOpenLinksYes), migrate to use
164 // Gmail app.
165 MailtoHandler* gmailHandler = _handlers[kGmailAppStoreID];
166 if ([gmailHandler isAvailable])
167 [defaults setObject:kGmailAppStoreID forKey:kMailtoDefaultHandlerKey];
168 else
169 [defaults removeObjectForKey:kMailtoDefaultHandlerKey];
170 break;
171 }
172 case 1:
173 // If legacy user was not using Gmail to handle mailto: links
174 // (kAutoOpenLinksNo), migrate to use system-provided Mail app.
175 [defaults removeObjectForKey:kMailtoDefaultHandlerKey];
176 break;
177 default:
178 NOTREACHED();
179 break;
180 }
181 [defaults removeObjectForKey:kLegacyShouldAutoOpenKey];
182 return;
183 }
184
185 // If a default handler for mailto: has already been registered, this means
rohitrao (ping after 24h) 2017/05/10 00:09:18 The rest of this function after this line isn't re
pkl (ping after 24h if needed) 2017/05/10 01:04:14 Done.
186 // that user had made a choice and no further migration should be done.
187 if ([defaults objectForKey:kMailtoDefaultHandlerKey])
188 return;
189
190 // For users who have not made an explict choice (kMailtoDefaultHandlerKey
rohitrao (ping after 24h) 2017/05/09 23:52:20 Typo: explicit.
rohitrao (ping after 24h) 2017/05/09 23:52:21 The absence of kMailtoDefaultHandlerKey could happ
pkl (ping after 24h if needed) 2017/05/10 00:02:19 From Settings UI, user can set Mail app as the han
pkl (ping after 24h if needed) 2017/05/10 00:02:19 Yes, will fix that.
191 // not set), if Gmail is detected, make an explicit choice for the user to
rohitrao (ping after 24h) 2017/05/09 23:52:20 If I choose to use system mail, then later install
pkl (ping after 24h if needed) 2017/05/10 00:02:19 If user has made a choice, this migration code wil
192 // use Gmail app as the default mailto: handler.
193 MailtoHandler* gmailHandler = _handlers[kGmailAppStoreID];
194 if ([gmailHandler isAvailable])
195 [defaults setObject:kGmailAppStoreID forKey:kMailtoDefaultHandlerKey];
196 }
197
198 @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