| OLD | NEW |
| 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/native_app_launcher/native_app_navigation_controller
.h" | 5 #import "ios/chrome/browser/native_app_launcher/native_app_navigation_controller
.h" |
| 6 | 6 |
| 7 #import <StoreKit/StoreKit.h> | 7 #import <StoreKit/StoreKit.h> |
| 8 | 8 |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/metrics/user_metrics.h" | 10 #include "base/metrics/user_metrics.h" |
| 11 #include "base/metrics/user_metrics_action.h" | 11 #include "base/metrics/user_metrics_action.h" |
| 12 #include "base/threading/sequenced_worker_pool.h" | 12 #include "base/threading/sequenced_worker_pool.h" |
| 13 #include "components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h" | 13 #include "components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h" |
| 14 #include "components/infobars/core/infobar_manager.h" | 14 #include "components/infobars/core/infobar_manager.h" |
| 15 #include "ios/chrome/browser/infobars/infobar_manager_impl.h" | 15 #include "ios/chrome/browser/infobars/infobar_manager_impl.h" |
| 16 #import "ios/chrome/browser/installation_notifier.h" | 16 #import "ios/chrome/browser/installation_notifier.h" |
| 17 #include "ios/chrome/browser/native_app_launcher/native_app_infobar_delegate.h" | 17 #include "ios/chrome/browser/native_app_launcher/native_app_infobar_delegate.h" |
| 18 #import "ios/chrome/browser/native_app_launcher/native_app_navigation_controller
_protocol.h" |
| 18 #include "ios/chrome/browser/native_app_launcher/native_app_navigation_util.h" | 19 #include "ios/chrome/browser/native_app_launcher/native_app_navigation_util.h" |
| 19 #import "ios/chrome/browser/open_url_util.h" | 20 #import "ios/chrome/browser/open_url_util.h" |
| 20 #import "ios/chrome/browser/tabs/tab.h" | 21 #import "ios/chrome/browser/tabs/tab.h" |
| 21 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" | 22 #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" |
| 22 #import "ios/public/provider/chrome/browser/native_app_launcher/native_app_metad
ata.h" | 23 #import "ios/public/provider/chrome/browser/native_app_launcher/native_app_metad
ata.h" |
| 23 #import "ios/public/provider/chrome/browser/native_app_launcher/native_app_types
.h" | 24 #import "ios/public/provider/chrome/browser/native_app_launcher/native_app_types
.h" |
| 24 #import "ios/public/provider/chrome/browser/native_app_launcher/native_app_white
list_manager.h" | 25 #import "ios/public/provider/chrome/browser/native_app_launcher/native_app_white
list_manager.h" |
| 25 #include "ios/web/public/web_state/web_state.h" | 26 #include "ios/web/public/web_state/web_state.h" |
| 27 #import "ios/web/public/web_state/web_state_observer_bridge.h" |
| 26 #include "ios/web/public/web_thread.h" | 28 #include "ios/web/public/web_thread.h" |
| 27 #import "ios/web/web_state/ui/crw_web_controller.h" | |
| 28 #import "net/base/mac/url_conversions.h" | 29 #import "net/base/mac/url_conversions.h" |
| 29 | 30 |
| 30 #if !defined(__has_feature) || !__has_feature(objc_arc) | 31 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 31 #error "This file requires ARC support." | 32 #error "This file requires ARC support." |
| 32 #endif | 33 #endif |
| 33 | 34 |
| 34 using base::UserMetricsAction; | 35 using base::UserMetricsAction; |
| 35 | 36 |
| 36 @interface NativeAppNavigationController () | 37 @interface NativeAppNavigationController ()< |
| 38 CRWWebStateObserver, |
| 39 NativeAppNavigationControllerProtocol> |
| 37 // Shows a native app infobar by looking at the page's URL and by checking | 40 // Shows a native app infobar by looking at the page's URL and by checking |
| 38 // wheter that infobar should be bypassed or not. | 41 // wheter that infobar should be bypassed or not. |
| 39 - (void)showInfoBarIfNecessary; | 42 - (void)showInfoBarIfNecessary; |
| 40 | 43 |
| 41 // Returns a pointer to the NSMutableSet of |_appsPossiblyBeingInstalled| | 44 // Returns a pointer to the NSMutableSet of |_appsPossiblyBeingInstalled| |
| 42 - (NSMutableSet*)appsPossiblyBeingInstalled; | 45 - (NSMutableSet*)appsPossiblyBeingInstalled; |
| 43 | 46 |
| 44 // Records what type of infobar was opened. | 47 // Records what type of infobar was opened. |
| 45 - (void)recordInfobarDisplayedOfType:(NativeAppControllerType)type | 48 - (void)recordInfobarDisplayedOfType:(NativeAppControllerType)type |
| 46 onLinkNavigation:(BOOL)isLinkNavigation; | 49 onLinkNavigation:(BOOL)isLinkNavigation; |
| 47 | 50 |
| 48 @end | 51 @end |
| 49 | 52 |
| 50 @implementation NativeAppNavigationController { | 53 @implementation NativeAppNavigationController { |
| 51 // WebState provides access to the *TabHelper objects. This will eventually | 54 // WebState provides access to the *TabHelper objects. This will eventually |
| 52 // replace the need to have |_tab| in this object. | 55 // replace the need to have |_tab| in this object. |
| 53 web::WebState* _webState; | 56 web::WebState* _webState; |
| 54 // ImageFetcher needed to fetch the icons. | 57 // ImageFetcher needed to fetch the icons. |
| 55 std::unique_ptr<image_fetcher::IOSImageDataFetcherWrapper> _imageFetcher; | 58 std::unique_ptr<image_fetcher::IOSImageDataFetcherWrapper> _imageFetcher; |
| 56 // DEPRECATED: Tab hosting the infobar and is also used for accessing Tab | 59 // DEPRECATED: Tab hosting the infobar and is also used for accessing Tab |
| 57 // states such as navigation manager and whether it is a pre-rendered tab. | 60 // states such as navigation manager and whether it is a pre-rendered tab. |
| 58 // Use |webState| whenever possible. | 61 // Use |webState| whenever possible. |
| 59 __weak Tab* _tab; | 62 __weak Tab* _tab; |
| 60 id<NativeAppMetadata> _metadata; | 63 id<NativeAppMetadata> _metadata; |
| 61 // A set of appIds encoded as NSStrings. | 64 // A set of appIds encoded as NSStrings. |
| 62 NSMutableSet* _appsPossiblyBeingInstalled; | 65 NSMutableSet* _appsPossiblyBeingInstalled; |
| 66 // Allows this class to subscribe for CRWWebStateObserver callbacks. |
| 67 std::unique_ptr<web::WebStateObserverBridge> _webStateObserver; |
| 63 } | 68 } |
| 64 | 69 |
| 65 // Designated initializer. Use this instead of -init. | 70 // Designated initializer. Use this instead of -init. |
| 66 - (instancetype)initWithWebState:(web::WebState*)webState | 71 - (instancetype)initWithWebState:(web::WebState*)webState |
| 67 requestContextGetter:(net::URLRequestContextGetter*)context | 72 requestContextGetter:(net::URLRequestContextGetter*)context |
| 68 tab:(Tab*)tab { | 73 tab:(Tab*)tab { |
| 69 self = [super init]; | 74 self = [super init]; |
| 70 if (self) { | 75 if (self) { |
| 71 DCHECK(context); | 76 DCHECK(context); |
| 72 _imageFetcher = base::MakeUnique<image_fetcher::IOSImageDataFetcherWrapper>( | 77 _imageFetcher = base::MakeUnique<image_fetcher::IOSImageDataFetcherWrapper>( |
| 73 context, web::WebThread::GetBlockingPool()); | 78 context, web::WebThread::GetBlockingPool()); |
| 74 DCHECK(webState); | 79 DCHECK(webState); |
| 75 _webState = webState; | 80 _webState = webState; |
| 76 // Allows |tab| to be nil for unit testing. If not nil, it should have the | 81 // Allows |tab| to be nil for unit testing. If not nil, it should have the |
| 77 // same webState. | 82 // same webState. |
| 78 DCHECK(!tab || [tab webState] == webState); | 83 DCHECK(!tab || [tab webState] == webState); |
| 79 _tab = tab; | 84 _tab = tab; |
| 80 _appsPossiblyBeingInstalled = [[NSMutableSet alloc] init]; | 85 _appsPossiblyBeingInstalled = [[NSMutableSet alloc] init]; |
| 86 _webStateObserver = |
| 87 base::MakeUnique<web::WebStateObserverBridge>(webState, self); |
| 81 } | 88 } |
| 82 return self; | 89 return self; |
| 83 } | 90 } |
| 84 | 91 |
| 85 - (void)copyStateFrom:(NativeAppNavigationController*)controller { | 92 - (void)copyStateFrom:(NativeAppNavigationController*)controller { |
| 86 DCHECK(controller); | 93 DCHECK(controller); |
| 87 _appsPossiblyBeingInstalled = [[NSMutableSet alloc] | 94 _appsPossiblyBeingInstalled = [[NSMutableSet alloc] |
| 88 initWithSet:[controller appsPossiblyBeingInstalled]]; | 95 initWithSet:[controller appsPossiblyBeingInstalled]]; |
| 89 for (NSString* appIdString in _appsPossiblyBeingInstalled) { | 96 for (NSString* appIdString in _appsPossiblyBeingInstalled) { |
| 90 DCHECK([appIdString isKindOfClass:[NSString class]]); | 97 DCHECK([appIdString isKindOfClass:[NSString class]]); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 break; | 159 break; |
| 153 case NATIVE_APP_OPEN_POLICY_CONTROLLER: | 160 case NATIVE_APP_OPEN_POLICY_CONTROLLER: |
| 154 base::RecordAction(UserMetricsAction("MobileGALOpenPolicyInfoBar")); | 161 base::RecordAction(UserMetricsAction("MobileGALOpenPolicyInfoBar")); |
| 155 break; | 162 break; |
| 156 default: | 163 default: |
| 157 NOTREACHED(); | 164 NOTREACHED(); |
| 158 break; | 165 break; |
| 159 } | 166 } |
| 160 } | 167 } |
| 161 | 168 |
| 162 #pragma mark - | 169 #pragma mark - NativeAppNavigationControllerProtocol methods |
| 163 #pragma mark NativeAppNavigationControllerProtocol methods | |
| 164 | 170 |
| 165 - (NSString*)appId { | 171 - (NSString*)appId { |
| 166 return [_metadata appId]; | 172 return [_metadata appId]; |
| 167 } | 173 } |
| 168 | 174 |
| 169 - (NSString*)appName { | 175 - (NSString*)appName { |
| 170 return [_metadata appName]; | 176 return [_metadata appName]; |
| 171 } | 177 } |
| 172 | 178 |
| 173 - (void)fetchSmallIconWithCompletionBlock:(void (^)(UIImage*))block { | 179 - (void)fetchSmallIconWithCompletionBlock:(void (^)(UIImage*))block { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 199 GURL launchURL([_metadata launchURLWithURL:URL identity:nil]); | 205 GURL launchURL([_metadata launchURLWithURL:URL identity:nil]); |
| 200 if (launchURL.is_valid()) { | 206 if (launchURL.is_valid()) { |
| 201 OpenUrlWithCompletionHandler(net::NSURLWithGURL(launchURL), nil); | 207 OpenUrlWithCompletionHandler(net::NSURLWithGURL(launchURL), nil); |
| 202 } | 208 } |
| 203 } | 209 } |
| 204 | 210 |
| 205 - (void)updateMetadataWithUserAction:(NativeAppActionType)userAction { | 211 - (void)updateMetadataWithUserAction:(NativeAppActionType)userAction { |
| 206 [_metadata updateWithUserAction:userAction]; | 212 [_metadata updateWithUserAction:userAction]; |
| 207 } | 213 } |
| 208 | 214 |
| 209 #pragma mark - | 215 #pragma mark - CRWWebStateObserver methods |
| 210 #pragma mark CRWWebControllerObserver methods | |
| 211 | 216 |
| 212 - (void)pageLoaded:(CRWWebController*)webController { | 217 - (void)webState:(web::WebState*)webState didLoadPageWithSuccess:(BOOL)success { |
| 213 if (![_tab isPrerenderTab]) | 218 if (success && ![_tab isPrerenderTab]) |
| 214 [self showInfoBarIfNecessary]; | 219 [self showInfoBarIfNecessary]; |
| 215 } | 220 } |
| 216 | 221 |
| 217 - (void)webControllerWillClose:(CRWWebController*)webController { | 222 - (void)webStateDestroyed:(web::WebState*)webState { |
| 218 [webController removeObserver:self]; | 223 _webState = nullptr; |
| 224 _webStateObserver.reset(); |
| 219 } | 225 } |
| 220 | 226 |
| 227 #pragma mark - Private methods |
| 228 |
| 221 - (void)appDidInstall:(NSNotification*)notification { | 229 - (void)appDidInstall:(NSNotification*)notification { |
| 222 [self removeAppFromNotification:notification]; | 230 [self removeAppFromNotification:notification]; |
| 223 [self showInfoBarIfNecessary]; | 231 [self showInfoBarIfNecessary]; |
| 224 } | 232 } |
| 225 | 233 |
| 226 - (void)removeAppFromNotification:(NSNotification*)notification { | 234 - (void)removeAppFromNotification:(NSNotification*)notification { |
| 227 DCHECK([[notification object] isKindOfClass:[InstallationNotifier class]]); | 235 DCHECK([[notification object] isKindOfClass:[InstallationNotifier class]]); |
| 228 NSString* schemeOfInstalledApp = [notification name]; | 236 NSString* schemeOfInstalledApp = [notification name]; |
| 229 __block NSString* appIDToRemove = nil; | 237 __block NSString* appIDToRemove = nil; |
| 230 [_appsPossiblyBeingInstalled | 238 [_appsPossiblyBeingInstalled |
| 231 enumerateObjectsUsingBlock:^(id appID, BOOL* stop) { | 239 enumerateObjectsUsingBlock:^(id appID, BOOL* stop) { |
| 232 NSURL* appURL = | 240 NSURL* appURL = |
| 233 [ios::GetChromeBrowserProvider()->GetNativeAppWhitelistManager() | 241 [ios::GetChromeBrowserProvider()->GetNativeAppWhitelistManager() |
| 234 schemeForAppId:appID]; | 242 schemeForAppId:appID]; |
| 235 if ([[appURL scheme] isEqualToString:schemeOfInstalledApp]) { | 243 if ([[appURL scheme] isEqualToString:schemeOfInstalledApp]) { |
| 236 appIDToRemove = appID; | 244 appIDToRemove = appID; |
| 237 *stop = YES; | 245 *stop = YES; |
| 238 } | 246 } |
| 239 }]; | 247 }]; |
| 240 DCHECK(appIDToRemove); | 248 DCHECK(appIDToRemove); |
| 241 [_appsPossiblyBeingInstalled removeObject:appIDToRemove]; | 249 [_appsPossiblyBeingInstalled removeObject:appIDToRemove]; |
| 242 } | 250 } |
| 243 | 251 |
| 244 @end | 252 @end |
| OLD | NEW |