| // Copyright 2013 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/content_settings_table_view_controller.h" |
| |
| #include "base/check_op.h" |
| #include "base/feature_list.h" |
| #include "base/metrics/user_metrics.h" |
| #include "base/metrics/user_metrics_action.h" |
| #include "components/content_settings/core/browser/host_content_settings_map.h" |
| #include "components/content_settings/core/common/content_settings.h" |
| #include "components/content_settings/core/common/content_settings_types.h" |
| #include "components/strings/grit/components_strings.h" |
| #include "ios/chrome/browser/browser_state/chrome_browser_state.h" |
| #include "ios/chrome/browser/content_settings/host_content_settings_map_factory.h" |
| #import "ios/chrome/browser/ui/settings/block_popups_table_view_controller.h" |
| #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" |
| #import "ios/chrome/browser/ui/settings/settings_table_view_controller_constants.h" |
| #import "ios/chrome/browser/ui/settings/utils/content_setting_backed_boolean.h" |
| #import "ios/chrome/browser/ui/table_view/cells/table_view_detail_icon_item.h" |
| #import "ios/chrome/browser/ui/table_view/cells/table_view_multi_detail_text_item.h" |
| #include "ios/chrome/browser/ui/ui_feature_flags.h" |
| #import "ios/chrome/common/ui/colors/UIColor+cr_semantic_colors.h" |
| #include "ios/chrome/grit/ios_strings.h" |
| #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" |
| #include "ios/public/provider/chrome/browser/mailto/mailto_handler_provider.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/l10n/l10n_util_mac.h" |
| |
| #if !defined(__has_feature) || !__has_feature(objc_arc) |
| #error "This file requires ARC support." |
| #endif |
| |
| namespace { |
| |
| // Is YES when one window has mailTo controller opened. |
| BOOL openedMailTo = NO; |
| |
| // Notification name of changes to openedMailTo state. |
| NSString* kMailToInstanceChanged = @"MailToInstanceChanged"; |
| |
| typedef NS_ENUM(NSInteger, SectionIdentifier) { |
| SectionIdentifierSettings = kSectionIdentifierEnumZero, |
| }; |
| |
| typedef NS_ENUM(NSInteger, ItemType) { |
| ItemTypeSettingsBlockPopups = kItemTypeEnumZero, |
| ItemTypeSettingsComposeEmail, |
| }; |
| |
| } // namespace |
| |
| @interface ContentSettingsTableViewController () <BooleanObserver> { |
| // The observable boolean that binds to the "Disable Popups" setting state. |
| ContentSettingBackedBoolean* _disablePopupsSetting; |
| |
| // Updatable Items |
| TableViewDetailIconItem* _blockPopupsDetailItem; |
| TableViewDetailIconItem* _composeEmailDetailItem; |
| TableViewMultiDetailTextItem* _openedInAnotherWindowItem; |
| } |
| |
| // Returns the value for the default setting with ID |settingID|. |
| - (ContentSetting)getContentSetting:(ContentSettingsType)settingID; |
| |
| // Helpers to create collection view items. |
| - (id)blockPopupsItem; |
| - (id)composeEmailItem; |
| |
| @end |
| |
| @implementation ContentSettingsTableViewController { |
| ChromeBrowserState* _browserState; // weak |
| } |
| |
| - (instancetype)initWithBrowserState:(ChromeBrowserState*)browserState { |
| DCHECK(browserState); |
| UITableViewStyle style = base::FeatureList::IsEnabled(kSettingsRefresh) |
| ? UITableViewStylePlain |
| : UITableViewStyleGrouped; |
| self = [super initWithStyle:style]; |
| if (self) { |
| _browserState = browserState; |
| self.title = l10n_util::GetNSString(IDS_IOS_CONTENT_SETTINGS_TITLE); |
| |
| HostContentSettingsMap* settingsMap = |
| ios::HostContentSettingsMapFactory::GetForBrowserState(browserState); |
| _disablePopupsSetting = [[ContentSettingBackedBoolean alloc] |
| initWithHostContentSettingsMap:settingsMap |
| settingID:ContentSettingsType::POPUPS |
| inverted:YES]; |
| [_disablePopupsSetting setObserver:self]; |
| } |
| return self; |
| } |
| |
| #pragma mark - UIViewController |
| |
| - (void)viewDidLoad { |
| [super viewDidLoad]; |
| self.tableView.rowHeight = UITableViewAutomaticDimension; |
| [self loadModel]; |
| } |
| |
| - (void)viewWillAppear:(BOOL)animated { |
| [super viewWillAppear:animated]; |
| [[NSNotificationCenter defaultCenter] |
| addObserver:self |
| selector:@selector(mailToControllerChanged) |
| name:kMailToInstanceChanged |
| object:nil]; |
| [self checkMailToOwnership]; |
| } |
| |
| - (void)viewWillDisappear:(BOOL)animated { |
| [super viewWillDisappear:animated]; |
| [self checkMailToOwnership]; |
| [[NSNotificationCenter defaultCenter] removeObserver:self |
| name:kMailToInstanceChanged |
| object:nil]; |
| } |
| |
| #pragma mark - ChromeTableViewController |
| |
| - (void)loadModel { |
| [super loadModel]; |
| |
| TableViewModel* model = self.tableViewModel; |
| [model addSectionWithIdentifier:SectionIdentifierSettings]; |
| [model addItem:[self blockPopupsItem] |
| toSectionWithIdentifier:SectionIdentifierSettings]; |
| MailtoHandlerProvider* provider = |
| ios::GetChromeBrowserProvider()->GetMailtoHandlerProvider(); |
| NSString* settingsTitle = provider->MailtoHandlerSettingsTitle(); |
| // Display email settings only on one window at a time, by checking |
| // if this is the current owner. |
| _openedInAnotherWindowItem = nil; |
| _composeEmailDetailItem = nil; |
| if (settingsTitle) { |
| if (!openedMailTo) { |
| [model addItem:[self composeEmailItem] |
| toSectionWithIdentifier:SectionIdentifierSettings]; |
| } else { |
| [model addItem:[self openedInAnotherWindowItem] |
| toSectionWithIdentifier:SectionIdentifierSettings]; |
| } |
| } |
| } |
| |
| #pragma mark - SettingsControllerProtocol |
| |
| - (void)reportDismissalUserAction { |
| base::RecordAction(base::UserMetricsAction("MobileContentSettingsClose")); |
| } |
| |
| - (void)reportBackUserAction { |
| base::RecordAction(base::UserMetricsAction("MobileContentSettingsBack")); |
| } |
| |
| #pragma mark - ContentSettingsTableViewController |
| |
| - (TableViewItem*)blockPopupsItem { |
| _blockPopupsDetailItem = [[TableViewDetailIconItem alloc] |
| initWithType:ItemTypeSettingsBlockPopups]; |
| NSString* subtitle = [_disablePopupsSetting value] |
| ? l10n_util::GetNSString(IDS_IOS_SETTING_ON) |
| : l10n_util::GetNSString(IDS_IOS_SETTING_OFF); |
| _blockPopupsDetailItem.text = l10n_util::GetNSString(IDS_IOS_BLOCK_POPUPS); |
| _blockPopupsDetailItem.detailText = subtitle; |
| _blockPopupsDetailItem.accessoryType = |
| UITableViewCellAccessoryDisclosureIndicator; |
| _blockPopupsDetailItem.accessibilityTraits |= UIAccessibilityTraitButton; |
| _blockPopupsDetailItem.accessibilityIdentifier = kSettingsBlockPopupsCellId; |
| return _blockPopupsDetailItem; |
| } |
| |
| - (TableViewItem*)composeEmailItem { |
| _composeEmailDetailItem = [[TableViewDetailIconItem alloc] |
| initWithType:ItemTypeSettingsComposeEmail]; |
| // Use the handler's preferred title string for the compose email item. |
| MailtoHandlerProvider* provider = |
| ios::GetChromeBrowserProvider()->GetMailtoHandlerProvider(); |
| NSString* settingsTitle = provider->MailtoHandlerSettingsTitle(); |
| DCHECK([settingsTitle length]); |
| // .detailText can display the selected mailto handling app, but the current |
| // MailtoHandlerProvider does not expose this through its API. |
| _composeEmailDetailItem.text = settingsTitle; |
| _composeEmailDetailItem.accessoryType = |
| UITableViewCellAccessoryDisclosureIndicator; |
| _composeEmailDetailItem.accessibilityTraits |= UIAccessibilityTraitButton; |
| _composeEmailDetailItem.accessibilityIdentifier = kSettingsDefaultAppsCellId; |
| return _composeEmailDetailItem; |
| } |
| |
| - (TableViewItem*)openedInAnotherWindowItem { |
| _openedInAnotherWindowItem = [[TableViewMultiDetailTextItem alloc] |
| initWithType:ItemTypeSettingsComposeEmail]; |
| // Use the handler's preferred title string for the compose email item. |
| MailtoHandlerProvider* provider = |
| ios::GetChromeBrowserProvider()->GetMailtoHandlerProvider(); |
| NSString* settingsTitle = provider->MailtoHandlerSettingsTitle(); |
| DCHECK([settingsTitle length]); |
| // .detailText can display the selected mailto handling app, but the current |
| // MailtoHandlerProvider does not expose this through its API. |
| _openedInAnotherWindowItem.text = settingsTitle; |
| |
| _openedInAnotherWindowItem.trailingDetailText = |
| l10n_util::GetNSString(IDS_IOS_SETTING_OPENED_IN_ANOTHER_WINDOW); |
| _openedInAnotherWindowItem.accessibilityTraits |= |
| UIAccessibilityTraitButton | UIAccessibilityTraitNotEnabled; |
| _openedInAnotherWindowItem.accessibilityIdentifier = |
| kSettingsDefaultAppsCellId; |
| return _openedInAnotherWindowItem; |
| } |
| |
| - (ContentSetting)getContentSetting:(ContentSettingsType)settingID { |
| return ios::HostContentSettingsMapFactory::GetForBrowserState(_browserState) |
| ->GetDefaultContentSetting(settingID, NULL); |
| } |
| |
| #pragma mark - UITableViewDelegate |
| |
| - (void)tableView:(UITableView*)tableView |
| didSelectRowAtIndexPath:(NSIndexPath*)indexPath { |
| [super tableView:tableView didSelectRowAtIndexPath:indexPath]; |
| |
| NSInteger itemType = [self.tableViewModel itemTypeForIndexPath:indexPath]; |
| switch (itemType) { |
| case ItemTypeSettingsBlockPopups: { |
| BlockPopupsTableViewController* controller = |
| [[BlockPopupsTableViewController alloc] |
| initWithBrowserState:_browserState]; |
| controller.dispatcher = self.dispatcher; |
| [self.navigationController pushViewController:controller animated:YES]; |
| break; |
| } |
| case ItemTypeSettingsComposeEmail: { |
| if (openedMailTo) |
| break; |
| |
| MailtoHandlerProvider* provider = |
| ios::GetChromeBrowserProvider()->GetMailtoHandlerProvider(); |
| UIViewController* controller = |
| provider->MailtoHandlerSettingsController(); |
| if (controller) { |
| [self.navigationController pushViewController:controller animated:YES]; |
| openedMailTo = YES; |
| [[NSNotificationCenter defaultCenter] |
| postNotificationName:kMailToInstanceChanged |
| object:nil]; |
| } |
| break; |
| } |
| } |
| [tableView deselectRowAtIndexPath:indexPath animated:YES]; |
| } |
| |
| #pragma mark - BooleanObserver |
| |
| - (void)booleanDidChange:(id<ObservableBoolean>)observableBoolean { |
| DCHECK_EQ(observableBoolean, _disablePopupsSetting); |
| |
| NSString* subtitle = [_disablePopupsSetting value] |
| ? l10n_util::GetNSString(IDS_IOS_SETTING_ON) |
| : l10n_util::GetNSString(IDS_IOS_SETTING_OFF); |
| // Update the item. |
| _blockPopupsDetailItem.detailText = subtitle; |
| |
| // Update the cell. |
| [self reconfigureCellsForItems:@[ _blockPopupsDetailItem ]]; |
| } |
| |
| #pragma mark Private |
| |
| // Called to reload data when another window has mailTo settings opened. |
| - (void)mailToControllerChanged { |
| [self reloadData]; |
| } |
| |
| // Verifies using the navigation stack if this is a return from mailTo settings |
| // and this instance should reset |openedMailTo|. |
| - (void)checkMailToOwnership { |
| // Since this doesn't know or have access to the mailTo controller code, |
| // it detects if the flow is coming back from it, based on the navigation |
| // bar stack items. |
| NSString* top = self.navigationController.navigationBar.topItem.title; |
| MailtoHandlerProvider* provider = |
| ios::GetChromeBrowserProvider()->GetMailtoHandlerProvider(); |
| NSString* mailToTitle = provider->MailtoHandlerSettingsTitle(); |
| if ([top isEqualToString:mailToTitle]) { |
| openedMailTo = NO; |
| [[NSNotificationCenter defaultCenter] |
| postNotificationName:kMailToInstanceChanged |
| object:nil]; |
| } |
| } |
| |
| @end |