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

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

Issue 2649403002: Revert of WebStateList is an array of web::WebState* wrappers. (Closed)
Patch Set: Fix conflicts with other CLs. 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 | « ios/chrome/browser/tabs/tab_model.h ('k') | ios/chrome/browser/tabs/tab_model_unittest.mm » ('j') | 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 @"kTabModelTabDeselectedNotification"; 59 @"kTabModelTabDeselectedNotification";
60 NSString* const kTabModelNewTabWillOpenNotification = 60 NSString* const kTabModelNewTabWillOpenNotification =
61 @"kTabModelNewTabWillOpenNotification"; 61 @"kTabModelNewTabWillOpenNotification";
62 NSString* const kTabModelTabKey = @"tab"; 62 NSString* const kTabModelTabKey = @"tab";
63 NSString* const kTabModelPageLoadSuccess = @"pageLoadSuccess"; 63 NSString* const kTabModelPageLoadSuccess = @"pageLoadSuccess";
64 NSString* const kTabModelOpenInBackgroundKey = @"shouldOpenInBackground"; 64 NSString* const kTabModelOpenInBackgroundKey = @"shouldOpenInBackground";
65 65
66 namespace { 66 namespace {
67 67
68 // Updates CRWSessionCertificatePolicyManager's certificate policy cache. 68 // Updates CRWSessionCertificatePolicyManager's certificate policy cache.
69 void UpdateCertificatePolicyCacheFromWebState(web::WebStateImpl* web_state) { 69 void UpdateCertificatePolicyCacheFromWebState(web::WebStateImpl* webState) {
70 DCHECK([NSThread isMainThread]); 70 DCHECK([NSThread isMainThread]);
71 DCHECK(web_state); 71 DCHECK(webState);
72 scoped_refptr<web::CertificatePolicyCache> policy_cache = 72 scoped_refptr<web::CertificatePolicyCache> policy_cache =
73 web::BrowserState::GetCertificatePolicyCache( 73 web::BrowserState::GetCertificatePolicyCache(webState->GetBrowserState());
74 web_state->GetBrowserState());
75 CRWSessionController* controller = 74 CRWSessionController* controller =
76 web_state->GetNavigationManagerImpl().GetSessionController(); 75 webState->GetNavigationManagerImpl().GetSessionController();
77 [[controller sessionCertificatePolicyManager] 76 [[controller sessionCertificatePolicyManager]
78 updateCertificatePolicyCache:policy_cache]; 77 updateCertificatePolicyCache:policy_cache];
79 } 78 }
80 79
81 // Populates the certificate policy cache based on the current entries of the 80 // Populates the certificate policy cache based on the current entries of the
82 // given tabs. 81 // given tabs.
83 void RestoreCertificatePolicyCacheFromTabs(WebStateList* web_state_list) { 82 void RestoreCertificatePolicyCacheFromTabs(NSArray* tabs) {
84 DCHECK([NSThread isMainThread]); 83 DCHECK([NSThread isMainThread]);
85 for (id<WebStateHandle> web_state in web_state_list) { 84 for (Tab* tab in tabs) {
86 UpdateCertificatePolicyCacheFromWebState(web_state.webStateImpl); 85 UpdateCertificatePolicyCacheFromWebState(tab.webStateImpl);
87 } 86 }
88 } 87 }
89 88
90 // Scrubs the certificate policy cache of all the certificate policies except 89 // Scrubs the certificate policy cache of all the certificate policies except
91 // those for the current entries of the given tabs. 90 // those for the current entries of the given tabs.
92 void CleanCertificatePolicyCache( 91 void CleanCertificatePolicyCache(
93 scoped_refptr<web::CertificatePolicyCache> policy_cache, 92 scoped_refptr<web::CertificatePolicyCache> policy_cache,
94 WebStateList* web_state_list) { 93 NSArray* tabs) {
95 DCHECK_CURRENTLY_ON(web::WebThread::IO); 94 DCHECK_CURRENTLY_ON(web::WebThread::IO);
96 DCHECK(policy_cache); 95 DCHECK(policy_cache);
97 policy_cache->ClearCertificatePolicies(); 96 policy_cache->ClearCertificatePolicies();
98 web::WebThread::PostTask( 97 web::WebThread::PostTask(
99 web::WebThread::UI, FROM_HERE, 98 web::WebThread::UI, FROM_HERE,
100 base::Bind(&RestoreCertificatePolicyCacheFromTabs, web_state_list)); 99 base::Bind(&RestoreCertificatePolicyCacheFromTabs, tabs));
101 }
102
103 // Creates a NSArray<Tab*>* with elements from |web_state_list| falling into
104 // |range|. This is for compatibility with TabUsageRecorder existing API. That
105 // API will be refactored in later CL and this method removed, see
106 // http://crbug.com/681867 for details.
107 NSArray<Tab*>* GetTabsFromWebStateList(WebStateList* web_state_list,
108 NSRange range) {
109 base::scoped_nsobject<NSMutableArray<Tab*>> mutableArray(
110 [[NSMutableArray alloc] initWithCapacity:range.length]);
111
112 for (NSUInteger ii = range.location; NSLocationInRange(ii, range); ++ii) {
113 [mutableArray addObject:[web_state_list webStateAtIndex:ii]];
114 }
115
116 return [[mutableArray copy] autorelease];
117 } 100 }
118 101
119 } // anonymous namespace 102 } // anonymous namespace
120 103
121 @interface TabModelObservers : CRBProtocolObservers<TabModelObserver> 104 @interface TabModelObservers : CRBProtocolObservers<TabModelObserver>
122 @end 105 @end
123 @implementation TabModelObservers 106 @implementation TabModelObservers
124 @end 107 @end
125 108
126 @interface TabModel ()<TabUsageRecorderDelegate> { 109 @interface TabModel ()<TabUsageRecorderDelegate> {
110 // Array of |Tab| objects.
111 base::scoped_nsobject<NSMutableArray> _tabs;
127 // Maintains policy for where new tabs go and the selection when a tab 112 // Maintains policy for where new tabs go and the selection when a tab
128 // is removed. 113 // is removed.
129 base::scoped_nsobject<TabModelOrderController> _orderController; 114 base::scoped_nsobject<TabModelOrderController> _orderController;
130 // The delegate for sync. 115 // The delegate for sync.
131 std::unique_ptr<TabModelSyncedWindowDelegate> _syncedWindowDelegate; 116 std::unique_ptr<TabModelSyncedWindowDelegate> _syncedWindowDelegate;
132 // Currently selected tab. May be nil. 117 // Currently selected tab. May be nil.
133 base::WeakNSObject<Tab> _currentTab; 118 base::WeakNSObject<Tab> _currentTab;
134 119
135 // Counters for metrics. 120 // Counters for metrics.
136 int _openedTabCount; 121 int _openedTabCount;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 [super dealloc]; 190 [super dealloc];
206 } 191 }
207 192
208 #pragma mark - Public methods 193 #pragma mark - Public methods
209 194
210 - (Tab*)currentTab { 195 - (Tab*)currentTab {
211 return _currentTab.get(); 196 return _currentTab.get();
212 } 197 }
213 198
214 - (void)setCurrentTab:(Tab*)newTab { 199 - (void)setCurrentTab:(Tab*)newTab {
215 DCHECK([self containsWebState:newTab]); 200 DCHECK([_tabs containsObject:newTab]);
216 if (_currentTab != newTab) { 201 if (_currentTab != newTab) {
217 base::RecordAction(base::UserMetricsAction("MobileTabSwitched")); 202 base::RecordAction(base::UserMetricsAction("MobileTabSwitched"));
218 [self updateSnapshotCache:newTab]; 203 [self updateSnapshotCache:newTab];
219 } 204 }
220 if (_tabUsageRecorder) { 205 if (_tabUsageRecorder) {
221 _tabUsageRecorder->RecordTabSwitched(_currentTab, newTab); 206 _tabUsageRecorder->RecordTabSwitched(_currentTab, newTab);
222 } 207 }
223 [self changeSelectedTabFrom:_currentTab to:newTab persistState:YES]; 208 [self changeSelectedTabFrom:_currentTab to:newTab persistState:YES];
224 } 209 }
225 210
226 - (TabModelSyncedWindowDelegate*)syncedWindowDelegate { 211 - (TabModelSyncedWindowDelegate*)syncedWindowDelegate {
227 return _syncedWindowDelegate.get(); 212 return _syncedWindowDelegate.get();
228 } 213 }
229 214
230 - (TabUsageRecorder*)tabUsageRecorder { 215 - (TabUsageRecorder*)tabUsageRecorder {
231 return _tabUsageRecorder.get(); 216 return _tabUsageRecorder.get();
232 } 217 }
233 218
234 - (BOOL)isOffTheRecord { 219 - (BOOL)isOffTheRecord {
235 return _browserState && _browserState->IsOffTheRecord(); 220 return _browserState && _browserState->IsOffTheRecord();
236 } 221 }
237 222
238 - (BOOL)isEmpty { 223 - (BOOL)isEmpty {
239 return self.count == 0; 224 return self.count == 0;
240 } 225 }
241 226
227 - (NSUInteger)count {
228 return [_tabs count];
229 }
230
242 - (instancetype)initWithSessionWindow:(SessionWindowIOS*)window 231 - (instancetype)initWithSessionWindow:(SessionWindowIOS*)window
243 sessionService:(SessionServiceIOS*)service 232 sessionService:(SessionServiceIOS*)service
244 browserState:(ios::ChromeBrowserState*)browserState { 233 browserState:(ios::ChromeBrowserState*)browserState {
245 if ((self = [super init])) { 234 if ((self = [super init])) {
246 _observers.reset([[TabModelObservers 235 _observers.reset([[TabModelObservers
247 observersWithProtocol:@protocol(TabModelObserver)] retain]); 236 observersWithProtocol:@protocol(TabModelObserver)] retain]);
248 237
249 _browserState = browserState; 238 _browserState = browserState;
250 DCHECK(_browserState); 239 DCHECK(_browserState);
251 240
252 // There must be a valid session service defined to consume session windows. 241 // There must be a valid session service defined to consume session windows.
253 DCHECK(service); 242 DCHECK(service);
254 _sessionService.reset([service retain]); 243 _sessionService.reset([service retain]);
255 244
256 // Normal browser states are the only ones to get tab restore. Tab sync 245 // Normal browser states are the only ones to get tab restore. Tab sync
257 // handles incognito browser states by filtering on profile, so it's 246 // handles incognito browser states by filtering on profile, so it's
258 // important to the backend code to always have a sync window delegate. 247 // important to the backend code to always have a sync window delegate.
259 if (!_browserState->IsOffTheRecord()) { 248 if (!_browserState->IsOffTheRecord()) {
260 // Set up the usage recorder before tabs are created. 249 // Set up the usage recorder before tabs are created.
261 _tabUsageRecorder.reset(new TabUsageRecorder(self)); 250 _tabUsageRecorder.reset(new TabUsageRecorder(self));
262 } 251 }
263 _syncedWindowDelegate.reset(new TabModelSyncedWindowDelegate(self)); 252 _syncedWindowDelegate.reset(new TabModelSyncedWindowDelegate(self));
264 253
254 _tabs.reset([[NSMutableArray alloc] init]);
265 NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter]; 255 NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
266 if (window) { 256 if (window) {
267 while (window.unclaimedSessions) { 257 while (window.unclaimedSessions) {
268 std::unique_ptr<web::WebStateImpl> webState = [window nextSession]; 258 std::unique_ptr<web::WebStateImpl> webState = [window nextSession];
269 DCHECK_EQ(webState->GetBrowserState(), _browserState); 259 DCHECK_EQ(webState->GetBrowserState(), _browserState);
270 // Restore the CertificatePolicyCache. 260 // Restore the CertificatePolicyCache.
271 UpdateCertificatePolicyCacheFromWebState(webState.get()); 261 UpdateCertificatePolicyCacheFromWebState(webState.get());
272 // Create a new tab for each entry in the window. Don't send delegate 262 // Create a new tab for each entry in the window. Don't send delegate
273 // notifications for each restored tab, only when all done. 263 // notifications for each restored tab, only when all done.
274 base::scoped_nsobject<Tab> tab( 264 base::scoped_nsobject<Tab> tab(
275 [[Tab alloc] initWithWebState:std::move(webState) model:self]); 265 [[Tab alloc] initWithWebState:std::move(webState) model:self]);
276 [tab webController].usePlaceholderOverlay = YES; 266 [tab webController].usePlaceholderOverlay = YES;
277 [tab fetchFavicon]; 267 [tab fetchFavicon];
278 [self addWebState:tab]; 268 [_tabs addObject:tab];
279 269
280 TabParentingGlobalObserver::GetInstance()->OnTabParented( 270 TabParentingGlobalObserver::GetInstance()->OnTabParented(
281 [tab webStateImpl]); 271 [tab webStateImpl]);
282 } 272 }
283 if (self.count) { 273 if ([_tabs count]) {
284 DCHECK(window.selectedIndex < self.count); 274 DCHECK(window.selectedIndex < [_tabs count]);
285 _currentTab.reset([self tabAtIndex:window.selectedIndex]); 275 _currentTab.reset([self tabAtIndex:window.selectedIndex]);
286 DCHECK(_currentTab); 276 DCHECK(_currentTab);
287 if (_tabUsageRecorder) { 277 if (_tabUsageRecorder)
288 _tabUsageRecorder->InitialRestoredTabs( 278 _tabUsageRecorder->InitialRestoredTabs(_currentTab, _tabs);
289 _currentTab,
290 GetTabsFromWebStateList(self, NSMakeRange(0, self.count)));
291 }
292 // Perform initializations for affiliated objects which update the 279 // Perform initializations for affiliated objects which update the
293 // session information related to the current tab. 280 // session information related to the current tab.
294 [_currentTab updateLastVisitedTimestamp]; 281 [_currentTab updateLastVisitedTimestamp];
295 [self saveSessionImmediately:NO]; 282 [self saveSessionImmediately:NO];
296 } 283 }
297 } 284 }
298 285
299 _orderController.reset( 286 _orderController.reset(
300 [[TabModelOrderController alloc] initWithTabModel:self]); 287 [[TabModelOrderController alloc] initWithTabModel:self]);
301 // Register for resign active notification. 288 // Register for resign active notification.
(...skipping 21 matching lines...) Expand all
323 - (instancetype)init { 310 - (instancetype)init {
324 NOTREACHED(); 311 NOTREACHED();
325 return nil; 312 return nil;
326 } 313 }
327 314
328 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window { 315 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window {
329 DCHECK(_browserState); 316 DCHECK(_browserState);
330 DCHECK(window); 317 DCHECK(window);
331 if (!window.unclaimedSessions) 318 if (!window.unclaimedSessions)
332 return NO; 319 return NO;
333 size_t oldCount = self.count; 320 size_t oldCount = [_tabs count];
334 size_t index = oldCount; 321 size_t index = oldCount;
335 while (window.unclaimedSessions) { 322 while (window.unclaimedSessions) {
336 std::unique_ptr<web::WebStateImpl> webState = [window nextSession]; 323 std::unique_ptr<web::WebStateImpl> webState = [window nextSession];
337 DCHECK_EQ(webState->GetBrowserState(), _browserState); 324 DCHECK_EQ(webState->GetBrowserState(), _browserState);
338 Tab* tab = [self insertTabWithWebState:std::move(webState) atIndex:index++]; 325 Tab* tab = [self insertTabWithWebState:std::move(webState) atIndex:index++];
339 tab.webController.usePlaceholderOverlay = YES; 326 tab.webController.usePlaceholderOverlay = YES;
340 // Restore the CertificatePolicyCache. Note that after calling Pass() 327 // Restore the CertificatePolicyCache. Note that after calling Pass()
341 // |webState| is invalid, so we need to get the webstate from |tab|. 328 // |webState| is invalid, so we need to get the webstate from |tab|.
342 UpdateCertificatePolicyCacheFromWebState(tab.webStateImpl); 329 UpdateCertificatePolicyCacheFromWebState(tab.webStateImpl);
343 } 330 }
344 DCHECK(self.count > oldCount); 331 DCHECK([_tabs count] > oldCount);
345 // If any tab was restored, the saved selected tab must be selected. 332 // If any tab was restored, the saved selected tab must be selected.
346 if (self.count > oldCount) { 333 if ([_tabs count] > oldCount) {
347 NSUInteger selectedIndex = window.selectedIndex; 334 NSUInteger selectedIndex = window.selectedIndex;
348 if (selectedIndex == NSNotFound) 335 if (selectedIndex == NSNotFound)
349 selectedIndex = oldCount; 336 selectedIndex = oldCount;
350 else 337 else
351 selectedIndex += oldCount; 338 selectedIndex += oldCount;
352 DCHECK(selectedIndex < self.count); 339 DCHECK(selectedIndex < [_tabs count]);
353 Tab* newTab = [self tabAtIndex:selectedIndex]; 340 Tab* newTab = [self tabAtIndex:selectedIndex];
354 DCHECK(newTab); 341 DCHECK(newTab);
355 [self changeSelectedTabFrom:_currentTab to:newTab persistState:YES]; 342 [self changeSelectedTabFrom:_currentTab to:newTab persistState:YES];
356 343
357 // If there was only one tab and it was the new tab page, clobber it. 344 // If there was only one tab and it was the new tab page, clobber it.
358 if (oldCount == 1) { 345 if (oldCount == 1) {
359 Tab* tab = [self firstWebState]; 346 Tab* tab = [_tabs objectAtIndex:0];
360 if (tab.url == GURL(kChromeUINewTabURL)) { 347 if (tab.url == GURL(kChromeUINewTabURL)) {
361 [self closeTab:tab]; 348 [self closeTab:tab];
362 if (_tabUsageRecorder) { 349 if (_tabUsageRecorder)
363 _tabUsageRecorder->InitialRestoredTabs( 350 _tabUsageRecorder->InitialRestoredTabs(_currentTab, _tabs);
364 _currentTab,
365 GetTabsFromWebStateList(self, NSMakeRange(0, self.count)));
366 }
367 return YES; 351 return YES;
368 } 352 }
369 } 353 }
370 if (_tabUsageRecorder) { 354 if (_tabUsageRecorder) {
371 _tabUsageRecorder->InitialRestoredTabs( 355 _tabUsageRecorder->InitialRestoredTabs(
372 _currentTab, GetTabsFromWebStateList( 356 _currentTab,
373 self, NSMakeRange(oldCount, self.count - oldCount))); 357 [_tabs subarrayWithRange:NSMakeRange(oldCount,
358 [_tabs count] - oldCount)]);
374 } 359 }
375 } 360 }
376 return NO; 361 return NO;
377 } 362 }
378 363
379 - (void)saveSessionImmediately:(BOOL)immediately { 364 - (void)saveSessionImmediately:(BOOL)immediately {
380 // Do nothing if there are tabs in the model but no selected tab. This is 365 // Do nothing if there are tabs in the model but no selected tab. This is
381 // a transitional state. 366 // a transitional state.
382 if ((!_currentTab && self.count) || !_browserState) 367 if ((!_currentTab && [_tabs count]) || !_browserState)
383 return; 368 return;
384 [_sessionService saveWindow:self.windowForSavingSession 369 [_sessionService saveWindow:self.windowForSavingSession
385 forBrowserState:_browserState 370 forBrowserState:_browserState
386 immediately:immediately]; 371 immediately:immediately];
387 } 372 }
388 373
389 - (Tab*)tabAtIndex:(NSUInteger)index { 374 - (Tab*)tabAtIndex:(NSUInteger)index {
390 return [self webStateAtIndex:index]; 375 return [_tabs objectAtIndex:index];
391 } 376 }
392 377
393 - (NSUInteger)indexOfTab:(Tab*)tab { 378 - (NSUInteger)indexOfTab:(Tab*)tab {
394 return [self indexOfWebState:tab]; 379 return [_tabs indexOfObject:tab];
395 } 380 }
396 381
397 - (Tab*)tabWithWindowName:(NSString*)windowName { 382 - (Tab*)tabWithWindowName:(NSString*)windowName {
398 if (!windowName) 383 if (!windowName)
399 return nil; 384 return nil;
400 for (Tab* tab in self) { 385 for (Tab* tab in _tabs.get()) {
401 if ([windowName isEqualToString:tab.windowName]) { 386 if ([windowName isEqualToString:tab.windowName]) {
402 return tab; 387 return tab;
403 } 388 }
404 } 389 }
405 return nil; 390 return nil;
406 } 391 }
407 392
408 - (Tab*)nextTabWithOpener:(Tab*)tab afterTab:(Tab*)afterTab { 393 - (Tab*)nextTabWithOpener:(Tab*)tab afterTab:(Tab*)afterTab {
409 NSUInteger startIndex = NSNotFound; 394 NSUInteger startIndex = NSNotFound;
410 // Start looking after |afterTab|. If it's not found, start looking after 395 // Start looking after |afterTab|. If it's not found, start looking after
411 // |tab|. If it's not found either, bail. 396 // |tab|. If it's not found either, bail.
412 if (afterTab) 397 if (afterTab)
413 startIndex = [self indexOfTab:afterTab]; 398 startIndex = [self indexOfTab:afterTab];
414 if (startIndex == NSNotFound) 399 if (startIndex == NSNotFound)
415 startIndex = [self indexOfTab:tab]; 400 startIndex = [self indexOfTab:tab];
416 if (startIndex == NSNotFound) 401 if (startIndex == NSNotFound)
417 return nil; 402 return nil;
418 NSString* parentID = tab.tabId; 403 NSString* parentID = tab.tabId;
419 for (NSUInteger i = startIndex + 1; i < self.count; ++i) { 404 for (NSUInteger i = startIndex + 1; i < [_tabs count]; ++i) {
420 Tab* current = [self webStateAtIndex:i]; 405 Tab* current = [_tabs objectAtIndex:i];
421 DCHECK([current navigationManager]); 406 DCHECK([current navigationManager]);
422 CRWSessionController* sessionController = 407 CRWSessionController* sessionController =
423 [current navigationManager]->GetSessionController(); 408 [current navigationManager]->GetSessionController();
424 if ([sessionController.openerId isEqualToString:parentID]) 409 if ([sessionController.openerId isEqualToString:parentID])
425 return current; 410 return current;
426 } 411 }
427 return nil; 412 return nil;
428 } 413 }
429 414
430 - (Tab*)firstTabWithOpener:(Tab*)tab { 415 - (Tab*)firstTabWithOpener:(Tab*)tab {
431 if (!tab) 416 if (!tab)
432 return nil; 417 return nil;
433 NSUInteger stopIndex = [self indexOfTab:tab]; 418 NSUInteger stopIndex = [self indexOfTab:tab];
434 if (stopIndex == NSNotFound) 419 if (stopIndex == NSNotFound)
435 return nil; 420 return nil;
436 NSString* parentID = tab.tabId; 421 NSString* parentID = tab.tabId;
437 // Match the navigation index as well as the session id, to better match the 422 // Match the navigation index as well as the session id, to better match the
438 // state of the tab. I.e. two tabs are opened via a link from tab A, and then 423 // state of the tab. I.e. two tabs are opened via a link from tab A, and then
439 // a new url is loaded into tab A, and more tabs opened from that url, the 424 // a new url is loaded into tab A, and more tabs opened from that url, the
440 // latter two tabs should not be grouped with the former two. The navigation 425 // latter two tabs should not be grouped with the former two. The navigation
441 // index is the simplest way to detect navigation changes. 426 // index is the simplest way to detect navigation changes.
442 DCHECK([tab navigationManager]); 427 DCHECK([tab navigationManager]);
443 NSInteger parentNavIndex = [tab navigationManager]->GetCurrentItemIndex(); 428 NSInteger parentNavIndex = [tab navigationManager]->GetCurrentItemIndex();
444 for (NSUInteger i = 0; i < stopIndex; ++i) { 429 for (NSUInteger i = 0; i < stopIndex; ++i) {
445 Tab* tabToCheck = [self webStateAtIndex:i]; 430 Tab* tabToCheck = [_tabs objectAtIndex:i];
446 DCHECK([tabToCheck navigationManager]); 431 DCHECK([tabToCheck navigationManager]);
447 CRWSessionController* sessionController = 432 CRWSessionController* sessionController =
448 [tabToCheck navigationManager]->GetSessionController(); 433 [tabToCheck navigationManager]->GetSessionController();
449 if ([sessionController.openerId isEqualToString:parentID] && 434 if ([sessionController.openerId isEqualToString:parentID] &&
450 sessionController.openerNavigationIndex == parentNavIndex) { 435 sessionController.openerNavigationIndex == parentNavIndex) {
451 return tabToCheck; 436 return tabToCheck;
452 } 437 }
453 } 438 }
454 return nil; 439 return nil;
455 } 440 }
456 441
457 - (Tab*)lastTabWithOpener:(Tab*)tab { 442 - (Tab*)lastTabWithOpener:(Tab*)tab {
458 NSUInteger startIndex = [self indexOfTab:tab]; 443 NSUInteger startIndex = [self indexOfTab:tab];
459 if (startIndex == NSNotFound) 444 if (startIndex == NSNotFound)
460 return nil; 445 return nil;
461 // There is at least one tab in the model, because otherwise the above check 446 // There is at least one tab in the model, because otherwise the above check
462 // would have returned. 447 // would have returned.
463 NSString* parentID = tab.tabId; 448 NSString* parentID = tab.tabId;
464 DCHECK([tab navigationManager]); 449 DCHECK([tab navigationManager]);
465 NSInteger parentNavIndex = [tab navigationManager]->GetCurrentItemIndex(); 450 NSInteger parentNavIndex = [tab navigationManager]->GetCurrentItemIndex();
466 451
467 Tab* match = nil; 452 Tab* match = nil;
468 // Find the last tab in the first matching 'group'. A 'group' is a set of 453 // Find the last tab in the first matching 'group'. A 'group' is a set of
469 // tabs whose opener's id and opener's navigation index match. The navigation 454 // tabs whose opener's id and opener's navigation index match. The navigation
470 // index is used in addition to the session id to detect navigations changes 455 // index is used in addition to the session id to detect navigations changes
471 // within the same session. 456 // within the same session.
472 for (NSUInteger i = startIndex + 1; i < self.count; ++i) { 457 for (NSUInteger i = startIndex + 1; i < [_tabs count]; ++i) {
473 Tab* tabToCheck = [self webStateAtIndex:i]; 458 Tab* tabToCheck = [_tabs objectAtIndex:i];
474 DCHECK([tabToCheck navigationManager]); 459 DCHECK([tabToCheck navigationManager]);
475 CRWSessionController* sessionController = 460 CRWSessionController* sessionController =
476 [tabToCheck navigationManager]->GetSessionController(); 461 [tabToCheck navigationManager]->GetSessionController();
477 if ([sessionController.openerId isEqualToString:parentID] && 462 if ([sessionController.openerId isEqualToString:parentID] &&
478 sessionController.openerNavigationIndex == parentNavIndex) { 463 sessionController.openerNavigationIndex == parentNavIndex) {
479 match = tabToCheck; 464 match = tabToCheck;
480 } else if (match) { 465 } else if (match) {
481 break; 466 break;
482 } 467 }
483 } 468 }
484 return match; 469 return match;
485 } 470 }
486 471
487 - (Tab*)openerOfTab:(Tab*)tab { 472 - (Tab*)openerOfTab:(Tab*)tab {
488 if (![tab navigationManager]) 473 if (![tab navigationManager])
489 return nil; 474 return nil;
490 NSString* openerId = [tab navigationManager]->GetSessionController().openerId; 475 NSString* openerId = [tab navigationManager]->GetSessionController().openerId;
491 if (!openerId.length) // Short-circuit if opener is empty. 476 if (!openerId.length) // Short-circuit if opener is empty.
492 return nil; 477 return nil;
493 for (Tab* iteratedTab in self) { 478 for (Tab* iteratedTab in _tabs.get()) {
494 if ([iteratedTab.tabId isEqualToString:openerId]) 479 if ([iteratedTab.tabId isEqualToString:openerId])
495 return iteratedTab; 480 return iteratedTab;
496 } 481 }
497 return nil; 482 return nil;
498 } 483 }
499 484
500 - (Tab*)insertOrUpdateTabWithURL:(const GURL&)URL 485 - (Tab*)insertOrUpdateTabWithURL:(const GURL&)URL
501 referrer:(const web::Referrer&)referrer 486 referrer:(const web::Referrer&)referrer
502 transition:(ui::PageTransition)transition 487 transition:(ui::PageTransition)transition
503 windowName:(NSString*)windowName 488 windowName:(NSString*)windowName
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 DCHECK_EQ(webState->GetBrowserState(), _browserState); 561 DCHECK_EQ(webState->GetBrowserState(), _browserState);
577 base::scoped_nsobject<Tab> tab( 562 base::scoped_nsobject<Tab> tab(
578 [[Tab alloc] initWithWebState:std::move(webState) model:self]); 563 [[Tab alloc] initWithWebState:std::move(webState) model:self]);
579 [tab webController].webUsageEnabled = webUsageEnabled_; 564 [tab webController].webUsageEnabled = webUsageEnabled_;
580 [self insertTab:tab atIndex:index]; 565 [self insertTab:tab atIndex:index];
581 return tab; 566 return tab;
582 } 567 }
583 568
584 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index { 569 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index {
585 DCHECK(tab); 570 DCHECK(tab);
586 DCHECK(index <= self.count); 571 DCHECK(index <= [_tabs count]);
587 [tab fetchFavicon]; 572 [tab fetchFavicon];
588 [self insertWebState:tab atIndex:index]; 573 [_tabs insertObject:tab atIndex:index];
589 574
590 [_observers tabModel:self didInsertTab:tab atIndex:index inForeground:NO]; 575 [_observers tabModel:self didInsertTab:tab atIndex:index inForeground:NO];
591 [_observers tabModelDidChangeTabCount:self]; 576 [_observers tabModelDidChangeTabCount:self];
592 577
593 base::RecordAction(base::UserMetricsAction("MobileNewTabOpened")); 578 base::RecordAction(base::UserMetricsAction("MobileNewTabOpened"));
594 // Persist the session due to a new tab being inserted. If this is a 579 // Persist the session due to a new tab being inserted. If this is a
595 // background tab (will not become active), saving now will capture the 580 // background tab (will not become active), saving now will capture the
596 // state properly. If it does eventually become active, another save will 581 // state properly. If it does eventually become active, another save will
597 // be triggered to properly capture the end result. 582 // be triggered to properly capture the end result.
598 [self saveSessionImmediately:NO]; 583 [self saveSessionImmediately:NO];
599 ++_newTabCount; 584 ++_newTabCount;
600 } 585 }
601 586
602 - (void)moveTab:(Tab*)tab toIndex:(NSUInteger)toIndex { 587 - (void)moveTab:(Tab*)tab toIndex:(NSUInteger)toIndex {
603 NSUInteger fromIndex = [self indexOfTab:tab]; 588 NSUInteger fromIndex = [self indexOfTab:tab];
604 DCHECK_NE(NSNotFound, static_cast<NSInteger>(fromIndex)); 589 DCHECK_NE(NSNotFound, static_cast<NSInteger>(fromIndex));
605 DCHECK_LT(toIndex, self.count); 590 DCHECK_LT(toIndex, self.count);
606 if (fromIndex == NSNotFound || toIndex >= self.count || 591 if (fromIndex == NSNotFound || toIndex >= self.count ||
607 fromIndex == toIndex) { 592 fromIndex == toIndex) {
608 return; 593 return;
609 } 594 }
610 595
611 base::scoped_nsobject<Tab> tabSaver([tab retain]); 596 base::scoped_nsobject<Tab> tabSaver([tab retain]);
612 [self removeWebState:tab]; 597 [_tabs removeObject:tab];
613 [self insertWebState:tab atIndex:toIndex]; 598 [_tabs insertObject:tab atIndex:toIndex];
614 599
615 [_observers tabModel:self didMoveTab:tab fromIndex:fromIndex toIndex:toIndex]; 600 [_observers tabModel:self didMoveTab:tab fromIndex:fromIndex toIndex:toIndex];
616 } 601 }
617 602
618 - (void)replaceTab:(Tab*)oldTab 603 - (void)replaceTab:(Tab*)oldTab
619 withTab:(Tab*)newTab 604 withTab:(Tab*)newTab
620 keepOldTabOpen:(BOOL)keepOldTabOpen { 605 keepOldTabOpen:(BOOL)keepOldTabOpen {
621 NSUInteger index = [self indexOfTab:oldTab]; 606 NSUInteger index = [self indexOfTab:oldTab];
622 DCHECK_NE(NSNotFound, static_cast<NSInteger>(index)); 607 DCHECK_NE(NSNotFound, static_cast<NSInteger>(index));
623 608
624 base::scoped_nsobject<Tab> tabSaver([oldTab retain]); 609 base::scoped_nsobject<Tab> tabSaver([oldTab retain]);
625 [newTab fetchFavicon]; 610 [newTab fetchFavicon];
626 [self replaceWebStateAtIndex:index withWebState:newTab]; 611 [_tabs replaceObjectAtIndex:index withObject:newTab];
627 [newTab setParentTabModel:self]; 612 [newTab setParentTabModel:self];
628 613
629 [_observers tabModel:self didReplaceTab:oldTab withTab:newTab atIndex:index]; 614 [_observers tabModel:self didReplaceTab:oldTab withTab:newTab atIndex:index];
630 615
631 if (self.currentTab == oldTab) 616 if (self.currentTab == oldTab)
632 [self changeSelectedTabFrom:nil to:newTab persistState:NO]; 617 [self changeSelectedTabFrom:nil to:newTab persistState:NO];
633 618
634 [oldTab setParentTabModel:nil]; 619 [oldTab setParentTabModel:nil];
635 if (!keepOldTabOpen) 620 if (!keepOldTabOpen)
636 [oldTab close]; 621 [oldTab close];
637 622
638 // Record a tab clobber, since swapping tabs bypasses the tab code that would 623 // Record a tab clobber, since swapping tabs bypasses the tab code that would
639 // normally log clobbers. 624 // normally log clobbers.
640 base::RecordAction(base::UserMetricsAction("MobileTabClobbered")); 625 base::RecordAction(base::UserMetricsAction("MobileTabClobbered"));
641 } 626 }
642 627
643 - (void)closeTabAtIndex:(NSUInteger)index { 628 - (void)closeTabAtIndex:(NSUInteger)index {
644 DCHECK(index < self.count); 629 DCHECK(index < [_tabs count]);
645 [self closeTab:[self webStateAtIndex:index]]; 630 [self closeTab:[_tabs objectAtIndex:index]];
646 } 631 }
647 632
648 - (void)closeTab:(Tab*)tab { 633 - (void)closeTab:(Tab*)tab {
649 // Ensure the tab stays alive long enough for us to send out the 634 // Ensure the tab stays alive long enough for us to send out the
650 // notice of its destruction to the delegate. 635 // notice of its destruction to the delegate.
651 [_observers tabModel:self willRemoveTab:tab]; 636 [_observers tabModel:self willRemoveTab:tab];
652 [tab close]; // Note it is not safe to access the tab after 'close'. 637 [tab close]; // Note it is not safe to access the tab after 'close'.
653 } 638 }
654 639
655 - (void)closeAllTabs { 640 - (void)closeAllTabs {
656 // If this changes, _closedTabCount metrics need to be adjusted. 641 // If this changes, _closedTabCount metrics need to be adjusted.
657 for (NSInteger i = self.count - 1; i >= 0; --i) 642 for (NSInteger i = self.count - 1; i >= 0; --i)
658 [self closeTabAtIndex:i]; 643 [self closeTabAtIndex:i];
659 [[NSNotificationCenter defaultCenter] 644 [[NSNotificationCenter defaultCenter]
660 postNotificationName:kTabModelAllTabsDidCloseNotification 645 postNotificationName:kTabModelAllTabsDidCloseNotification
661 object:self]; 646 object:self];
662 } 647 }
663 648
664 - (void)haltAllTabs { 649 - (void)haltAllTabs {
665 for (Tab* tab in self) { 650 for (Tab* tab in _tabs.get()) {
666 [tab terminateNetworkActivity]; 651 [tab terminateNetworkActivity];
667 } 652 }
668 } 653 }
669 654
670 - (void)notifyTabChanged:(Tab*)tab { 655 - (void)notifyTabChanged:(Tab*)tab {
671 [_observers tabModel:self didChangeTab:tab]; 656 [_observers tabModel:self didChangeTab:tab];
672 } 657 }
673 658
674 - (void)addObserver:(id<TabModelObserver>)observer { 659 - (void)addObserver:(id<TabModelObserver>)observer {
675 [_observers addObserver:observer]; 660 [_observers addObserver:observer];
(...skipping 16 matching lines...) Expand all
692 200, 50); 677 200, 50);
693 UMA_HISTOGRAM_CUSTOM_COUNTS("Session.NewTabCounts", _newTabCount, 1, 200, 50); 678 UMA_HISTOGRAM_CUSTOM_COUNTS("Session.NewTabCounts", _newTabCount, 1, 200, 50);
694 } 679 }
695 680
696 - (void)notifyTabSnapshotChanged:(Tab*)tab withImage:(UIImage*)image { 681 - (void)notifyTabSnapshotChanged:(Tab*)tab withImage:(UIImage*)image {
697 DCHECK([NSThread isMainThread]); 682 DCHECK([NSThread isMainThread]);
698 [_observers tabModel:self didChangeTabSnapshot:tab withImage:image]; 683 [_observers tabModel:self didChangeTabSnapshot:tab withImage:image];
699 } 684 }
700 685
701 - (void)resetAllWebViews { 686 - (void)resetAllWebViews {
702 for (Tab* tab in self) { 687 for (Tab* tab in _tabs.get()) {
703 [tab.webController reinitializeWebViewAndReload:(tab == _currentTab)]; 688 [tab.webController reinitializeWebViewAndReload:(tab == _currentTab)];
704 } 689 }
705 } 690 }
706 691
707 - (void)setWebUsageEnabled:(BOOL)webUsageEnabled { 692 - (void)setWebUsageEnabled:(BOOL)webUsageEnabled {
708 if (webUsageEnabled_ == webUsageEnabled) 693 if (webUsageEnabled_ == webUsageEnabled)
709 return; 694 return;
710 webUsageEnabled_ = webUsageEnabled; 695 webUsageEnabled_ = webUsageEnabled;
711 for (Tab* tab in self) { 696 for (Tab* tab in _tabs.get()) {
712 tab.webUsageEnabled = webUsageEnabled; 697 tab.webUsageEnabled = webUsageEnabled;
713 } 698 }
714 } 699 }
715 700
716 - (void)setPrimary:(BOOL)primary { 701 - (void)setPrimary:(BOOL)primary {
717 if (_tabUsageRecorder) 702 if (_tabUsageRecorder)
718 _tabUsageRecorder->RecordPrimaryTabModelChange(primary, _currentTab); 703 _tabUsageRecorder->RecordPrimaryTabModelChange(primary, _currentTab);
719 } 704 }
720 705
721 - (NSSet*)currentlyReferencedExternalFiles { 706 - (NSSet*)currentlyReferencedExternalFiles {
722 NSMutableSet* referencedFiles = [NSMutableSet set]; 707 NSMutableSet* referencedFiles = [NSMutableSet set];
723 if (!_browserState) 708 if (!_browserState)
724 return referencedFiles; 709 return referencedFiles;
725 // Check the currently open tabs for external files. 710 // Check the currently open tabs for external files.
726 for (Tab* tab in self) { 711 for (Tab* tab in _tabs.get()) {
727 if (UrlIsExternalFileReference(tab.url)) { 712 if (UrlIsExternalFileReference(tab.url)) {
728 NSString* fileName = base::SysUTF8ToNSString(tab.url.ExtractFileName()); 713 NSString* fileName = base::SysUTF8ToNSString(tab.url.ExtractFileName());
729 [referencedFiles addObject:fileName]; 714 [referencedFiles addObject:fileName];
730 } 715 }
731 } 716 }
732 // Do the same for the recently closed tabs. 717 // Do the same for the recently closed tabs.
733 sessions::TabRestoreService* restoreService = 718 sessions::TabRestoreService* restoreService =
734 IOSChromeTabRestoreServiceFactory::GetForBrowserState(_browserState); 719 IOSChromeTabRestoreServiceFactory::GetForBrowserState(_browserState);
735 DCHECK(restoreService); 720 DCHECK(restoreService);
736 for (const auto& entry : restoreService->entries()) { 721 for (const auto& entry : restoreService->entries()) {
(...skipping 16 matching lines...) Expand all
753 [[NSNotificationCenter defaultCenter] removeObserver:self]; 738 [[NSNotificationCenter defaultCenter] removeObserver:self];
754 if (_browserState) { 739 if (_browserState) {
755 UnregisterTabModelFromChromeBrowserState(_browserState, self); 740 UnregisterTabModelFromChromeBrowserState(_browserState, self);
756 } 741 }
757 _browserState = nullptr; 742 _browserState = nullptr;
758 } 743 }
759 744
760 // Called when a tab is closing, but before its CRWWebController is destroyed. 745 // Called when a tab is closing, but before its CRWWebController is destroyed.
761 // Equivalent to DetachTabContentsAt() in Chrome's TabStripModel. 746 // Equivalent to DetachTabContentsAt() in Chrome's TabStripModel.
762 - (void)didCloseTab:(Tab*)closedTab { 747 - (void)didCloseTab:(Tab*)closedTab {
763 NSUInteger closedTabIndex = [self indexOfWebState:closedTab]; 748 NSUInteger closedTabIndex = [_tabs indexOfObject:closedTab];
764 DCHECK(closedTab); 749 DCHECK(closedTab);
765 DCHECK(closedTabIndex != NSNotFound); 750 DCHECK(closedTabIndex != NSNotFound);
766 // Let the sessions::TabRestoreService know about that new tab. 751 // Let the sessions::TabRestoreService know about that new tab.
767 sessions::TabRestoreService* restoreService = 752 sessions::TabRestoreService* restoreService =
768 _browserState 753 _browserState
769 ? IOSChromeTabRestoreServiceFactory::GetForBrowserState(_browserState) 754 ? IOSChromeTabRestoreServiceFactory::GetForBrowserState(_browserState)
770 : nullptr; 755 : nullptr;
771 web::NavigationManagerImpl* navigationManager = [closedTab navigationManager]; 756 web::NavigationManagerImpl* navigationManager = [closedTab navigationManager];
772 DCHECK(navigationManager); 757 DCHECK(navigationManager);
773 int itemCount = navigationManager->GetItemCount(); 758 int itemCount = navigationManager->GetItemCount();
774 if (restoreService && (![self isNTPTab:closedTab] || itemCount > 1)) { 759 if (restoreService && (![self isNTPTab:closedTab] || itemCount > 1)) {
775 restoreService->CreateHistoricalTab( 760 restoreService->CreateHistoricalTab(
776 sessions::IOSLiveTab::GetForWebState(closedTab.webStateImpl), 761 sessions::IOSLiveTab::GetForWebState(closedTab.webStateImpl),
777 static_cast<int>(closedTabIndex)); 762 static_cast<int>(closedTabIndex));
778 } 763 }
779 // This needs to be called before the tab is removed from the list. 764 // This needs to be called before the tab is removed from the list.
780 Tab* newSelection = 765 Tab* newSelection =
781 [_orderController determineNewSelectedTabFromRemovedTab:closedTab]; 766 [_orderController determineNewSelectedTabFromRemovedTab:closedTab];
782 base::scoped_nsobject<Tab> kungFuDeathGrip([closedTab retain]); 767 base::scoped_nsobject<Tab> kungFuDeathGrip([closedTab retain]);
783 [self removeWebState:closedTab]; 768 [_tabs removeObject:closedTab];
784 769
785 // If closing the current tab, clear |_currentTab| before sending any 770 // If closing the current tab, clear |_currentTab| before sending any
786 // notification. This avoids various parts of the code getting confused 771 // notification. This avoids various parts of the code getting confused
787 // when the current tab isn't in the tab model. 772 // when the current tab isn't in the tab model.
788 Tab* savedCurrentTab = _currentTab; 773 Tab* savedCurrentTab = _currentTab;
789 if (closedTab == _currentTab) 774 if (closedTab == _currentTab)
790 _currentTab.reset(nil); 775 _currentTab.reset(nil);
791 776
792 [_observers tabModel:self didRemoveTab:closedTab atIndex:closedTabIndex]; 777 [_observers tabModel:self didRemoveTab:closedTab atIndex:closedTabIndex];
793 [_observers tabModelDidChangeTabCount:self]; 778 [_observers tabModelDidChangeTabCount:self];
(...skipping 30 matching lines...) Expand all
824 if (previousURL.ReplaceComponents(replacements) == 809 if (previousURL.ReplaceComponents(replacements) ==
825 currentURL.ReplaceComponents(replacements)) { 810 currentURL.ReplaceComponents(replacements)) {
826 return; 811 return;
827 } 812 }
828 } 813 }
829 814
830 int tabCount = static_cast<int>(self.count); 815 int tabCount = static_cast<int>(self.count);
831 UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountPerLoad", tabCount, 1, 200, 50); 816 UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountPerLoad", tabCount, 1, 200, 50);
832 } 817 }
833 818
819 #pragma mark - NSFastEnumeration
820
821 - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState*)state
822 objects:(id*)objects
823 count:(NSUInteger)count {
824 return [_tabs countByEnumeratingWithState:state objects:objects count:count];
825 }
826
834 #pragma mark - TabUsageRecorderDelegate 827 #pragma mark - TabUsageRecorderDelegate
835 828
836 - (NSUInteger)liveTabsCount { 829 - (NSUInteger)liveTabsCount {
837 NSUInteger count = 0; 830 NSUInteger count = 0;
838 for (Tab* tab in self) { 831 NSArray* tabs = _tabs.get();
832 for (Tab* tab in tabs) {
839 if ([tab.webController isViewAlive]) 833 if ([tab.webController isViewAlive])
840 count++; 834 count++;
841 } 835 }
842 return count; 836 return count;
843 } 837 }
844 838
845 #pragma mark - Private methods 839 #pragma mark - Private methods
846 840
847 - (SessionWindowIOS*)windowForSavingSession { 841 - (SessionWindowIOS*)windowForSavingSession {
848 // Background tabs will already have their state preserved, but not the 842 // Background tabs will already have their state preserved, but not the
849 // fg tab. Do it now. 843 // fg tab. Do it now.
850 [_currentTab recordStateInHistory]; 844 [_currentTab recordStateInHistory];
851 845
852 // Build the array of sessions. Copy the session objects as the saving will 846 // Build the array of sessions. Copy the session objects as the saving will
853 // be done on a separate thread. 847 // be done on a separate thread.
854 // TODO(crbug.com/661986): This could get expensive especially since this 848 // TODO(crbug.com/661986): This could get expensive especially since this
855 // window may never be saved (if another call comes in before the delay). 849 // window may never be saved (if another call comes in before the delay).
856 SessionWindowIOS* window = [[[SessionWindowIOS alloc] init] autorelease]; 850 SessionWindowIOS* window = [[[SessionWindowIOS alloc] init] autorelease];
857 for (Tab* tab in self) { 851 for (Tab* tab in _tabs.get()) {
858 DCHECK(tab.webStateImpl); 852 DCHECK(tab.webStateImpl);
859 std::unique_ptr<web::WebStateImpl> webStateCopy( 853 std::unique_ptr<web::WebStateImpl> webStateCopy(
860 tab.webStateImpl->CopyForSessionWindow()); 854 tab.webStateImpl->CopyForSessionWindow());
861 [window addSession:std::move(webStateCopy)]; 855 [window addSession:std::move(webStateCopy)];
862 } 856 }
863 window.selectedIndex = [self indexOfTab:_currentTab]; 857 window.selectedIndex = [self indexOfTab:_currentTab];
864 return window; 858 return window;
865 } 859 }
866 860
867 - (BOOL)isNTPTab:(Tab*)tab { 861 - (BOOL)isNTPTab:(Tab*)tab {
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 - (void)applicationDidEnterBackground:(NSNotification*)notify { 1006 - (void)applicationDidEnterBackground:(NSNotification*)notify {
1013 if (!_browserState) 1007 if (!_browserState)
1014 return; 1008 return;
1015 // Evict all the certificate policies except for the current entries of the 1009 // Evict all the certificate policies except for the current entries of the
1016 // active sessions. 1010 // active sessions.
1017 scoped_refptr<web::CertificatePolicyCache> policy_cache = 1011 scoped_refptr<web::CertificatePolicyCache> policy_cache =
1018 web::BrowserState::GetCertificatePolicyCache(_browserState); 1012 web::BrowserState::GetCertificatePolicyCache(_browserState);
1019 DCHECK(policy_cache); 1013 DCHECK(policy_cache);
1020 web::WebThread::PostTask( 1014 web::WebThread::PostTask(
1021 web::WebThread::IO, FROM_HERE, 1015 web::WebThread::IO, FROM_HERE,
1022 base::Bind(&CleanCertificatePolicyCache, policy_cache, self)); 1016 base::Bind(&CleanCertificatePolicyCache, policy_cache, _tabs));
1023 1017
1024 if (_tabUsageRecorder) 1018 if (_tabUsageRecorder)
1025 _tabUsageRecorder->AppDidEnterBackground(); 1019 _tabUsageRecorder->AppDidEnterBackground();
1026 1020
1027 // Normally, the session is saved after some timer expires but since the app 1021 // Normally, the session is saved after some timer expires but since the app
1028 // is about to enter the background send YES to save the session immediately. 1022 // is about to enter the background send YES to save the session immediately.
1029 [self saveSessionImmediately:YES]; 1023 [self saveSessionImmediately:YES];
1030 1024
1031 // Write out a grey version of the current website to disk. 1025 // Write out a grey version of the current website to disk.
1032 if (webUsageEnabled_ && _currentTab) { 1026 if (webUsageEnabled_ && _currentTab) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 web::NavigationManager::WebLoadParams params(URL); 1065 web::NavigationManager::WebLoadParams params(URL);
1072 params.referrer = referrer; 1066 params.referrer = referrer;
1073 params.transition_type = ui::PAGE_TRANSITION_TYPED; 1067 params.transition_type = ui::PAGE_TRANSITION_TYPED;
1074 [[tab webController] loadWithParams:params]; 1068 [[tab webController] loadWithParams:params];
1075 [tab webController].webUsageEnabled = webUsageEnabled_; 1069 [tab webController].webUsageEnabled = webUsageEnabled_;
1076 [self insertTab:tab atIndex:index]; 1070 [self insertTab:tab atIndex:index];
1077 return tab; 1071 return tab;
1078 } 1072 }
1079 1073
1080 @end 1074 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/tabs/tab_model.h ('k') | ios/chrome/browser/tabs/tab_model_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698