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

Side by Side Diff: ios/chrome/browser/tabs/tab_model.mm

Issue 2674893002: Refactor TabModel initialisation from a saved session. (Closed)
Patch Set: Rebase. Created 3 years, 10 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/tabs/tab_model.h" 5 #import "ios/chrome/browser/tabs/tab_model.h"
6 6
7 #include <list> 7 #include <list>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 // The |index| parameter can be set to 150 // The |index| parameter can be set to
151 // TabModelConstants::kTabPositionAutomatically if the caller doesn't have a 151 // TabModelConstants::kTabPositionAutomatically if the caller doesn't have a
152 // preference for the position of the tab. 152 // preference for the position of the tab.
153 - (Tab*)insertTabWithLoadParams: 153 - (Tab*)insertTabWithLoadParams:
154 (const web::NavigationManager::WebLoadParams&)params 154 (const web::NavigationManager::WebLoadParams&)params
155 windowName:(NSString*)windowName 155 windowName:(NSString*)windowName
156 opener:(Tab*)parentTab 156 opener:(Tab*)parentTab
157 openedByDOM:(BOOL)openedByDOM 157 openedByDOM:(BOOL)openedByDOM
158 atIndex:(NSUInteger)index 158 atIndex:(NSUInteger)index
159 inBackground:(BOOL)inBackground; 159 inBackground:(BOOL)inBackground;
160
160 // Call to switch the selected tab. Broadcasts about the change in selection. 161 // Call to switch the selected tab. Broadcasts about the change in selection.
161 // It's ok for |newTab| to be nil in case the last tab is going away. In that 162 // It's ok for |newTab| to be nil in case the last tab is going away. In that
162 // case, the "tab deselected" notification gets sent, but no corresponding 163 // case, the "tab deselected" notification gets sent, but no corresponding
163 // "tab selected" notification is sent. |persist| indicates whether or not 164 // "tab selected" notification is sent. |persist| indicates whether or not
164 // the tab's state should be persisted in history upon switching. 165 // the tab's state should be persisted in history upon switching.
165 - (void)changeSelectedTabFrom:(Tab*)oldTab 166 - (void)changeSelectedTabFrom:(Tab*)oldTab
166 to:(Tab*)newTab 167 to:(Tab*)newTab
167 persistState:(BOOL)persist; 168 persistState:(BOOL)persist;
169
168 // Tells the snapshot cache the adjacent tab session ids. 170 // Tells the snapshot cache the adjacent tab session ids.
169 - (void)updateSnapshotCache:(Tab*)tab; 171 - (void)updateSnapshotCache:(Tab*)tab;
172
170 // Helper method that posts a notification with the given name with |tab| 173 // Helper method that posts a notification with the given name with |tab|
171 // in the userInfo dictionary under the kTabModelTabKey. 174 // in the userInfo dictionary under the kTabModelTabKey.
172 - (void)postNotificationName:(NSString*)notificationName withTab:(Tab*)tab; 175 - (void)postNotificationName:(NSString*)notificationName withTab:(Tab*)tab;
176
177 // Helper method to restore a saved session and control if the state should
178 // be persisted or not. Used to implement the public -restoreSessionWindow:
179 // method and restoring session in the initialiser.
180 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window
181 persistState:(BOOL)persistState;
182
173 @end 183 @end
174 184
175 @implementation TabModel 185 @implementation TabModel
176 186
177 @synthesize browserState = _browserState; 187 @synthesize browserState = _browserState;
178 @synthesize sessionID = _sessionID; 188 @synthesize sessionID = _sessionID;
179 @synthesize webUsageEnabled = webUsageEnabled_; 189 @synthesize webUsageEnabled = webUsageEnabled_;
180 190
181 #pragma mark - Overriden 191 #pragma mark - Overriden
182 192
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 // Normal browser states are the only ones to get tab restore. Tab sync 259 // Normal browser states are the only ones to get tab restore. Tab sync
250 // handles incognito browser states by filtering on profile, so it's 260 // handles incognito browser states by filtering on profile, so it's
251 // important to the backend code to always have a sync window delegate. 261 // important to the backend code to always have a sync window delegate.
252 if (!_browserState->IsOffTheRecord()) { 262 if (!_browserState->IsOffTheRecord()) {
253 // Set up the usage recorder before tabs are created. 263 // Set up the usage recorder before tabs are created.
254 _tabUsageRecorder.reset(new TabUsageRecorder(self)); 264 _tabUsageRecorder.reset(new TabUsageRecorder(self));
255 } 265 }
256 _syncedWindowDelegate.reset(new TabModelSyncedWindowDelegate(self)); 266 _syncedWindowDelegate.reset(new TabModelSyncedWindowDelegate(self));
257 267
258 _tabs.reset([[NSMutableArray alloc] init]); 268 _tabs.reset([[NSMutableArray alloc] init]);
259 NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
260 if (window) { 269 if (window) {
261 web::WebState::CreateParams params(_browserState); 270 DCHECK([_observers empty]);
262 for (CRWNavigationManagerStorage* session in window.sessions) { 271 // Restore the session and reset the session metrics (as the event have
263 std::unique_ptr<web::WebState> webState = 272 // not been generated by the user but by a cold start cycle).
264 web::WebState::Create(params, session); 273 [self restoreSessionWindow:window persistState:NO];
265 DCHECK_EQ(webState->GetBrowserState(), _browserState); 274 [self resetSessionMetrics];
266 // Restore the CertificatePolicyCache.
267 UpdateCertificatePolicyCacheFromWebState(webState.get());
268 // Create a new tab for each entry in the window. Don't send delegate
269 // notifications for each restored tab, only when all done.
270 base::scoped_nsobject<Tab> tab(
271 [[Tab alloc] initWithWebState:std::move(webState) model:self]);
272 [tab webController].usePlaceholderOverlay = YES;
273 [tab fetchFavicon];
274 [_tabs addObject:tab];
275
276 TabParentingGlobalObserver::GetInstance()->OnTabParented(
277 tab.get().webState);
278 }
279 if ([_tabs count]) {
280 DCHECK(window.selectedIndex < [_tabs count]);
281 _currentTab.reset([self tabAtIndex:window.selectedIndex]);
282 DCHECK(_currentTab);
283 if (_tabUsageRecorder)
284 _tabUsageRecorder->InitialRestoredTabs(_currentTab, _tabs);
285 // Perform initializations for affiliated objects which update the
286 // session information related to the current tab.
287 [_currentTab updateLastVisitedTimestamp];
288 [self saveSessionImmediately:NO];
289 }
290 } 275 }
291 276
292 _orderController.reset( 277 _orderController.reset(
293 [[TabModelOrderController alloc] initWithTabModel:self]); 278 [[TabModelOrderController alloc] initWithTabModel:self]);
279
294 // Register for resign active notification. 280 // Register for resign active notification.
295 [defaultCenter addObserver:self 281 [[NSNotificationCenter defaultCenter]
296 selector:@selector(willResignActive:) 282 addObserver:self
297 name:UIApplicationWillResignActiveNotification 283 selector:@selector(willResignActive:)
298 object:nil]; 284 name:UIApplicationWillResignActiveNotification
285 object:nil];
299 // Register for background notification. 286 // Register for background notification.
300 [defaultCenter addObserver:self 287 [[NSNotificationCenter defaultCenter]
301 selector:@selector(applicationDidEnterBackground:) 288 addObserver:self
302 name:UIApplicationDidEnterBackgroundNotification 289 selector:@selector(applicationDidEnterBackground:)
303 object:nil]; 290 name:UIApplicationDidEnterBackgroundNotification
291 object:nil];
304 // Register for foregrounding notification. 292 // Register for foregrounding notification.
305 [defaultCenter addObserver:self 293 [[NSNotificationCenter defaultCenter]
306 selector:@selector(applicationWillEnterForeground:) 294 addObserver:self
307 name:UIApplicationWillEnterForegroundNotification 295 selector:@selector(applicationWillEnterForeground:)
308 object:nil]; 296 name:UIApplicationWillEnterForegroundNotification
297 object:nil];
309 298
310 // Associate with ios::ChromeBrowserState. 299 // Associate with ios::ChromeBrowserState.
311 RegisterTabModelWithChromeBrowserState(_browserState, self); 300 RegisterTabModelWithChromeBrowserState(_browserState, self);
312 } 301 }
313 return self; 302 return self;
314 } 303 }
315 304
316 - (instancetype)init { 305 - (instancetype)init {
317 NOTREACHED(); 306 NOTREACHED();
318 return nil; 307 return nil;
319 } 308 }
320 309
321 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window { 310 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window {
322 DCHECK(_browserState); 311 return [self restoreSessionWindow:window persistState:YES];
323 DCHECK(window);
324 NSArray* sessions = window.sessions;
325 if (!sessions.count)
326 return NO;
327 size_t oldCount = [_tabs count];
328 size_t index = oldCount;
329 web::WebState::CreateParams params(_browserState);
330 for (CRWNavigationManagerStorage* session in sessions) {
331 std::unique_ptr<web::WebState> webState =
332 web::WebState::Create(params, session);
333 DCHECK_EQ(webState->GetBrowserState(), _browserState);
334 Tab* tab = [self insertTabWithWebState:std::move(webState) atIndex:index++];
335 tab.webController.usePlaceholderOverlay = YES;
336 // Restore the CertificatePolicyCache. Note that after calling Pass()
337 // |webState| is invalid, so we need to get the webstate from |tab|.
338 UpdateCertificatePolicyCacheFromWebState(tab.webState);
339 }
340 DCHECK([_tabs count] > oldCount);
341 // If any tab was restored, the saved selected tab must be selected.
342 if ([_tabs count] > oldCount) {
343 NSUInteger selectedIndex = window.selectedIndex;
344 if (selectedIndex == NSNotFound)
345 selectedIndex = oldCount;
346 else
347 selectedIndex += oldCount;
348 DCHECK(selectedIndex < [_tabs count]);
349 Tab* newTab = [self tabAtIndex:selectedIndex];
350 DCHECK(newTab);
351 [self changeSelectedTabFrom:_currentTab to:newTab persistState:YES];
352
353 // If there was only one tab and it was the new tab page, clobber it.
354 if (oldCount == 1) {
355 Tab* tab = [_tabs objectAtIndex:0];
356 if (tab.url == GURL(kChromeUINewTabURL)) {
357 [self closeTab:tab];
358 if (_tabUsageRecorder)
359 _tabUsageRecorder->InitialRestoredTabs(_currentTab, _tabs);
360 return YES;
361 }
362 }
363 if (_tabUsageRecorder) {
364 _tabUsageRecorder->InitialRestoredTabs(
365 _currentTab,
366 [_tabs subarrayWithRange:NSMakeRange(oldCount,
367 [_tabs count] - oldCount)]);
368 }
369 }
370 return NO;
371 } 312 }
372 313
373 - (void)saveSessionImmediately:(BOOL)immediately { 314 - (void)saveSessionImmediately:(BOOL)immediately {
374 // Do nothing if there are tabs in the model but no selected tab. This is 315 // Do nothing if there are tabs in the model but no selected tab. This is
375 // a transitional state. 316 // a transitional state.
376 if ((!_currentTab && [_tabs count]) || !_browserState) 317 if ((!_currentTab && [_tabs count]) || !_browserState)
377 return; 318 return;
378 [_sessionService saveWindow:self.windowForSavingSession 319 [_sessionService saveWindow:self.windowForSavingSession
379 forBrowserState:_browserState 320 forBrowserState:_browserState
380 immediately:immediately]; 321 immediately:immediately];
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 // initializer dictionaryWithObject, because that approach adds the dictionary 936 // initializer dictionaryWithObject, because that approach adds the dictionary
996 // to the autorelease pool, which in turn holds Tab alive longer than 937 // to the autorelease pool, which in turn holds Tab alive longer than
997 // necessary. 938 // necessary.
998 base::scoped_nsobject<NSDictionary> userInfo( 939 base::scoped_nsobject<NSDictionary> userInfo(
999 [[NSDictionary alloc] initWithObjectsAndKeys:tab, kTabModelTabKey, nil]); 940 [[NSDictionary alloc] initWithObjectsAndKeys:tab, kTabModelTabKey, nil]);
1000 [[NSNotificationCenter defaultCenter] postNotificationName:notificationName 941 [[NSNotificationCenter defaultCenter] postNotificationName:notificationName
1001 object:self 942 object:self
1002 userInfo:userInfo]; 943 userInfo:userInfo];
1003 } 944 }
1004 945
946 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window
947 persistState:(BOOL)persistState {
948 DCHECK(_browserState);
949 DCHECK(window);
950
951 NSArray* sessions = window.sessions;
952 if (!sessions.count)
953 return NO;
954
955 size_t oldCount = [_tabs count];
956 web::WebState::CreateParams params(_browserState);
957
958 for (CRWNavigationManagerStorage* session in sessions) {
959 std::unique_ptr<web::WebState> webState =
960 web::WebState::Create(params, session);
961 DCHECK_EQ(webState->GetBrowserState(), _browserState);
962 Tab* tab =
963 [self insertTabWithWebState:std::move(webState) atIndex:[_tabs count]];
964 tab.webController.usePlaceholderOverlay = YES;
965
966 // Restore the CertificatePolicyCache (note that webState is invalid after
967 // passing it via move semantic to -insertTabWithWebState:atIndex:).
968 UpdateCertificatePolicyCacheFromWebState(tab.webState);
969 }
970 DCHECK_GT([_tabs count], oldCount);
971
972 // Update the selected tab if there was a selected Tab in the saved session.
973 if (window.selectedIndex != NSNotFound) {
974 NSUInteger selectedIndex = window.selectedIndex + oldCount;
975 DCHECK_LT(selectedIndex, [_tabs count]);
976 DCHECK([self tabAtIndex:selectedIndex]);
977 [self changeSelectedTabFrom:_currentTab
978 to:[self tabAtIndex:selectedIndex]
979 persistState:persistState];
980 }
981
982 // If there was only one tab and it was the new tab page, clobber it.
983 BOOL closedNTPTab = NO;
984 if (oldCount == 1) {
985 Tab* tab = [_tabs objectAtIndex:0];
986 if (tab.url == GURL(kChromeUINewTabURL)) {
987 [self closeTab:tab];
988 closedNTPTab = YES;
989 oldCount = 0;
990 }
991 }
992 if (_tabUsageRecorder) {
993 _tabUsageRecorder->InitialRestoredTabs(
994 _currentTab,
995 [_tabs
996 subarrayWithRange:NSMakeRange(oldCount, [_tabs count] - oldCount)]);
997 }
998 return closedNTPTab;
999 }
1000
1005 #pragma mark - Notification Handlers 1001 #pragma mark - Notification Handlers
1006 1002
1007 // Called when UIApplicationWillResignActiveNotification is received. 1003 // Called when UIApplicationWillResignActiveNotification is received.
1008 - (void)willResignActive:(NSNotification*)notify { 1004 - (void)willResignActive:(NSNotification*)notify {
1009 if (webUsageEnabled_ && _currentTab) { 1005 if (webUsageEnabled_ && _currentTab) {
1010 [[SnapshotCache sharedInstance] 1006 [[SnapshotCache sharedInstance]
1011 willBeSavedGreyWhenBackgrounding:_currentTab.get().tabId]; 1007 willBeSavedGreyWhenBackgrounding:_currentTab.get().tabId];
1012 } 1008 }
1013 } 1009 }
1014 1010
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1075 web::NavigationManager::WebLoadParams params(URL); 1071 web::NavigationManager::WebLoadParams params(URL);
1076 params.referrer = referrer; 1072 params.referrer = referrer;
1077 params.transition_type = ui::PAGE_TRANSITION_TYPED; 1073 params.transition_type = ui::PAGE_TRANSITION_TYPED;
1078 [[tab webController] loadWithParams:params]; 1074 [[tab webController] loadWithParams:params];
1079 [tab webController].webUsageEnabled = webUsageEnabled_; 1075 [tab webController].webUsageEnabled = webUsageEnabled_;
1080 [self insertTab:tab atIndex:index]; 1076 [self insertTab:tab atIndex:index];
1081 return tab; 1077 return tab;
1082 } 1078 }
1083 1079
1084 @end 1080 @end
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698