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

Side by Side Diff: ios/chrome/browser/ui/ntp/google_landing_controller.mm

Issue 2791253002: Create an Obj-C bridge for MostVisitedSitesObserver (Closed)
Patch Set: Fix BUILD.gn Created 3 years, 8 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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/ui/ntp/google_landing_controller.h" 5 #import "ios/chrome/browser/ui/ntp/google_landing_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/i18n/case_conversion.h" 9 #include "base/i18n/case_conversion.h"
10 #import "base/ios/weak_nsobject.h" 10 #import "base/ios/weak_nsobject.h"
11 #include "base/json/json_reader.h" 11 #include "base/json/json_reader.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/mac/bind_objc_block.h" 13 #include "base/mac/bind_objc_block.h"
14 #include "base/mac/foundation_util.h" 14 #include "base/mac/foundation_util.h"
15 #include "base/mac/scoped_nsobject.h" 15 #include "base/mac/scoped_nsobject.h"
16 #include "base/metrics/histogram_macros.h" 16 #include "base/metrics/histogram_macros.h"
17 #include "base/metrics/user_metrics.h" 17 #include "base/metrics/user_metrics.h"
18 #include "base/metrics/user_metrics_action.h" 18 #include "base/metrics/user_metrics_action.h"
19 #include "base/strings/sys_string_conversions.h" 19 #include "base/strings/sys_string_conversions.h"
20 #include "components/favicon/core/large_icon_service.h" 20 #include "components/favicon/core/large_icon_service.h"
21 #include "components/keyed_service/core/service_access_type.h" 21 #include "components/keyed_service/core/service_access_type.h"
22 #import "components/ntp_tiles/ios/most_visited_sites_bridge_observer.h"
22 #include "components/ntp_tiles/most_visited_sites.h" 23 #include "components/ntp_tiles/most_visited_sites.h"
23 #include "components/ntp_tiles/ntp_tile.h" 24 #include "components/ntp_tiles/ntp_tile.h"
24 #include "components/rappor/rappor_service_impl.h" 25 #include "components/rappor/rappor_service_impl.h"
25 #include "components/search_engines/template_url_service.h" 26 #include "components/search_engines/template_url_service.h"
26 #include "components/search_engines/template_url_service_observer.h" 27 #include "components/search_engines/template_url_service_observer.h"
27 #include "components/strings/grit/components_strings.h" 28 #include "components/strings/grit/components_strings.h"
28 #include "ios/chrome/browser/application_context.h" 29 #include "ios/chrome/browser/application_context.h"
29 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" 30 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
30 #import "ios/chrome/browser/favicon/favicon_loader.h" 31 #import "ios/chrome/browser/favicon/favicon_loader.h"
31 #include "ios/chrome/browser/favicon/favicon_service_factory.h" 32 #include "ios/chrome/browser/favicon/favicon_service_factory.h"
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 const NSInteger kMaxNumMostVisitedFavicons = 8; 102 const NSInteger kMaxNumMostVisitedFavicons = 8;
102 const NSInteger kMaxNumMostVisitedFaviconRows = 2; 103 const NSInteger kMaxNumMostVisitedFaviconRows = 2;
103 const CGFloat kMaxSearchFieldFrameMargin = 200; 104 const CGFloat kMaxSearchFieldFrameMargin = 200;
104 const CGFloat kShiftTilesDownAnimationDuration = 0.2; 105 const CGFloat kShiftTilesDownAnimationDuration = 0.2;
105 106
106 const CGFloat kMostVisitedPaddingIPhone = 16; 107 const CGFloat kMostVisitedPaddingIPhone = 16;
107 const CGFloat kMostVisitedPaddingIPadFavicon = 24; 108 const CGFloat kMostVisitedPaddingIPadFavicon = 24;
108 109
109 } // namespace 110 } // namespace
110 111
111 @interface GoogleLandingController ()
112 - (void)onMostVisitedURLsAvailable:(const ntp_tiles::NTPTilesVector&)data;
113 - (void)onIconMadeAvailable:(const GURL&)siteUrl;
114 @end
115
116 namespace google_landing { 112 namespace google_landing {
117 113
118 // MostVisitedSitesObserverBridge allow registration as a
119 // MostVisitedSites::Observer.
120 class MostVisitedSitesObserverBridge
121 : public ntp_tiles::MostVisitedSites::Observer {
122 public:
123 MostVisitedSitesObserverBridge(GoogleLandingController* owner);
124 ~MostVisitedSitesObserverBridge() override;
125
126 // MostVisitedSites::Observer implementation.
127 void OnMostVisitedURLsAvailable(
128 const ntp_tiles::NTPTilesVector& most_visited) override;
129 void OnIconMadeAvailable(const GURL& site_url) override;
130
131 private:
132 GoogleLandingController* _owner;
133 };
134
135 MostVisitedSitesObserverBridge::MostVisitedSitesObserverBridge(
136 GoogleLandingController* owner)
137 : _owner(owner) {}
138
139 MostVisitedSitesObserverBridge::~MostVisitedSitesObserverBridge() {}
140
141 void MostVisitedSitesObserverBridge::OnMostVisitedURLsAvailable(
142 const ntp_tiles::NTPTilesVector& tiles) {
143 [_owner onMostVisitedURLsAvailable:tiles];
144 }
145
146 void MostVisitedSitesObserverBridge::OnIconMadeAvailable(const GURL& site_url) {
147 [_owner onIconMadeAvailable:site_url];
148 }
149
150 // Observer used to hide the Google logo and doodle if the TemplateURLService 114 // Observer used to hide the Google logo and doodle if the TemplateURLService
151 // changes. 115 // changes.
152 class SearchEngineObserver : public TemplateURLServiceObserver { 116 class SearchEngineObserver : public TemplateURLServiceObserver {
153 public: 117 public:
154 SearchEngineObserver(GoogleLandingController* owner, 118 SearchEngineObserver(GoogleLandingController* owner,
155 TemplateURLService* urlService); 119 TemplateURLService* urlService);
156 ~SearchEngineObserver() override; 120 ~SearchEngineObserver() override;
157 void OnTemplateURLServiceChanged() override; 121 void OnTemplateURLServiceChanged() override;
158 122
159 private: 123 private:
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 // To prevent this from happening, we reset the inset to 0 before changing the 177 // To prevent this from happening, we reset the inset to 0 before changing the
214 // frame. 178 // frame.
215 [_googleLanding resetSectionInset]; 179 [_googleLanding resetSectionInset];
216 [super setFrame:frame]; 180 [super setFrame:frame];
217 [_googleLanding updateSubviewFrames]; 181 [_googleLanding updateSubviewFrames];
218 [_googleLanding reloadData]; 182 [_googleLanding reloadData];
219 } 183 }
220 184
221 @end 185 @end
222 186
223 @interface GoogleLandingController ()<OverscrollActionsControllerDelegate, 187 @interface GoogleLandingController ()<MostVisitedSitesObserver,
188 OverscrollActionsControllerDelegate,
224 UICollectionViewDataSource, 189 UICollectionViewDataSource,
225 UICollectionViewDelegate, 190 UICollectionViewDelegate,
226 UICollectionViewDelegateFlowLayout, 191 UICollectionViewDelegateFlowLayout,
227 UIGestureRecognizerDelegate, 192 UIGestureRecognizerDelegate,
228 WhatsNewHeaderViewDelegate> { 193 WhatsNewHeaderViewDelegate> {
229 // The main view. 194 // The main view.
230 base::scoped_nsobject<GoogleLandingView> _view; 195 base::scoped_nsobject<GoogleLandingView> _view;
231 196
232 // Fake omnibox. 197 // Fake omnibox.
233 base::scoped_nsobject<UIButton> _searchTapTarget; 198 base::scoped_nsobject<UIButton> _searchTapTarget;
(...skipping 26 matching lines...) Expand all
260 base::scoped_nsobject<UISwipeGestureRecognizer> _swipeGestureRecognizer; 225 base::scoped_nsobject<UISwipeGestureRecognizer> _swipeGestureRecognizer;
261 226
262 // Handles displaying the context menu for all form factors. 227 // Handles displaying the context menu for all form factors.
263 base::scoped_nsobject<ContextMenuCoordinator> _contextMenuCoordinator; 228 base::scoped_nsobject<ContextMenuCoordinator> _contextMenuCoordinator;
264 229
265 // What's new promo. 230 // What's new promo.
266 std::unique_ptr<NotificationPromoWhatsNew> _notification_promo; 231 std::unique_ptr<NotificationPromoWhatsNew> _notification_promo;
267 232
268 // A MostVisitedSites::Observer bridge object to get notified of most visited 233 // A MostVisitedSites::Observer bridge object to get notified of most visited
269 // sites changes. 234 // sites changes.
270 std::unique_ptr<google_landing::MostVisitedSitesObserverBridge> 235 std::unique_ptr<ntp_tiles::MostVisitedSitesBridge> _most_visited_bridge;
271 _most_visited_observer_bridge;
272 236
273 std::unique_ptr<ntp_tiles::MostVisitedSites> _most_visited_sites; 237 std::unique_ptr<ntp_tiles::MostVisitedSites> _most_visited_sites;
274 238
275 // URL of the last deleted most viewed entry. If present the UI to restore it 239 // URL of the last deleted most viewed entry. If present the UI to restore it
276 // is shown. 240 // is shown.
277 base::scoped_nsobject<NSURL> _deletedUrl; 241 base::scoped_nsobject<NSURL> _deletedUrl;
278 242
279 // Listen for default search engine changes. 243 // Listen for default search engine changes.
280 std::unique_ptr<google_landing::SearchEngineObserver> _observer; 244 std::unique_ptr<google_landing::SearchEngineObserver> _observer;
281 TemplateURLService* _templateURLService; // weak 245 TemplateURLService* _templateURLService; // weak
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 forSupplementaryViewOfKind:UICollectionElementKindSectionHeader 886 forSupplementaryViewOfKind:UICollectionElementKindSectionHeader
923 withReuseIdentifier:@"whatsNew"]; 887 withReuseIdentifier:@"whatsNew"];
924 [_mostVisitedView registerClass:[NewTabPageHeaderView class] 888 [_mostVisitedView registerClass:[NewTabPageHeaderView class]
925 forSupplementaryViewOfKind:UICollectionElementKindSectionHeader 889 forSupplementaryViewOfKind:UICollectionElementKindSectionHeader
926 withReuseIdentifier:@"header"]; 890 withReuseIdentifier:@"header"];
927 [_mostVisitedView setAccessibilityIdentifier:@"Google Landing"]; 891 [_mostVisitedView setAccessibilityIdentifier:@"Google Landing"];
928 892
929 [_view addSubview:_mostVisitedView]; 893 [_view addSubview:_mostVisitedView];
930 _most_visited_sites = 894 _most_visited_sites =
931 IOSMostVisitedSitesFactory::NewForBrowserState(_browserState); 895 IOSMostVisitedSitesFactory::NewForBrowserState(_browserState);
932 _most_visited_observer_bridge.reset( 896 _most_visited_bridge.reset(new ntp_tiles::MostVisitedSitesBridge(self));
933 new google_landing::MostVisitedSitesObserverBridge(self)); 897 _most_visited_sites->SetMostVisitedURLsObserver(_most_visited_bridge.get(),
934 _most_visited_sites->SetMostVisitedURLsObserver( 898 kMaxNumMostVisitedFavicons);
935 _most_visited_observer_bridge.get(), kMaxNumMostVisitedFavicons);
936 } 899 }
937 900
938 - (void)updateSearchField { 901 - (void)updateSearchField {
939 NSArray* constraints = 902 NSArray* constraints =
940 @[ _hintLabelLeadingConstraint, _voiceTapTrailingConstraint ]; 903 @[ _hintLabelLeadingConstraint, _voiceTapTrailingConstraint ];
941 [_headerView updateSearchField:_searchTapTarget 904 [_headerView updateSearchField:_searchTapTarget
942 withInitialFrame:[self searchFieldFrame] 905 withInitialFrame:[self searchFieldFrame]
943 subviewConstraints:constraints 906 subviewConstraints:constraints
944 forOffset:[_mostVisitedView contentOffset].y]; 907 forOffset:[_mostVisitedView contentOffset].y];
945 } 908 }
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 1052
1090 - (void)logMostVisitedClick:(const NSUInteger)visitedIndex 1053 - (void)logMostVisitedClick:(const NSUInteger)visitedIndex
1091 tileType:(ntp_tiles::metrics::MostVisitedTileType)tileType { 1054 tileType:(ntp_tiles::metrics::MostVisitedTileType)tileType {
1092 new_tab_page_uma::RecordAction( 1055 new_tab_page_uma::RecordAction(
1093 _browserState, new_tab_page_uma::ACTION_OPENED_MOST_VISITED_ENTRY); 1056 _browserState, new_tab_page_uma::ACTION_OPENED_MOST_VISITED_ENTRY);
1094 base::RecordAction(UserMetricsAction("MobileNTPMostVisited")); 1057 base::RecordAction(UserMetricsAction("MobileNTPMostVisited"));
1095 const ntp_tiles::NTPTile& tile = _mostVisitedData[visitedIndex]; 1058 const ntp_tiles::NTPTile& tile = _mostVisitedData[visitedIndex];
1096 ntp_tiles::metrics::RecordTileClick(visitedIndex, tile.source, tileType); 1059 ntp_tiles::metrics::RecordTileClick(visitedIndex, tile.source, tileType);
1097 } 1060 }
1098 1061
1099 - (void)onMostVisitedURLsAvailable:(const ntp_tiles::NTPTilesVector&)data {
1100 _mostVisitedData = data;
1101 [self reloadData];
1102
1103 if (data.size() && !_recordedPageImpression) {
1104 _recordedPageImpression = YES;
1105 std::vector<ntp_tiles::metrics::TileImpression> tiles;
1106 for (const ntp_tiles::NTPTile& ntpTile : data) {
1107 tiles.emplace_back(ntpTile.source, ntp_tiles::metrics::UNKNOWN_TILE_TYPE,
1108 ntpTile.url);
1109 }
1110 ntp_tiles::metrics::RecordPageImpression(
1111 tiles, GetApplicationContext()->GetRapporServiceImpl());
1112 }
1113 }
1114
1115 - (void)onIconMadeAvailable:(const GURL&)siteUrl {
1116 for (size_t i = 0; i < [self numberOfItems]; ++i) {
1117 const ntp_tiles::NTPTile& ntpTile = _mostVisitedData[i];
1118 if (ntpTile.url == siteUrl) {
1119 NSIndexPath* indexPath =
1120 [NSIndexPath indexPathForRow:i inSection:SectionWithMostVisited];
1121 [_mostVisitedView reloadItemsAtIndexPaths:@[ indexPath ]];
1122 break;
1123 }
1124 }
1125 }
1126
1127 - (void)reloadData { 1062 - (void)reloadData {
1128 // -reloadData updates from |_mostVisitedData|. 1063 // -reloadData updates from |_mostVisitedData|.
1129 // -invalidateLayout is necessary because sometimes the flowLayout has the 1064 // -invalidateLayout is necessary because sometimes the flowLayout has the
1130 // wrong cached size and will throw an internal exception if the 1065 // wrong cached size and will throw an internal exception if the
1131 // -numberOfItems shrinks. -setNeedsLayout is needed in case 1066 // -numberOfItems shrinks. -setNeedsLayout is needed in case
1132 // -numberOfItems increases enough to add a new row and change the height 1067 // -numberOfItems increases enough to add a new row and change the height
1133 // of _mostVisitedView. 1068 // of _mostVisitedView.
1134 [_mostVisitedView reloadData]; 1069 [_mostVisitedView reloadData];
1135 [[_mostVisitedView collectionViewLayout] invalidateLayout]; 1070 [[_mostVisitedView collectionViewLayout] invalidateLayout];
1136 [self.view setNeedsLayout]; 1071 [self.view setNeedsLayout];
(...skipping 17 matching lines...) Expand all
1154 ? kTopSpacingMaterialPortrait 1089 ? kTopSpacingMaterialPortrait
1155 : kTopSpacingMaterialLandscape; 1090 : kTopSpacingMaterialLandscape;
1156 } 1091 }
1157 } else { 1092 } else {
1158 headerHeight = kNonGoogleSearchHeaderHeightIPad; 1093 headerHeight = kNonGoogleSearchHeaderHeightIPad;
1159 } 1094 }
1160 } 1095 }
1161 return headerHeight; 1096 return headerHeight;
1162 } 1097 }
1163 1098
1099 #pragma mark - MostVisitedSitesObserver
1100
1101 - (void)onMostVisitedURLsAvailable:(const ntp_tiles::NTPTilesVector&)data {
1102 _mostVisitedData = data;
1103 [self reloadData];
1104
1105 if (data.size() && !_recordedPageImpression) {
1106 _recordedPageImpression = YES;
1107 std::vector<ntp_tiles::metrics::TileImpression> tiles;
1108 for (const ntp_tiles::NTPTile& ntpTile : data) {
1109 tiles.emplace_back(ntpTile.source, ntp_tiles::metrics::UNKNOWN_TILE_TYPE,
1110 ntpTile.url);
1111 }
1112 ntp_tiles::metrics::RecordPageImpression(
1113 tiles, GetApplicationContext()->GetRapporServiceImpl());
1114 }
1115 }
1116
1117 - (void)onIconMadeAvailable:(const GURL&)siteUrl {
1118 for (size_t i = 0; i < [self numberOfItems]; ++i) {
1119 const ntp_tiles::NTPTile& ntpTile = _mostVisitedData[i];
1120 if (ntpTile.url == siteUrl) {
1121 NSIndexPath* indexPath =
1122 [NSIndexPath indexPathForRow:i inSection:SectionWithMostVisited];
1123 [_mostVisitedView reloadItemsAtIndexPaths:@[ indexPath ]];
1124 break;
1125 }
1126 }
1127 }
1128
1164 #pragma mark - UICollectionView Methods. 1129 #pragma mark - UICollectionView Methods.
1165 1130
1166 - (CGSize)collectionView:(UICollectionView*)collectionView 1131 - (CGSize)collectionView:(UICollectionView*)collectionView
1167 layout: 1132 layout:
1168 (UICollectionViewLayout*)collectionViewLayout 1133 (UICollectionViewLayout*)collectionViewLayout
1169 referenceSizeForHeaderInSection:(NSInteger)section { 1134 referenceSizeForHeaderInSection:(NSInteger)section {
1170 CGFloat headerHeight = 0; 1135 CGFloat headerHeight = 0;
1171 if (section == SectionWithOmnibox) { 1136 if (section == SectionWithOmnibox) {
1172 headerHeight = [self heightForSectionWithOmnibox]; 1137 headerHeight = [self heightForSectionWithOmnibox];
1173 ((UICollectionViewFlowLayout*)collectionViewLayout).headerReferenceSize = 1138 ((UICollectionViewFlowLayout*)collectionViewLayout).headerReferenceSize =
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
1738 if (!view) { 1703 if (!view) {
1739 return nil; 1704 return nil;
1740 } 1705 }
1741 if ([view isKindOfClass:aClass]) { 1706 if ([view isKindOfClass:aClass]) {
1742 return view; 1707 return view;
1743 } 1708 }
1744 return [self nearestAncestorOfView:[view superview] withClass:aClass]; 1709 return [self nearestAncestorOfView:[view superview] withClass:aClass];
1745 } 1710 }
1746 1711
1747 @end 1712 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698