Index: ios/chrome/browser/ui/settings/native_apps_collection_view_controller.mm |
diff --git a/ios/chrome/browser/ui/settings/native_apps_collection_view_controller.mm b/ios/chrome/browser/ui/settings/native_apps_collection_view_controller.mm |
deleted file mode 100644 |
index 68602f5d12ed963218e85afbbdeed9b2cd38bc6d..0000000000000000000000000000000000000000 |
--- a/ios/chrome/browser/ui/settings/native_apps_collection_view_controller.mm |
+++ /dev/null |
@@ -1,405 +0,0 @@ |
-// Copyright 2015 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#import "ios/chrome/browser/ui/settings/native_apps_collection_view_controller.h" |
-#import "ios/chrome/browser/ui/settings/native_apps_collection_view_controller_private.h" |
- |
-#import <StoreKit/StoreKit.h> |
- |
-#include "base/logging.h" |
-#import "base/mac/foundation_util.h" |
-#include "base/memory/ptr_util.h" |
-#include "base/metrics/histogram_macros.h" |
-#include "base/metrics/user_metrics.h" |
-#include "base/metrics/user_metrics_action.h" |
-#include "base/strings/sys_string_conversions.h" |
-#include "base/threading/sequenced_worker_pool.h" |
-#include "components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h" |
-#import "ios/chrome/browser/installation_notifier.h" |
-#import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h" |
-#import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item.h" |
-#import "ios/chrome/browser/ui/collection_view/collection_view_model.h" |
-#import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h" |
-#import "ios/chrome/browser/ui/settings/cells/native_app_item.h" |
-#import "ios/chrome/browser/ui/settings/settings_utils.h" |
-#import "ios/chrome/common/string_util.h" |
-#include "ios/chrome/grit/ios_strings.h" |
-#import "ios/public/provider/chrome/browser/chrome_browser_provider.h" |
-#import "ios/public/provider/chrome/browser/native_app_launcher/native_app_metadata.h" |
-#import "ios/public/provider/chrome/browser/native_app_launcher/native_app_whitelist_manager.h" |
-#import "ios/third_party/material_components_ios/src/components/Buttons/src/MaterialButtons.h" |
-#include "ios/web/public/web_thread.h" |
-#include "ui/base/l10n/l10n_util.h" |
-#include "url/gurl.h" |
- |
-#if !defined(__has_feature) || !__has_feature(objc_arc) |
-#error "This file requires ARC support." |
-#endif |
- |
-const NSInteger kTagShift = 1000; |
- |
-namespace { |
- |
-typedef NS_ENUM(NSInteger, SectionIdentifier) { |
- SectionIdentifierLearnMore = kSectionIdentifierEnumZero, |
- SectionIdentifierApps, |
-}; |
- |
-typedef NS_ENUM(NSInteger, ItemType) { |
- ItemTypeApp = kItemTypeEnumZero, |
- ItemTypeLearnMore, |
-}; |
- |
-} // namespace |
- |
-@interface NativeAppsCollectionViewController ()< |
- SKStoreProductViewControllerDelegate> { |
- std::unique_ptr<image_fetcher::IOSImageDataFetcherWrapper> _imageFetcher; |
- NSArray* _nativeAppsInSettings; |
- BOOL _userDidSomething; |
-} |
- |
-// List of the native apps visible in Settings. |
-@property(nonatomic, copy) NSArray* appsInSettings; |
- |
-// Delegate for App-Store-related operations. |
-@property(nonatomic, weak) id<StoreKitLauncher> storeKitLauncher; |
- |
-// Sets up the list of visible apps based on |nativeAppWhitelistManager|, which |
-// serves as datasource for this controller. Apps from |
-// |nativeAppWhitelistManager| are stored in |_nativeAppsInSettings| and |
-// |-reloadData| is sent to the receiver. |
-- (void)configureWithNativeAppWhiteListManager: |
- (id<NativeAppWhitelistManager>)nativeAppWhitelistManager; |
- |
-// Returns a new Native App collection view item for the metadata at |index| in |
-// |_nativeAppsInSettings|. |
-- (CollectionViewItem*)nativeAppItemAtIndex:(NSUInteger)index; |
- |
-// Target method for the auto open in app switch. |
-// Called when an auto-open-in-app switch is toggled. |
-- (void)autoOpenInAppChanged:(UISwitch*)switchControl; |
- |
-// Called when an Install button is being tapped. |
-- (void)installApp:(UIButton*)button; |
- |
-// Called when an app with the registered scheme is opened. |
-- (void)appDidInstall:(NSNotification*)notification; |
- |
-// Returns the app at |index| in the list of visible apps. |
-- (id<NativeAppMetadata>)nativeAppAtIndex:(NSUInteger)index; |
- |
-// Records a user action in UMA under NativeAppLauncher.Settings. |
-// If this method is not called during the lifetime of the view, |
-// |settings::kNativeAppsActionDidNothing| is recorded in UMA. |
-- (void)recordUserAction:(settings::NativeAppsAction)action; |
- |
-@end |
- |
-@implementation NativeAppsCollectionViewController |
- |
-@synthesize storeKitLauncher = _storeKitLauncher; |
- |
-- (id)initWithURLRequestContextGetter: |
- (net::URLRequestContextGetter*)requestContextGetter { |
- self = [super initWithStyle:CollectionViewControllerStyleAppBar]; |
- if (self) { |
- _imageFetcher = base::MakeUnique<image_fetcher::IOSImageDataFetcherWrapper>( |
- requestContextGetter, web::WebThread::GetBlockingPool()); |
- base::RecordAction(base::UserMetricsAction("MobileGALOpenSettings")); |
- _storeKitLauncher = self; |
- |
- [self loadModel]; |
- } |
- return self; |
-} |
- |
-- (void)dealloc { |
- [[InstallationNotifier sharedInstance] unregisterForNotifications:self]; |
- if (!_userDidSomething) |
- [self recordUserAction:settings::kNativeAppsActionDidNothing]; |
-} |
- |
-#pragma mark - View lifecycle |
- |
-- (void)viewDidLoad { |
- self.title = l10n_util::GetNSString(IDS_IOS_GOOGLE_APPS_SM_SETTINGS); |
- [self configureWithNativeAppWhiteListManager: |
- ios::GetChromeBrowserProvider()->GetNativeAppWhitelistManager()]; |
- |
- [super viewDidLoad]; |
-} |
- |
-- (void)viewWillAppear:(BOOL)animated { |
- [super viewWillAppear:animated]; |
- [[InstallationNotifier sharedInstance] checkNow]; |
- [[NSNotificationCenter defaultCenter] |
- addObserver:self |
- selector:@selector(reloadData) |
- name:UIApplicationDidBecomeActiveNotification |
- object:nil]; |
-} |
- |
-- (void)viewDidDisappear:(BOOL)animated { |
- [super viewDidDisappear:animated]; |
- [[NSNotificationCenter defaultCenter] |
- removeObserver:self |
- name:UIApplicationDidBecomeActiveNotification |
- object:nil]; |
-} |
- |
-#pragma mark - CollectionViewController |
- |
-- (void)loadModel { |
- [super loadModel]; |
- CollectionViewModel* model = self.collectionViewModel; |
- NSUInteger appsCount = [_nativeAppsInSettings count]; |
- |
- [model addSectionWithIdentifier:SectionIdentifierLearnMore]; |
- [model addItem:[self learnMoreItem] |
- toSectionWithIdentifier:SectionIdentifierLearnMore]; |
- |
- [model addSectionWithIdentifier:SectionIdentifierApps]; |
- |
- for (NSUInteger i = 0; i < appsCount; i++) { |
- [model addItem:[self nativeAppItemAtIndex:i] |
- toSectionWithIdentifier:SectionIdentifierApps]; |
- } |
-} |
- |
-- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView |
- cellForItemAtIndexPath:(NSIndexPath*)indexPath { |
- UICollectionViewCell* cell = |
- [super collectionView:collectionView cellForItemAtIndexPath:indexPath]; |
- if ([self.collectionViewModel |
- sectionIdentifierForSection:indexPath.section] == |
- SectionIdentifierApps) { |
- NativeAppCell* appCell = base::mac::ObjCCastStrict<NativeAppCell>(cell); |
- [self configureNativeAppCell:appCell atIndexPath:indexPath]; |
- } |
- return cell; |
-} |
- |
-#pragma mark - MDCCollectionViewStylingDelegate |
- |
-- (CGFloat)collectionView:(nonnull UICollectionView*)collectionView |
- cellHeightAtIndexPath:(nonnull NSIndexPath*)indexPath { |
- CollectionViewItem* item = |
- [self.collectionViewModel itemAtIndexPath:indexPath]; |
- switch (item.type) { |
- case ItemTypeLearnMore: |
- return [MDCCollectionViewCell |
- cr_preferredHeightForWidth:CGRectGetWidth(collectionView.bounds) |
- forItem:item]; |
- case ItemTypeApp: |
- return MDCCellDefaultOneLineWithAvatarHeight; |
- default: |
- return MDCCellDefaultOneLineHeight; |
- } |
-} |
- |
-- (void)configureNativeAppCell:(NativeAppCell*)appCell |
- atIndexPath:(NSIndexPath*)indexPath { |
- appCell.switchControl.tag = [self tagForIndexPath:indexPath]; |
- [appCell.switchControl addTarget:self |
- action:@selector(autoOpenInAppChanged:) |
- forControlEvents:UIControlEventValueChanged]; |
- appCell.installButton.tag = [self tagForIndexPath:indexPath]; |
- [appCell.installButton addTarget:self |
- action:@selector(installApp:) |
- forControlEvents:UIControlEventTouchUpInside]; |
- CollectionViewItem* item = |
- [self.collectionViewModel itemAtIndexPath:indexPath]; |
- NativeAppItem* appItem = base::mac::ObjCCastStrict<NativeAppItem>(item); |
- if (!appItem.icon) { |
- // Fetch the real icon. |
- __weak NativeAppsCollectionViewController* weakSelf = self; |
- id<NativeAppMetadata> metadata = [self nativeAppAtIndex:indexPath.item]; |
- [metadata fetchSmallIconWithImageFetcher:_imageFetcher.get() |
- completionBlock:^(UIImage* image) { |
- |
- NativeAppsCollectionViewController* strongSelf = |
- weakSelf; |
- if (!image || !strongSelf) |
- return; |
- appItem.icon = image; |
- [strongSelf.collectionView |
- reloadItemsAtIndexPaths:@[ indexPath ]]; |
- }]; |
- } |
-} |
- |
-- (CollectionViewItem*)learnMoreItem { |
- NSString* learnMoreText = |
- l10n_util::GetNSString(IDS_IOS_GOOGLE_APPS_SM_SECTION_HEADER); |
- CollectionViewFooterItem* learnMoreItem = |
- [[CollectionViewFooterItem alloc] initWithType:ItemTypeLearnMore]; |
- learnMoreItem.text = learnMoreText; |
- return learnMoreItem; |
-} |
- |
-#pragma mark - SKStoreProductViewControllerDelegate methods |
- |
-- (void)productViewControllerDidFinish: |
- (SKStoreProductViewController*)viewController { |
- [self dismissViewControllerAnimated:YES completion:nil]; |
-} |
- |
-#pragma mark - StoreKitLauncher methods |
- |
-- (void)openAppStore:(NSString*)appId { |
- // Reported crashes show that -openAppStore: had been called with |
- // a nil |appId|, but opening AppStore is meaningful only if the |appId| is |
- // not nil, so be defensive and early return if |appId| is nil. |
- if (![appId length]) |
- return; |
- NSDictionary* product = |
- @{SKStoreProductParameterITunesItemIdentifier : appId}; |
- SKStoreProductViewController* storeViewController = |
- [[SKStoreProductViewController alloc] init]; |
- [storeViewController setDelegate:self]; |
- [storeViewController loadProductWithParameters:product completionBlock:nil]; |
- [self presentViewController:storeViewController animated:YES completion:nil]; |
-} |
- |
-#pragma mark - MDCCollectionViewStylingDelegate |
- |
-// MDCCollectionViewStylingDelegate protocol is implemented so that cells don't |
-// display ink on touch. |
-- (BOOL)collectionView:(nonnull UICollectionView*)collectionView |
- hidesInkViewAtIndexPath:(nonnull NSIndexPath*)indexPath { |
- return YES; |
-} |
- |
-- (MDCCollectionViewCellStyle)collectionView:(UICollectionView*)collectionView |
- cellStyleForSection:(NSInteger)section { |
- NSInteger sectionIdentifier = |
- [self.collectionViewModel sectionIdentifierForSection:section]; |
- switch (sectionIdentifier) { |
- case SectionIdentifierLearnMore: |
- // Display the Learn More footer in the default style with no "card" UI |
- // and no section padding. |
- return MDCCollectionViewCellStyleDefault; |
- default: |
- return self.styler.cellStyle; |
- } |
-} |
- |
-- (BOOL)collectionView:(UICollectionView*)collectionView |
- shouldHideItemBackgroundAtIndexPath:(NSIndexPath*)indexPath { |
- NSInteger sectionIdentifier = |
- [self.collectionViewModel sectionIdentifierForSection:indexPath.section]; |
- switch (sectionIdentifier) { |
- case SectionIdentifierLearnMore: |
- // Display the Learn More footer without any background image or |
- // shadowing. |
- return YES; |
- default: |
- return NO; |
- } |
-} |
-#pragma mark - Private methods |
- |
-- (void)autoOpenInAppChanged:(UISwitch*)switchControl { |
- NSInteger index = [self indexPathForTag:switchControl.tag].item; |
- id<NativeAppMetadata> metadata = [self nativeAppAtIndex:index]; |
- DCHECK([metadata isInstalled]); |
- BOOL autoOpenOn = switchControl.on; |
- metadata.shouldAutoOpenLinks = autoOpenOn; |
- [self recordUserAction:(autoOpenOn |
- ? settings::kNativeAppsActionTurnedAutoOpenOn |
- : settings::kNativeAppsActionTurnedAutoOpenOff)]; |
-} |
- |
-- (void)installApp:(UIButton*)button { |
- [self recordUserAction:settings::kNativeAppsActionClickedInstall]; |
- NSInteger index = [self indexPathForTag:button.tag].item; |
- id<NativeAppMetadata> metadata = [self nativeAppAtIndex:index]; |
- DCHECK(![metadata isInstalled]); |
- [metadata updateCounterWithAppInstallation]; |
- |
- // Register to get a notification when the app is installed. |
- [[InstallationNotifier sharedInstance] |
- registerForInstallationNotifications:self |
- withSelector:@selector(appDidInstall:) |
- forScheme:[metadata anyScheme]]; |
- [self.storeKitLauncher openAppStore:[metadata appId]]; |
-} |
- |
-- (void)appDidInstall:(NSNotification*)notification { |
- // The name of the notification is the scheme of the new app installed. |
- GURL url(base::SysNSStringToUTF8([notification name]) + ":"); |
- DCHECK(url.is_valid()); |
- NSUInteger matchingAppIndex = [_nativeAppsInSettings |
- indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL* stop) { |
- id<NativeAppMetadata> metadata = |
- static_cast<id<NativeAppMetadata>>(obj); |
- return [metadata canOpenURL:url]; |
- }]; |
- [[self nativeAppAtIndex:matchingAppIndex] setShouldAutoOpenLinks:YES]; |
- [self reloadData]; |
-} |
- |
-- (void)configureWithNativeAppWhiteListManager: |
- (id<NativeAppWhitelistManager>)nativeAppWhitelistManager { |
- NSArray* allApps = [nativeAppWhitelistManager |
- filteredAppsUsingBlock:^(const id<NativeAppMetadata> app, BOOL* stop) { |
- return [app isGoogleOwnedApp]; |
- }]; |
- [self setAppsInSettings:allApps]; |
- [self reloadData]; |
-} |
- |
-- (id<NativeAppMetadata>)nativeAppAtIndex:(NSUInteger)index { |
- id<NativeAppMetadata> metadata = [_nativeAppsInSettings objectAtIndex:index]; |
- DCHECK([metadata conformsToProtocol:@protocol(NativeAppMetadata)]); |
- return metadata; |
-} |
- |
-- (void)recordUserAction:(settings::NativeAppsAction)action { |
- _userDidSomething = YES; |
- UMA_HISTOGRAM_ENUMERATION("NativeAppLauncher.Settings", action, |
- settings::kNativeAppsActionCount); |
-} |
- |
-- (CollectionViewItem*)nativeAppItemAtIndex:(NSUInteger)index { |
- id<NativeAppMetadata> metadata = [self nativeAppAtIndex:index]; |
- // Determine the state of the cell. |
- NativeAppItemState state; |
- if ([metadata isInstalled]) { |
- state = [metadata shouldAutoOpenLinks] ? NativeAppItemSwitchOn |
- : NativeAppItemSwitchOff; |
- } else { |
- state = NativeAppItemInstall; |
- } |
- NativeAppItem* appItem = [[NativeAppItem alloc] initWithType:ItemTypeApp]; |
- appItem.name = [metadata appName]; |
- appItem.state = state; |
- return appItem; |
-} |
- |
-- (NSArray*)appsInSettings { |
- return _nativeAppsInSettings; |
-} |
- |
-- (void)setAppsInSettings:(NSArray*)apps { |
- _nativeAppsInSettings = [apps copy]; |
-} |
- |
-- (NSInteger)tagForIndexPath:(NSIndexPath*)indexPath { |
- DCHECK(indexPath.section == |
- [self.collectionViewModel |
- sectionForSectionIdentifier:SectionIdentifierApps]); |
- return indexPath.item + kTagShift; |
-} |
- |
-- (NSIndexPath*)indexPathForTag:(NSInteger)shiftedTag { |
- NSInteger unshiftedTag = shiftedTag - kTagShift; |
- return [NSIndexPath |
- indexPathForItem:unshiftedTag |
- inSection:[self.collectionViewModel |
- sectionForSectionIdentifier:SectionIdentifierApps]]; |
-} |
- |
-@end |