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

Powered by Google App Engine
This is Rietveld 408576698