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

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

Issue 2674893002: Refactor TabModel initialisation from a saved session. (Closed)
Patch Set: Remove unused local variable. 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 // Restore the session and reset the session metrics (as the event have
262 for (CRWNavigationManagerStorage* session in window.sessions) { 271 // not been generated by the user but by a cold start cycle).
263 std::unique_ptr<web::WebState> webState = 272 [self restoreSessionWindow:window persistState:NO];
rohitrao (ping after 24h) 2017/02/06 13:45:40 Is it worth DCHECKing that _observers is still emp
sdefresne 2017/02/06 14:10:45 The only code path that can lead to adding observe
rohitrao (ping after 24h) 2017/02/06 14:15:57 As an example, what would happen if we modified _t
sdefresne 2017/02/06 14:34:02 Called public method on an object that is not init
264 web::WebState::Create(params, session); 273 [self resetSessionMetrics];
rohitrao (ping after 24h) 2017/02/06 13:45:40 This was another difference between the two functi
sdefresne 2017/02/06 14:10:45 Done.
265 DCHECK_EQ(webState->GetBrowserState(), _browserState);
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 } 274 }
291 275
292 _orderController.reset( 276 _orderController.reset(
293 [[TabModelOrderController alloc] initWithTabModel:self]); 277 [[TabModelOrderController alloc] initWithTabModel:self]);
278
294 // Register for resign active notification. 279 // Register for resign active notification.
295 [defaultCenter addObserver:self 280 [[NSNotificationCenter defaultCenter]
296 selector:@selector(willResignActive:) 281 addObserver:self
297 name:UIApplicationWillResignActiveNotification 282 selector:@selector(willResignActive:)
298 object:nil]; 283 name:UIApplicationWillResignActiveNotification
284 object:nil];
299 // Register for background notification. 285 // Register for background notification.
300 [defaultCenter addObserver:self 286 [[NSNotificationCenter defaultCenter]
301 selector:@selector(applicationDidEnterBackground:) 287 addObserver:self
302 name:UIApplicationDidEnterBackgroundNotification 288 selector:@selector(applicationDidEnterBackground:)
303 object:nil]; 289 name:UIApplicationDidEnterBackgroundNotification
290 object:nil];
304 // Register for foregrounding notification. 291 // Register for foregrounding notification.
305 [defaultCenter addObserver:self 292 [[NSNotificationCenter defaultCenter]
306 selector:@selector(applicationWillEnterForeground:) 293 addObserver:self
307 name:UIApplicationWillEnterForegroundNotification 294 selector:@selector(applicationWillEnterForeground:)
308 object:nil]; 295 name:UIApplicationWillEnterForegroundNotification
296 object:nil];
309 297
310 // Associate with ios::ChromeBrowserState. 298 // Associate with ios::ChromeBrowserState.
311 RegisterTabModelWithChromeBrowserState(_browserState, self); 299 RegisterTabModelWithChromeBrowserState(_browserState, self);
312 } 300 }
313 return self; 301 return self;
314 } 302 }
315 303
316 - (instancetype)init { 304 - (instancetype)init {
317 NOTREACHED(); 305 NOTREACHED();
318 return nil; 306 return nil;
319 } 307 }
320 308
321 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window { 309 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window {
322 DCHECK(_browserState); 310 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 } 311 }
372 312
373 - (void)saveSessionImmediately:(BOOL)immediately { 313 - (void)saveSessionImmediately:(BOOL)immediately {
374 // Do nothing if there are tabs in the model but no selected tab. This is 314 // Do nothing if there are tabs in the model but no selected tab. This is
375 // a transitional state. 315 // a transitional state.
376 if ((!_currentTab && [_tabs count]) || !_browserState) 316 if ((!_currentTab && [_tabs count]) || !_browserState)
377 return; 317 return;
378 [_sessionService saveWindow:self.windowForSavingSession 318 [_sessionService saveWindow:self.windowForSavingSession
379 forBrowserState:_browserState 319 forBrowserState:_browserState
380 immediately:immediately]; 320 immediately:immediately];
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 [self insertTab:tab atIndex:index]; 514 [self insertTab:tab atIndex:index];
575 return tab; 515 return tab;
576 } 516 }
577 517
578 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index { 518 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index {
579 DCHECK(tab); 519 DCHECK(tab);
580 DCHECK(index <= [_tabs count]); 520 DCHECK(index <= [_tabs count]);
581 [tab fetchFavicon]; 521 [tab fetchFavicon];
582 [_tabs insertObject:tab atIndex:index]; 522 [_tabs insertObject:tab atIndex:index];
583 523
524 TabParentingGlobalObserver::GetInstance()->OnTabParented(tab.webState);
rohitrao (ping after 24h) 2017/02/06 13:45:40 This is called a lot more often now, isn't it? It
sdefresne 2017/02/06 14:10:45 The method should have been called here too. The m
rohitrao (ping after 24h) 2017/02/06 14:15:57 I looked at the callsites as well and decided that
sdefresne 2017/02/06 14:34:02 Sure, done => https://codereview.chromium.org/2678
584 [_observers tabModel:self didInsertTab:tab atIndex:index inForeground:NO]; 525 [_observers tabModel:self didInsertTab:tab atIndex:index inForeground:NO];
585 [_observers tabModelDidChangeTabCount:self]; 526 [_observers tabModelDidChangeTabCount:self];
586 527
587 base::RecordAction(base::UserMetricsAction("MobileNewTabOpened")); 528 base::RecordAction(base::UserMetricsAction("MobileNewTabOpened"));
588 // Persist the session due to a new tab being inserted. If this is a 529 // Persist the session due to a new tab being inserted. If this is a
589 // background tab (will not become active), saving now will capture the 530 // background tab (will not become active), saving now will capture the
590 // state properly. If it does eventually become active, another save will 531 // state properly. If it does eventually become active, another save will
591 // be triggered to properly capture the end result. 532 // be triggered to properly capture the end result.
592 [self saveSessionImmediately:NO]; 533 [self saveSessionImmediately:NO];
593 ++_newTabCount; 534 ++_newTabCount;
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 // initializer dictionaryWithObject, because that approach adds the dictionary 934 // initializer dictionaryWithObject, because that approach adds the dictionary
994 // to the autorelease pool, which in turn holds Tab alive longer than 935 // to the autorelease pool, which in turn holds Tab alive longer than
995 // necessary. 936 // necessary.
996 base::scoped_nsobject<NSDictionary> userInfo( 937 base::scoped_nsobject<NSDictionary> userInfo(
997 [[NSDictionary alloc] initWithObjectsAndKeys:tab, kTabModelTabKey, nil]); 938 [[NSDictionary alloc] initWithObjectsAndKeys:tab, kTabModelTabKey, nil]);
998 [[NSNotificationCenter defaultCenter] postNotificationName:notificationName 939 [[NSNotificationCenter defaultCenter] postNotificationName:notificationName
999 object:self 940 object:self
1000 userInfo:userInfo]; 941 userInfo:userInfo];
1001 } 942 }
1002 943
944 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window
945 persistState:(BOOL)persistState {
946 DCHECK(_browserState);
947 DCHECK(window);
948
949 NSArray* sessions = window.sessions;
950 if (!sessions.count)
951 return NO;
952
953 size_t oldCount = [_tabs count];
954 web::WebState::CreateParams params(_browserState);
955
956 for (CRWNavigationManagerStorage* session in sessions) {
957 std::unique_ptr<web::WebState> webState =
958 web::WebState::Create(params, session);
959 DCHECK_EQ(webState->GetBrowserState(), _browserState);
960 Tab* tab =
961 [self insertTabWithWebState:std::move(webState) atIndex:[_tabs count]];
962 tab.webController.usePlaceholderOverlay = YES;
963
964 // Restore the CertificatePolicyCache (note that webState is invalid after
965 // passing it via move semantic to -insertTabWithWebState:atIndex:).
966 UpdateCertificatePolicyCacheFromWebState(tab.webState);
967 }
968 DCHECK_GT([_tabs count], oldCount);
969
970 // Update the selected tab if there was a selected Tab in the saved session.
971 if (window.selectedIndex != NSNotFound) {
972 NSUInteger selectedIndex = window.selectedIndex + oldCount;
973 DCHECK_LT(selectedIndex, [_tabs count]);
974 DCHECK([self tabAtIndex:selectedIndex]);
975 [self changeSelectedTabFrom:_currentTab
976 to:[self tabAtIndex:selectedIndex]
977 persistState:persistState];
978 }
979
980 // If there was only one tab and it was the new tab page, clobber it.
981 BOOL closedNTPTab = NO;
982 if (oldCount == 1) {
983 Tab* tab = [_tabs objectAtIndex:0];
984 if (tab.url == GURL(kChromeUINewTabURL)) {
985 [self closeTab:tab];
986 closedNTPTab = YES;
987 oldCount = 0;
988 }
989 }
990 if (_tabUsageRecorder) {
991 _tabUsageRecorder->InitialRestoredTabs(
992 _currentTab,
993 [_tabs
994 subarrayWithRange:NSMakeRange(oldCount, [_tabs count] - oldCount)]);
995 }
996 return closedNTPTab;
997 }
998
1003 #pragma mark - Notification Handlers 999 #pragma mark - Notification Handlers
1004 1000
1005 // Called when UIApplicationWillResignActiveNotification is received. 1001 // Called when UIApplicationWillResignActiveNotification is received.
1006 - (void)willResignActive:(NSNotification*)notify { 1002 - (void)willResignActive:(NSNotification*)notify {
1007 if (webUsageEnabled_ && _currentTab) { 1003 if (webUsageEnabled_ && _currentTab) {
1008 [[SnapshotCache sharedInstance] 1004 [[SnapshotCache sharedInstance]
1009 willBeSavedGreyWhenBackgrounding:_currentTab.get().tabId]; 1005 willBeSavedGreyWhenBackgrounding:_currentTab.get().tabId];
1010 } 1006 }
1011 } 1007 }
1012 1008
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 web::NavigationManager::WebLoadParams params(URL); 1069 web::NavigationManager::WebLoadParams params(URL);
1074 params.referrer = referrer; 1070 params.referrer = referrer;
1075 params.transition_type = ui::PAGE_TRANSITION_TYPED; 1071 params.transition_type = ui::PAGE_TRANSITION_TYPED;
1076 [[tab webController] loadWithParams:params]; 1072 [[tab webController] loadWithParams:params];
1077 [tab webController].webUsageEnabled = webUsageEnabled_; 1073 [tab webController].webUsageEnabled = webUsageEnabled_;
1078 [self insertTab:tab atIndex:index]; 1074 [self insertTab:tab atIndex:index];
1079 return tab; 1075 return tab;
1080 } 1076 }
1081 1077
1082 @end 1078 @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