| 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 7cd840e0bdb9fe53d10612713e34ab5aa7445420..94ee048b52746036e7527c5353657ed8cb9b0594 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,35 @@ 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];
|
| - }
|
| + DCHECK([_observers empty]);
|
| + // 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];
|
| + [self resetSessionMetrics];
|
| }
|
|
|
| _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 +308,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 {
|
| @@ -1002,6 +943,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.
|
|
|