Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 | |
| OLD | NEW |