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

Side by Side Diff: ios/chrome/app/spotlight/topsites_spotlight_manager.mm

Issue 2580363002: Upstream Chrome on iOS source code [1/11]. (Closed)
Patch Set: Created 4 years 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
(Empty)
1 // Copyright 2015 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/app/spotlight/topsites_spotlight_manager.h"
6
7 #include <memory>
8
9 #include "base/ios/weak_nsobject.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/strings/sys_string_conversions.h"
12 #include "components/bookmarks/browser/bookmark_model.h"
13 #include "components/browser_sync/profile_sync_service.h"
14 #include "components/history/core/browser/history_types.h"
15 #include "components/history/core/browser/top_sites.h"
16 #include "components/history/core/browser/top_sites_observer.h"
17 #include "components/suggestions/suggestions_service.h"
18 #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h"
19 #include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h"
20 #include "ios/chrome/browser/history/top_sites_factory.h"
21 #include "ios/chrome/browser/suggestions/suggestions_service_factory.h"
22 #include "ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.h"
23 #include "ios/chrome/browser/sync/sync_observer_bridge.h"
24 #include "ios/chrome/browser/ui/ntp/google_landing_controller.h"
25
26 class SpotlightTopSitesBridge;
27 class SpotlightTopSitesCallbackBridge;
28 class SpotlightSuggestionsBridge;
29
30 @interface TopSitesSpotlightManager ()<SyncObserverModelBridge> {
31 // Bridge to register for top sites changes. It's important that this instance
32 // variable is released before the _topSite one.
33 std::unique_ptr<SpotlightTopSitesBridge> _topSitesBridge;
34
35 // Bridge to register for top sites callbacks.
36 std::unique_ptr<SpotlightTopSitesCallbackBridge> _topSitesCallbackBridge;
37
38 // Bridge to register for sync changes.
39 std::unique_ptr<SyncObserverBridge> sync_observer_bridge_;
40
41 // Bridge to register for suggestion changes.
42 std::unique_ptr<SpotlightSuggestionsBridge> _suggestionsBridge;
43
44 bookmarks::BookmarkModel* _bookmarkModel; // weak
45 suggestions::SuggestionsService* _suggestionService; // weak
46 browser_sync::ProfileSyncService* _syncService; // weak
47
48 scoped_refptr<history::TopSites> _topSites;
49 std::unique_ptr<
50 suggestions::SuggestionsService::ResponseCallbackList::Subscription>
51 _suggestionsServiceResponseSubscription;
52
53 // Indicates if a reindex is pending. Reindexes made by calling the external
54 // reindexTopSites method are executed at most every second.
55 BOOL _isReindexPending;
56 }
57 @property(nonatomic, readonly) scoped_refptr<history::TopSites> topSites;
58
59 - (instancetype)
60 initWithLargeIconService:(favicon::LargeIconService*)largeIconService
61 topSites:(scoped_refptr<history::TopSites>)topSites
62 bookmarkModel:(bookmarks::BookmarkModel*)bookmarkModel
63 profileSyncService:(browser_sync::ProfileSyncService*)syncService
64 suggestionsService:(suggestions::SuggestionsService*)suggestionsService;
65
66 // Updates all indexed top sites from appropriate source, within limit of number
67 // of sites shown on NTP.
68 - (void)updateAllTopSitesSpotlightItems;
69 // Adds all top sites from appropriate source, within limit of number of sites
70 // shown on NTP.
71 - (void)addAllTopSitesSpotlightItems;
72 // Adds all top sites from TopSites source (most visited sites on device),
73 // within limit of number of sites shown on NTP.
74 - (void)addAllLocalTopSitesItems;
75 // Adds all top sites from Suggestions source (server-based), within limit of
76 // number of sites shown on NTP.
77 - (void)addAllSuggestionsTopSitesItems;
78 // Callback for topsites mostvisited, adds sites to spotlight.
79 - (void)onMostVisitedURLsAvailable:
80 (const history::MostVisitedURLList&)top_sites;
81 // Callback for suggestions, adds sites to spotlight.
82 - (void)onSuggestionsProfileAvailable:
83 (const suggestions::SuggestionsProfile&)suggestions_profile;
84
85 @end
86
87 class SpotlightTopSitesCallbackBridge
88 : public base::SupportsWeakPtr<SpotlightTopSitesCallbackBridge> {
89 public:
90 explicit SpotlightTopSitesCallbackBridge(TopSitesSpotlightManager* owner)
91 : owner_(owner) {}
92
93 SpotlightTopSitesCallbackBridge() {}
94
95 void OnMostVisitedURLsAvailable(const history::MostVisitedURLList& data) {
96 [owner_ onMostVisitedURLsAvailable:data];
97 }
98
99 private:
100 __unsafe_unretained TopSitesSpotlightManager* owner_; // weak, owns us
101 };
102
103 class SpotlightTopSitesBridge : public history::TopSitesObserver {
104 public:
105 explicit SpotlightTopSitesBridge(TopSitesSpotlightManager* owner)
106 : owner_(owner) {
107 owner.topSites->AddObserver(this);
108 };
109
110 ~SpotlightTopSitesBridge() override {
111 owner_.topSites->RemoveObserver(this);
112 };
113
114 void TopSitesLoaded(history::TopSites* top_sites) override {}
115
116 void TopSitesChanged(history::TopSites* top_sites,
117 ChangeReason change_reason) override {
118 [owner_ updateAllTopSitesSpotlightItems];
119 }
120
121 private:
122 __unsafe_unretained TopSitesSpotlightManager* owner_; // weak
123 };
124
125 class SpotlightSuggestionsBridge
126 : public base::SupportsWeakPtr<SpotlightSuggestionsBridge> {
127 public:
128 explicit SpotlightSuggestionsBridge(TopSitesSpotlightManager* owner)
129 : owner_(owner) {}
130
131 SpotlightSuggestionsBridge() {}
132
133 void OnSuggestionsProfileAvailable(
134 const suggestions::SuggestionsProfile& suggestions_profile) {
135 [owner_ onSuggestionsProfileAvailable:suggestions_profile];
136 }
137
138 private:
139 __unsafe_unretained TopSitesSpotlightManager* owner_; // weak, owns us
140 };
141
142 @implementation TopSitesSpotlightManager
143 @synthesize topSites = _topSites;
144
145 + (TopSitesSpotlightManager*)topSitesSpotlightManagerWithBrowserState:
146 (ios::ChromeBrowserState*)browserState {
147 return [[[TopSitesSpotlightManager alloc]
148 initWithLargeIconService:IOSChromeLargeIconServiceFactory::
149 GetForBrowserState(browserState)
150 topSites:ios::TopSitesFactory::GetForBrowserState(
151 browserState)
152 bookmarkModel:ios::BookmarkModelFactory::GetForBrowserState(
153 browserState)
154 profileSyncService:IOSChromeProfileSyncServiceFactory::
155 GetForBrowserState(browserState)
156 suggestionsService:suggestions::SuggestionsServiceFactory::
157 GetForBrowserState(browserState)]
158 autorelease];
159 }
160
161 - (instancetype)
162 initWithLargeIconService:(favicon::LargeIconService*)largeIconService
163 topSites:(scoped_refptr<history::TopSites>)topSites
164 bookmarkModel:(bookmarks::BookmarkModel*)bookmarkModel
165 profileSyncService:(browser_sync::ProfileSyncService*)syncService
166 suggestionsService:(suggestions::SuggestionsService*)suggestionsService {
167 self = [super initWithLargeIconService:largeIconService
168 domain:spotlight::DOMAIN_TOPSITES];
169 if (self) {
170 _topSites = topSites;
171 _topSitesBridge.reset(new SpotlightTopSitesBridge(self));
172 _topSitesCallbackBridge.reset(new SpotlightTopSitesCallbackBridge(self));
173 _bookmarkModel = bookmarkModel;
174 _isReindexPending = false;
175 if (syncService && suggestionsService) {
176 _suggestionsBridge.reset(new SpotlightSuggestionsBridge(self));
177 _syncService = syncService;
178 _suggestionService = suggestionsService;
179 _suggestionsServiceResponseSubscription = _suggestionService->AddCallback(
180 base::Bind(&SpotlightSuggestionsBridge::OnSuggestionsProfileAvailable,
181 _suggestionsBridge->AsWeakPtr()));
182 sync_observer_bridge_.reset(new SyncObserverBridge(self, syncService));
183 }
184 }
185 return self;
186 }
187
188 - (void)updateAllTopSitesSpotlightItems {
189 base::WeakNSObject<TopSitesSpotlightManager> weakSelf(self);
190 [self clearAllSpotlightItems:^(NSError* error) {
191 dispatch_async(dispatch_get_main_queue(), ^{
192 [weakSelf addAllTopSitesSpotlightItems];
193 });
194 }];
195 }
196
197 - (void)addAllTopSitesSpotlightItems {
198 if (_suggestionService) {
199 [self addAllSuggestionsTopSitesItems];
200 } else {
201 [self addAllLocalTopSitesItems];
202 }
203 }
204
205 - (void)addAllLocalTopSitesItems {
206 _topSites->GetMostVisitedURLs(
207 base::Bind(&SpotlightTopSitesCallbackBridge::OnMostVisitedURLsAvailable,
208 _topSitesCallbackBridge->AsWeakPtr()),
209 true);
210 }
211
212 - (void)addAllSuggestionsTopSitesItems {
213 if (!_suggestionService->FetchSuggestionsData()) {
214 [self addAllLocalTopSitesItems];
215 }
216 }
217
218 - (BOOL)isURLBookmarked:(const GURL&)URL {
219 if (!_bookmarkModel->loaded())
220 return NO;
221
222 std::vector<const bookmarks::BookmarkNode*> nodes;
223 _bookmarkModel->GetNodesByURL(URL, &nodes);
224 return nodes.size() > 0;
225 }
226
227 - (void)onMostVisitedURLsAvailable:
228 (const history::MostVisitedURLList&)top_sites {
229 NSUInteger sitesToIndex =
230 MIN(top_sites.size(), [GoogleLandingController maxSitesShown]);
231 for (size_t i = 0; i < sitesToIndex; i++) {
232 const GURL& URL = top_sites[i].url;
233
234 // Check if the item is bookmarked, in which case it is already indexed.
235 if ([self isURLBookmarked:URL]) {
236 continue;
237 }
238
239 [self refreshItemsWithURL:URL
240 title:base::SysUTF16ToNSString(top_sites[i].title)];
241 }
242 }
243
244 - (void)onSuggestionsProfileAvailable:
245 (const suggestions::SuggestionsProfile&)suggestionsProfile {
246 size_t size = suggestionsProfile.suggestions_size();
247 if (size) {
248 NSUInteger sitesToIndex =
249 MIN(size, [GoogleLandingController maxSitesShown]);
250 for (size_t i = 0; i < sitesToIndex; i++) {
251 const suggestions::ChromeSuggestion& suggestion =
252 suggestionsProfile.suggestions(i);
253 GURL URL = GURL(suggestion.url());
254 // Check if the item is bookmarked, in which case it is already indexed.
255 if ([self isURLBookmarked:URL]) {
256 continue;
257 }
258
259 std::string title = suggestion.title();
260 [self refreshItemsWithURL:URL title:base::SysUTF8ToNSString(title)];
261 }
262 } else {
263 [self addAllLocalTopSitesItems];
264 }
265 }
266
267 - (void)reindexTopSites {
268 if (_isReindexPending) {
269 return;
270 }
271 _isReindexPending = true;
272 base::WeakNSObject<TopSitesSpotlightManager> weakSelf(self);
273 dispatch_after(
274 dispatch_time(DISPATCH_TIME_NOW, static_cast<int64_t>(1 * NSEC_PER_SEC)),
275 dispatch_get_main_queue(), ^{
276 [weakSelf updateAllTopSitesSpotlightItems];
277 weakSelf.get()->_isReindexPending = false;
278 });
279 }
280
281 #pragma mark -
282 #pragma mark SyncObserverModelBridge
283
284 - (void)onSyncStateChanged {
285 [self updateAllTopSitesSpotlightItems];
286 }
287
288 @end
OLDNEW
« no previous file with comments | « ios/chrome/app/spotlight/topsites_spotlight_manager.h ('k') | ios/chrome/app/startup/chrome_main_starter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698