Chromium Code Reviews| Index: ios/chrome/browser/tabs/tab_model.mm |
| diff --git a/ios/chrome/browser/tabs/tab_model.mm b/ios/chrome/browser/tabs/tab_model.mm |
| index 0d324f991f1d252ad29533c3c68245fc6b023216..c770533f678a4607d55469c044e7cf6d01f78a62 100644 |
| --- a/ios/chrome/browser/tabs/tab_model.mm |
| +++ b/ios/chrome/browser/tabs/tab_model.mm |
| @@ -157,6 +157,7 @@ void CleanCertificatePolicyCache( |
| openedByDOM:(BOOL)openedByDOM |
| atIndex:(NSUInteger)index |
| inBackground:(BOOL)inBackground; |
| + |
| // Call to switch the selected tab. Broadcasts about the change in selection. |
| // It's ok for |newTab| to be nil in case the last tab is going away. In that |
| // case, the "tab deselected" notification gets sent, but no corresponding |
| @@ -165,11 +166,20 @@ void CleanCertificatePolicyCache( |
| - (void)changeSelectedTabFrom:(Tab*)oldTab |
| to:(Tab*)newTab |
| persistState:(BOOL)persist; |
| + |
| // Tells the snapshot cache the adjacent tab session ids. |
| - (void)updateSnapshotCache:(Tab*)tab; |
| + |
| // Helper method that posts a notification with the given name with |tab| |
| // in the userInfo dictionary under the kTabModelTabKey. |
| - (void)postNotificationName:(NSString*)notificationName withTab:(Tab*)tab; |
| + |
| +// Helper method to restore a saved session and control if the state should |
| +// be persisted or not. Used to implement the public -restoreSessionWindow: |
| +// method and restoring session in the initialiser. |
| +- (BOOL)restoreSessionWindow:(SessionWindowIOS*)window |
| + persistState:(BOOL)persistState; |
| + |
| @end |
| @implementation TabModel |
| @@ -256,56 +266,34 @@ void CleanCertificatePolicyCache( |
| _syncedWindowDelegate.reset(new TabModelSyncedWindowDelegate(self)); |
| _tabs.reset([[NSMutableArray alloc] init]); |
| - NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter]; |
| if (window) { |
| - web::WebState::CreateParams params(_browserState); |
| - for (CRWNavigationManagerStorage* session in window.sessions) { |
| - std::unique_ptr<web::WebState> webState = |
| - web::WebState::Create(params, session); |
| - DCHECK_EQ(webState->GetBrowserState(), _browserState); |
| - // Restore the CertificatePolicyCache. |
| - UpdateCertificatePolicyCacheFromWebState(webState.get()); |
| - // Create a new tab for each entry in the window. Don't send delegate |
| - // notifications for each restored tab, only when all done. |
| - base::scoped_nsobject<Tab> tab( |
| - [[Tab alloc] initWithWebState:std::move(webState) model:self]); |
| - [tab webController].usePlaceholderOverlay = YES; |
| - [tab fetchFavicon]; |
| - [_tabs addObject:tab]; |
| - |
| - TabParentingGlobalObserver::GetInstance()->OnTabParented( |
| - tab.get().webState); |
| - } |
| - if ([_tabs count]) { |
| - DCHECK(window.selectedIndex < [_tabs count]); |
| - _currentTab.reset([self tabAtIndex:window.selectedIndex]); |
| - DCHECK(_currentTab); |
| - if (_tabUsageRecorder) |
| - _tabUsageRecorder->InitialRestoredTabs(_currentTab, _tabs); |
| - // Perform initializations for affiliated objects which update the |
| - // session information related to the current tab. |
| - [_currentTab updateLastVisitedTimestamp]; |
| - [self saveSessionImmediately:NO]; |
| - } |
| + // Restore the session and reset the session metrics (as the event have |
| + // not been generated by the user but by a cold start cycle). |
| + [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
|
| + [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.
|
| } |
| _orderController.reset( |
| [[TabModelOrderController alloc] initWithTabModel:self]); |
| + |
| // Register for resign active notification. |
| - [defaultCenter addObserver:self |
| - selector:@selector(willResignActive:) |
| - name:UIApplicationWillResignActiveNotification |
| - object:nil]; |
| + [[NSNotificationCenter defaultCenter] |
| + addObserver:self |
| + selector:@selector(willResignActive:) |
| + name:UIApplicationWillResignActiveNotification |
| + object:nil]; |
| // Register for background notification. |
| - [defaultCenter addObserver:self |
| - selector:@selector(applicationDidEnterBackground:) |
| - name:UIApplicationDidEnterBackgroundNotification |
| - object:nil]; |
| + [[NSNotificationCenter defaultCenter] |
| + addObserver:self |
| + selector:@selector(applicationDidEnterBackground:) |
| + name:UIApplicationDidEnterBackgroundNotification |
| + object:nil]; |
| // Register for foregrounding notification. |
| - [defaultCenter addObserver:self |
| - selector:@selector(applicationWillEnterForeground:) |
| - name:UIApplicationWillEnterForegroundNotification |
| - object:nil]; |
| + [[NSNotificationCenter defaultCenter] |
| + addObserver:self |
| + selector:@selector(applicationWillEnterForeground:) |
| + name:UIApplicationWillEnterForegroundNotification |
| + object:nil]; |
| // Associate with ios::ChromeBrowserState. |
| RegisterTabModelWithChromeBrowserState(_browserState, self); |
| @@ -319,55 +307,7 @@ void CleanCertificatePolicyCache( |
| } |
| - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window { |
| - DCHECK(_browserState); |
| - DCHECK(window); |
| - NSArray* sessions = window.sessions; |
| - if (!sessions.count) |
| - return NO; |
| - size_t oldCount = [_tabs count]; |
| - size_t index = oldCount; |
| - web::WebState::CreateParams params(_browserState); |
| - for (CRWNavigationManagerStorage* session in sessions) { |
| - std::unique_ptr<web::WebState> webState = |
| - web::WebState::Create(params, session); |
| - DCHECK_EQ(webState->GetBrowserState(), _browserState); |
| - Tab* tab = [self insertTabWithWebState:std::move(webState) atIndex:index++]; |
| - tab.webController.usePlaceholderOverlay = YES; |
| - // Restore the CertificatePolicyCache. Note that after calling Pass() |
| - // |webState| is invalid, so we need to get the webstate from |tab|. |
| - UpdateCertificatePolicyCacheFromWebState(tab.webState); |
| - } |
| - DCHECK([_tabs count] > oldCount); |
| - // If any tab was restored, the saved selected tab must be selected. |
| - if ([_tabs count] > oldCount) { |
| - NSUInteger selectedIndex = window.selectedIndex; |
| - if (selectedIndex == NSNotFound) |
| - selectedIndex = oldCount; |
| - else |
| - selectedIndex += oldCount; |
| - DCHECK(selectedIndex < [_tabs count]); |
| - Tab* newTab = [self tabAtIndex:selectedIndex]; |
| - DCHECK(newTab); |
| - [self changeSelectedTabFrom:_currentTab to:newTab persistState:YES]; |
| - |
| - // If there was only one tab and it was the new tab page, clobber it. |
| - if (oldCount == 1) { |
| - Tab* tab = [_tabs objectAtIndex:0]; |
| - if (tab.url == GURL(kChromeUINewTabURL)) { |
| - [self closeTab:tab]; |
| - if (_tabUsageRecorder) |
| - _tabUsageRecorder->InitialRestoredTabs(_currentTab, _tabs); |
| - return YES; |
| - } |
| - } |
| - if (_tabUsageRecorder) { |
| - _tabUsageRecorder->InitialRestoredTabs( |
| - _currentTab, |
| - [_tabs subarrayWithRange:NSMakeRange(oldCount, |
| - [_tabs count] - oldCount)]); |
| - } |
| - } |
| - return NO; |
| + return [self restoreSessionWindow:window persistState:YES]; |
| } |
| - (void)saveSessionImmediately:(BOOL)immediately { |
| @@ -581,6 +521,7 @@ void CleanCertificatePolicyCache( |
| [tab fetchFavicon]; |
| [_tabs insertObject:tab atIndex:index]; |
| + 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
|
| [_observers tabModel:self didInsertTab:tab atIndex:index inForeground:NO]; |
| [_observers tabModelDidChangeTabCount:self]; |
| @@ -1000,6 +941,61 @@ void CleanCertificatePolicyCache( |
| userInfo:userInfo]; |
| } |
| +- (BOOL)restoreSessionWindow:(SessionWindowIOS*)window |
| + persistState:(BOOL)persistState { |
| + DCHECK(_browserState); |
| + DCHECK(window); |
| + |
| + NSArray* sessions = window.sessions; |
| + if (!sessions.count) |
| + return NO; |
| + |
| + size_t oldCount = [_tabs count]; |
| + web::WebState::CreateParams params(_browserState); |
| + |
| + for (CRWNavigationManagerStorage* session in sessions) { |
| + std::unique_ptr<web::WebState> webState = |
| + web::WebState::Create(params, session); |
| + DCHECK_EQ(webState->GetBrowserState(), _browserState); |
| + Tab* tab = |
| + [self insertTabWithWebState:std::move(webState) atIndex:[_tabs count]]; |
| + tab.webController.usePlaceholderOverlay = YES; |
| + |
| + // Restore the CertificatePolicyCache (note that webState is invalid after |
| + // passing it via move semantic to -insertTabWithWebState:atIndex:). |
| + UpdateCertificatePolicyCacheFromWebState(tab.webState); |
| + } |
| + DCHECK_GT([_tabs count], oldCount); |
| + |
| + // Update the selected tab if there was a selected Tab in the saved session. |
| + if (window.selectedIndex != NSNotFound) { |
| + NSUInteger selectedIndex = window.selectedIndex + oldCount; |
| + DCHECK_LT(selectedIndex, [_tabs count]); |
| + DCHECK([self tabAtIndex:selectedIndex]); |
| + [self changeSelectedTabFrom:_currentTab |
| + to:[self tabAtIndex:selectedIndex] |
| + persistState:persistState]; |
| + } |
| + |
| + // If there was only one tab and it was the new tab page, clobber it. |
| + BOOL closedNTPTab = NO; |
| + if (oldCount == 1) { |
| + Tab* tab = [_tabs objectAtIndex:0]; |
| + if (tab.url == GURL(kChromeUINewTabURL)) { |
| + [self closeTab:tab]; |
| + closedNTPTab = YES; |
| + oldCount = 0; |
| + } |
| + } |
| + if (_tabUsageRecorder) { |
| + _tabUsageRecorder->InitialRestoredTabs( |
| + _currentTab, |
| + [_tabs |
| + subarrayWithRange:NSMakeRange(oldCount, [_tabs count] - oldCount)]); |
| + } |
| + return closedNTPTab; |
| +} |
| + |
| #pragma mark - Notification Handlers |
| // Called when UIApplicationWillResignActiveNotification is received. |