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

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

Issue 2683393003: Refactor TabModel to use WebStateList to store WebStates. (Closed)
Patch Set: Rebase to get dependent CL fix of "gn check". 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/BUILD.gn ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ios/chrome/browser/tabs/tab_model.h" 5 #import "ios/chrome/browser/tabs/tab_model.h"
6 6
7 #include <utility> 7 #include <utility>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 10 matching lines...) Expand all
21 #include "components/sessions/ios/ios_live_tab.h" 21 #include "components/sessions/ios/ios_live_tab.h"
22 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" 22 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
23 #include "ios/chrome/browser/chrome_url_constants.h" 23 #include "ios/chrome/browser/chrome_url_constants.h"
24 #import "ios/chrome/browser/chrome_url_util.h" 24 #import "ios/chrome/browser/chrome_url_util.h"
25 #import "ios/chrome/browser/metrics/tab_usage_recorder.h" 25 #import "ios/chrome/browser/metrics/tab_usage_recorder.h"
26 #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h" 26 #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h"
27 #import "ios/chrome/browser/sessions/session_service.h" 27 #import "ios/chrome/browser/sessions/session_service.h"
28 #import "ios/chrome/browser/sessions/session_window.h" 28 #import "ios/chrome/browser/sessions/session_window.h"
29 #import "ios/chrome/browser/snapshots/snapshot_cache.h" 29 #import "ios/chrome/browser/snapshots/snapshot_cache.h"
30 #include "ios/chrome/browser/tab_parenting_global_observer.h" 30 #include "ios/chrome/browser/tab_parenting_global_observer.h"
31 #import "ios/chrome/browser/tabs/legacy_tab_helper.h"
31 #import "ios/chrome/browser/tabs/tab.h" 32 #import "ios/chrome/browser/tabs/tab.h"
32 #import "ios/chrome/browser/tabs/tab_model_list.h" 33 #import "ios/chrome/browser/tabs/tab_model_list.h"
33 #import "ios/chrome/browser/tabs/tab_model_observers.h" 34 #import "ios/chrome/browser/tabs/tab_model_observers.h"
34 #import "ios/chrome/browser/tabs/tab_model_order_controller.h" 35 #import "ios/chrome/browser/tabs/tab_model_order_controller.h"
35 #import "ios/chrome/browser/tabs/tab_model_synced_window_delegate.h" 36 #import "ios/chrome/browser/tabs/tab_model_synced_window_delegate.h"
36 #import "ios/chrome/browser/xcallback_parameters.h" 37 #import "ios/chrome/browser/xcallback_parameters.h"
38 #import "ios/shared/chrome/browser/tabs/web_state_list.h"
39 #import "ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper.h "
40 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h"
37 #import "ios/web/navigation/crw_session_certificate_policy_manager.h" 41 #import "ios/web/navigation/crw_session_certificate_policy_manager.h"
38 #import "ios/web/navigation/crw_session_controller.h" 42 #import "ios/web/navigation/crw_session_controller.h"
39 #include "ios/web/public/browser_state.h" 43 #include "ios/web/public/browser_state.h"
40 #include "ios/web/public/certificate_policy_cache.h" 44 #include "ios/web/public/certificate_policy_cache.h"
41 #include "ios/web/public/navigation_item.h" 45 #include "ios/web/public/navigation_item.h"
42 #import "ios/web/public/navigation_manager.h" 46 #import "ios/web/public/navigation_manager.h"
43 #include "ios/web/public/web_thread.h" 47 #include "ios/web/public/web_thread.h"
44 #import "ios/web/web_state/ui/crw_web_controller.h" 48 #import "ios/web/web_state/ui/crw_web_controller.h"
45 #import "ios/web/web_state/web_state_impl.h" 49 #import "ios/web/web_state/web_state_impl.h"
46 #include "url/gurl.h" 50 #include "url/gurl.h"
(...skipping 25 matching lines...) Expand all
72 DCHECK_CURRENTLY_ON(web::WebThread::UI); 76 DCHECK_CURRENTLY_ON(web::WebThread::UI);
73 // TODO(crbug.com/454984): Remove CRWSessionController usage once certificate 77 // TODO(crbug.com/454984): Remove CRWSessionController usage once certificate
74 // policy manager is moved to NavigationManager. 78 // policy manager is moved to NavigationManager.
75 CRWSessionController* controller = static_cast<web::WebStateImpl*>(web_state) 79 CRWSessionController* controller = static_cast<web::WebStateImpl*>(web_state)
76 ->GetNavigationManagerImpl() 80 ->GetNavigationManagerImpl()
77 .GetSessionController(); 81 .GetSessionController();
78 [[controller sessionCertificatePolicyManager] 82 [[controller sessionCertificatePolicyManager]
79 updateCertificatePolicyCache:policy_cache]; 83 updateCertificatePolicyCache:policy_cache];
80 } 84 }
81 85
82 // Populates the certificate policy cache based on the WebStates of |tab_model|. 86 // Populates the certificate policy cache based on the WebStates of
87 // |web_state_list|.
83 void RestoreCertificatePolicyCacheFromModel( 88 void RestoreCertificatePolicyCacheFromModel(
84 const scoped_refptr<web::CertificatePolicyCache>& policy_cache, 89 const scoped_refptr<web::CertificatePolicyCache>& policy_cache,
85 TabModel* tab_model) { 90 WebStateList* web_state_list) {
86 DCHECK_CURRENTLY_ON(web::WebThread::UI); 91 DCHECK_CURRENTLY_ON(web::WebThread::UI);
87 for (Tab* tab in tab_model) 92 for (size_t index = 0; index < web_state_list->count(); ++index) {
88 UpdateCertificatePolicyCacheFromWebState(policy_cache, tab.webState); 93 UpdateCertificatePolicyCacheFromWebState(
94 policy_cache, web_state_list->GetWebStateAt(index));
95 }
89 } 96 }
90 97
91 // Scrubs the certificate policy cache of all certificates policies except 98 // Scrubs the certificate policy cache of all certificates policies except
92 // those for the current entries in |tab_model|. 99 // those for the current entries in |web_state_list|.
93 void CleanCertificatePolicyCache( 100 void CleanCertificatePolicyCache(
94 base::CancelableTaskTracker* task_tracker, 101 base::CancelableTaskTracker* task_tracker,
95 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 102 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
96 const scoped_refptr<web::CertificatePolicyCache>& policy_cache, 103 const scoped_refptr<web::CertificatePolicyCache>& policy_cache,
97 TabModel* tab_model) { 104 WebStateList* web_state_list) {
98 DCHECK(tab_model);
99 DCHECK(policy_cache); 105 DCHECK(policy_cache);
106 DCHECK(web_state_list);
100 DCHECK_CURRENTLY_ON(web::WebThread::UI); 107 DCHECK_CURRENTLY_ON(web::WebThread::UI);
101 task_tracker->PostTaskAndReply( 108 task_tracker->PostTaskAndReply(
102 task_runner.get(), FROM_HERE, 109 task_runner.get(), FROM_HERE,
103 base::Bind(&web::CertificatePolicyCache::ClearCertificatePolicies, 110 base::Bind(&web::CertificatePolicyCache::ClearCertificatePolicies,
104 policy_cache), 111 policy_cache),
105 base::Bind(&RestoreCertificatePolicyCacheFromModel, policy_cache, 112 base::Bind(&RestoreCertificatePolicyCacheFromModel, policy_cache,
106 base::Unretained(tab_model))); 113 base::Unretained(web_state_list)));
107 } 114 }
108 115
109 } // anonymous namespace 116 } // anonymous namespace
110 117
111 @interface TabModel ()<TabUsageRecorderDelegate> { 118 @interface TabModel ()<TabUsageRecorderDelegate, WebStateProxyFactory> {
112 // Array of |Tab| objects. 119 // Underlying shared model implementation.
113 base::scoped_nsobject<NSMutableArray> _tabs; 120 WebStateList _webStateList;
121
122 // Helper providing NSFastEnumeration implementation over the WebStateList.
123 base::scoped_nsobject<WebStateListFastEnumerationHelper>
124 _fastEnumerationHelper;
125
126 // Used to keep the Tabs alive while the corresponding WebStates are stored
127 // in the WebStateList (as Tabs currently owns their WebState). Remove once
rohitrao (ping after 24h) 2017/02/14 14:37:12 "own"
sdefresne 2017/02/14 16:45:46 Done.
128 // WebState owns the associated Tab.
129 base::scoped_nsobject<NSMutableSet<Tab*>> _tabs;
rohitrao (ping after 24h) 2017/02/14 14:37:12 Another naming option is to call this something li
sdefresne 2017/02/14 16:45:46 Done.
130
114 // Maintains policy for where new tabs go and the selection when a tab 131 // Maintains policy for where new tabs go and the selection when a tab
115 // is removed. 132 // is removed.
116 base::scoped_nsobject<TabModelOrderController> _orderController; 133 base::scoped_nsobject<TabModelOrderController> _orderController;
117 // The delegate for sync. 134 // The delegate for sync.
118 std::unique_ptr<TabModelSyncedWindowDelegate> _syncedWindowDelegate; 135 std::unique_ptr<TabModelSyncedWindowDelegate> _syncedWindowDelegate;
119 // Currently selected tab. May be nil. 136 // Currently selected tab. May be nil.
120 base::WeakNSObject<Tab> _currentTab; 137 base::WeakNSObject<Tab> _currentTab;
121 138
122 // Counters for metrics. 139 // Counters for metrics.
123 int _openedTabCount; 140 int _openedTabCount;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 [super dealloc]; 224 [super dealloc];
208 } 225 }
209 226
210 #pragma mark - Public methods 227 #pragma mark - Public methods
211 228
212 - (Tab*)currentTab { 229 - (Tab*)currentTab {
213 return _currentTab.get(); 230 return _currentTab.get();
214 } 231 }
215 232
216 - (void)setCurrentTab:(Tab*)newTab { 233 - (void)setCurrentTab:(Tab*)newTab {
217 DCHECK([_tabs containsObject:newTab]); 234 DCHECK_NE([self indexOfTab:newTab], static_cast<NSUInteger>(NSNotFound));
218 if (_currentTab != newTab) { 235 if (_currentTab != newTab) {
219 base::RecordAction(base::UserMetricsAction("MobileTabSwitched")); 236 base::RecordAction(base::UserMetricsAction("MobileTabSwitched"));
220 [self updateSnapshotCache:newTab]; 237 [self updateSnapshotCache:newTab];
221 } 238 }
222 if (_tabUsageRecorder) { 239 if (_tabUsageRecorder) {
223 _tabUsageRecorder->RecordTabSwitched(_currentTab, newTab); 240 _tabUsageRecorder->RecordTabSwitched(_currentTab, newTab);
224 } 241 }
225 [self changeSelectedTabFrom:_currentTab to:newTab persistState:YES]; 242 [self changeSelectedTabFrom:_currentTab to:newTab persistState:YES];
226 } 243 }
227 244
228 - (TabModelSyncedWindowDelegate*)syncedWindowDelegate { 245 - (TabModelSyncedWindowDelegate*)syncedWindowDelegate {
229 return _syncedWindowDelegate.get(); 246 return _syncedWindowDelegate.get();
230 } 247 }
231 248
232 - (TabUsageRecorder*)tabUsageRecorder { 249 - (TabUsageRecorder*)tabUsageRecorder {
233 return _tabUsageRecorder.get(); 250 return _tabUsageRecorder.get();
234 } 251 }
235 252
236 - (BOOL)isOffTheRecord { 253 - (BOOL)isOffTheRecord {
237 return _browserState && _browserState->IsOffTheRecord(); 254 return _browserState && _browserState->IsOffTheRecord();
238 } 255 }
239 256
240 - (BOOL)isEmpty { 257 - (BOOL)isEmpty {
241 return self.count == 0; 258 return _webStateList.empty();
242 } 259 }
243 260
244 - (NSUInteger)count { 261 - (NSUInteger)count {
245 return [_tabs count]; 262 return _webStateList.count();
246 } 263 }
247 264
248 - (instancetype)initWithSessionWindow:(SessionWindowIOS*)window 265 - (instancetype)initWithSessionWindow:(SessionWindowIOS*)window
249 sessionService:(SessionServiceIOS*)service 266 sessionService:(SessionServiceIOS*)service
250 browserState:(ios::ChromeBrowserState*)browserState { 267 browserState:(ios::ChromeBrowserState*)browserState {
251 if ((self = [super init])) { 268 if ((self = [super init])) {
252 _observers.reset([[TabModelObservers 269 _tabs.reset([[NSMutableSet alloc] init]);
253 observersWithProtocol:@protocol(TabModelObserver)] retain]); 270 _observers.reset([[TabModelObservers observers] retain]);
271
272 _fastEnumerationHelper.reset([[WebStateListFastEnumerationHelper alloc]
273 initWithWebStateList:&_webStateList
274 proxyFactory:self]);
254 275
255 _browserState = browserState; 276 _browserState = browserState;
256 DCHECK(_browserState); 277 DCHECK(_browserState);
257 278
258 // There must be a valid session service defined to consume session windows. 279 // There must be a valid session service defined to consume session windows.
259 DCHECK(service); 280 DCHECK(service);
260 _sessionService.reset([service retain]); 281 _sessionService.reset([service retain]);
261 282
262 // Normal browser states are the only ones to get tab restore. Tab sync 283 // Normal browser states are the only ones to get tab restore. Tab sync
263 // handles incognito browser states by filtering on profile, so it's 284 // handles incognito browser states by filtering on profile, so it's
264 // important to the backend code to always have a sync window delegate. 285 // important to the backend code to always have a sync window delegate.
265 if (!_browserState->IsOffTheRecord()) { 286 if (!_browserState->IsOffTheRecord()) {
266 // Set up the usage recorder before tabs are created. 287 // Set up the usage recorder before tabs are created.
267 _tabUsageRecorder.reset(new TabUsageRecorder(self)); 288 _tabUsageRecorder.reset(new TabUsageRecorder(self));
268 } 289 }
269 _syncedWindowDelegate.reset(new TabModelSyncedWindowDelegate(self)); 290 _syncedWindowDelegate.reset(new TabModelSyncedWindowDelegate(self));
270 291
271 _tabs.reset([[NSMutableArray alloc] init]);
272 if (window) { 292 if (window) {
273 DCHECK([_observers empty]); 293 DCHECK([_observers empty]);
274 // Restore the session and reset the session metrics (as the event have 294 // Restore the session and reset the session metrics (as the event have
275 // not been generated by the user but by a cold start cycle). 295 // not been generated by the user but by a cold start cycle).
276 [self restoreSessionWindow:window persistState:NO]; 296 [self restoreSessionWindow:window persistState:NO];
277 [self resetSessionMetrics]; 297 [self resetSessionMetrics];
278 } 298 }
279 299
280 _orderController.reset( 300 _orderController.reset(
281 [[TabModelOrderController alloc] initWithTabModel:self]); 301 [[TabModelOrderController alloc] initWithTabModel:self]);
(...skipping 28 matching lines...) Expand all
310 return nil; 330 return nil;
311 } 331 }
312 332
313 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window { 333 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window {
314 return [self restoreSessionWindow:window persistState:YES]; 334 return [self restoreSessionWindow:window persistState:YES];
315 } 335 }
316 336
317 - (void)saveSessionImmediately:(BOOL)immediately { 337 - (void)saveSessionImmediately:(BOOL)immediately {
318 // Do nothing if there are tabs in the model but no selected tab. This is 338 // Do nothing if there are tabs in the model but no selected tab. This is
319 // a transitional state. 339 // a transitional state.
320 if ((!_currentTab && [_tabs count]) || !_browserState) 340 if ((!_currentTab && _webStateList.count()) || !_browserState)
321 return; 341 return;
322 [_sessionService saveWindow:self.windowForSavingSession 342 [_sessionService saveWindow:self.windowForSavingSession
323 forBrowserState:_browserState 343 forBrowserState:_browserState
324 immediately:immediately]; 344 immediately:immediately];
325 } 345 }
326 346
327 - (Tab*)tabAtIndex:(NSUInteger)index { 347 - (Tab*)tabAtIndex:(NSUInteger)index {
328 return [_tabs objectAtIndex:index]; 348 web::WebState* webState = _webStateList.GetWebStateAt(index);
349 return LegacyTabHelper::GetTabForWebState(webState);
329 } 350 }
330 351
331 - (NSUInteger)indexOfTab:(Tab*)tab { 352 - (NSUInteger)indexOfTab:(Tab*)tab {
332 return [_tabs indexOfObject:tab]; 353 size_t index = _webStateList.GetIndexOfWebState(tab.webState);
354 return index == WebStateList::kInvalidIndex ? NSNotFound : index;
333 } 355 }
334 356
335 - (Tab*)tabWithWindowName:(NSString*)windowName { 357 - (Tab*)tabWithWindowName:(NSString*)windowName {
336 if (!windowName) 358 if (!windowName)
337 return nil; 359 return nil;
338 for (Tab* tab in _tabs.get()) { 360 for (Tab* tab in self) {
339 if ([windowName isEqualToString:tab.windowName]) { 361 if ([windowName isEqualToString:tab.windowName]) {
340 return tab; 362 return tab;
341 } 363 }
342 } 364 }
343 return nil; 365 return nil;
344 } 366 }
345 367
346 - (Tab*)nextTabWithOpener:(Tab*)tab afterTab:(Tab*)afterTab { 368 - (Tab*)nextTabWithOpener:(Tab*)tab afterTab:(Tab*)afterTab {
347 NSUInteger startIndex = NSNotFound; 369 NSUInteger startIndex = NSNotFound;
348 // Start looking after |afterTab|. If it's not found, start looking after 370 // Start looking after |afterTab|. If it's not found, start looking after
349 // |tab|. If it's not found either, bail. 371 // |tab|. If it's not found either, bail.
350 if (afterTab) 372 if (afterTab)
351 startIndex = [self indexOfTab:afterTab]; 373 startIndex = [self indexOfTab:afterTab];
352 if (startIndex == NSNotFound) 374 if (startIndex == NSNotFound)
353 startIndex = [self indexOfTab:tab]; 375 startIndex = [self indexOfTab:tab];
354 if (startIndex == NSNotFound) 376 if (startIndex == NSNotFound)
355 return nil; 377 return nil;
356 NSString* parentID = tab.tabId; 378 NSString* parentID = tab.tabId;
357 for (NSUInteger i = startIndex + 1; i < [_tabs count]; ++i) { 379 for (NSUInteger i = startIndex + 1; i < _webStateList.count(); ++i) {
358 Tab* current = [_tabs objectAtIndex:i]; 380 Tab* current = [self tabAtIndex:i];
359 DCHECK([current navigationManager]); 381 DCHECK([current navigationManager]);
360 CRWSessionController* sessionController = 382 CRWSessionController* sessionController =
361 [current navigationManager]->GetSessionController(); 383 [current navigationManager]->GetSessionController();
362 if ([sessionController.openerId isEqualToString:parentID]) 384 if ([sessionController.openerId isEqualToString:parentID])
363 return current; 385 return current;
364 } 386 }
365 return nil; 387 return nil;
366 } 388 }
367 389
368 - (Tab*)firstTabWithOpener:(Tab*)tab { 390 - (Tab*)firstTabWithOpener:(Tab*)tab {
369 if (!tab) 391 if (!tab)
370 return nil; 392 return nil;
371 NSUInteger stopIndex = [self indexOfTab:tab]; 393 NSUInteger stopIndex = [self indexOfTab:tab];
372 if (stopIndex == NSNotFound) 394 if (stopIndex == NSNotFound)
373 return nil; 395 return nil;
374 NSString* parentID = tab.tabId; 396 NSString* parentID = tab.tabId;
375 // Match the navigation index as well as the session id, to better match the 397 // Match the navigation index as well as the session id, to better match the
376 // state of the tab. I.e. two tabs are opened via a link from tab A, and then 398 // state of the tab. I.e. two tabs are opened via a link from tab A, and then
377 // a new url is loaded into tab A, and more tabs opened from that url, the 399 // a new url is loaded into tab A, and more tabs opened from that url, the
378 // latter two tabs should not be grouped with the former two. The navigation 400 // latter two tabs should not be grouped with the former two. The navigation
379 // index is the simplest way to detect navigation changes. 401 // index is the simplest way to detect navigation changes.
380 DCHECK([tab navigationManager]); 402 DCHECK([tab navigationManager]);
381 NSInteger parentNavIndex = [tab navigationManager]->GetCurrentItemIndex(); 403 NSInteger parentNavIndex = [tab navigationManager]->GetCurrentItemIndex();
382 for (NSUInteger i = 0; i < stopIndex; ++i) { 404 for (NSUInteger i = 0; i < stopIndex; ++i) {
383 Tab* tabToCheck = [_tabs objectAtIndex:i]; 405 Tab* tabToCheck = [self tabAtIndex:i];
384 DCHECK([tabToCheck navigationManager]); 406 DCHECK([tabToCheck navigationManager]);
385 CRWSessionController* sessionController = 407 CRWSessionController* sessionController =
386 [tabToCheck navigationManager]->GetSessionController(); 408 [tabToCheck navigationManager]->GetSessionController();
387 if ([sessionController.openerId isEqualToString:parentID] && 409 if ([sessionController.openerId isEqualToString:parentID] &&
388 sessionController.openerNavigationIndex == parentNavIndex) { 410 sessionController.openerNavigationIndex == parentNavIndex) {
389 return tabToCheck; 411 return tabToCheck;
390 } 412 }
391 } 413 }
392 return nil; 414 return nil;
393 } 415 }
394 416
395 - (Tab*)lastTabWithOpener:(Tab*)tab { 417 - (Tab*)lastTabWithOpener:(Tab*)tab {
396 NSUInteger startIndex = [self indexOfTab:tab]; 418 NSUInteger startIndex = [self indexOfTab:tab];
397 if (startIndex == NSNotFound) 419 if (startIndex == NSNotFound)
398 return nil; 420 return nil;
399 // There is at least one tab in the model, because otherwise the above check 421 // There is at least one tab in the model, because otherwise the above check
400 // would have returned. 422 // would have returned.
401 NSString* parentID = tab.tabId; 423 NSString* parentID = tab.tabId;
402 DCHECK([tab navigationManager]); 424 DCHECK([tab navigationManager]);
403 NSInteger parentNavIndex = [tab navigationManager]->GetCurrentItemIndex(); 425 NSInteger parentNavIndex = [tab navigationManager]->GetCurrentItemIndex();
404 426
405 Tab* match = nil; 427 Tab* match = nil;
406 // Find the last tab in the first matching 'group'. A 'group' is a set of 428 // Find the last tab in the first matching 'group'. A 'group' is a set of
407 // tabs whose opener's id and opener's navigation index match. The navigation 429 // tabs whose opener's id and opener's navigation index match. The navigation
408 // index is used in addition to the session id to detect navigations changes 430 // index is used in addition to the session id to detect navigations changes
409 // within the same session. 431 // within the same session.
410 for (NSUInteger i = startIndex + 1; i < [_tabs count]; ++i) { 432 for (NSUInteger i = startIndex + 1; i < _webStateList.count(); ++i) {
411 Tab* tabToCheck = [_tabs objectAtIndex:i]; 433 Tab* tabToCheck = [self tabAtIndex:i];
412 DCHECK([tabToCheck navigationManager]); 434 DCHECK([tabToCheck navigationManager]);
413 CRWSessionController* sessionController = 435 CRWSessionController* sessionController =
414 [tabToCheck navigationManager]->GetSessionController(); 436 [tabToCheck navigationManager]->GetSessionController();
415 if ([sessionController.openerId isEqualToString:parentID] && 437 if ([sessionController.openerId isEqualToString:parentID] &&
416 sessionController.openerNavigationIndex == parentNavIndex) { 438 sessionController.openerNavigationIndex == parentNavIndex) {
417 match = tabToCheck; 439 match = tabToCheck;
418 } else if (match) { 440 } else if (match) {
419 break; 441 break;
420 } 442 }
421 } 443 }
422 return match; 444 return match;
423 } 445 }
424 446
425 - (Tab*)openerOfTab:(Tab*)tab { 447 - (Tab*)openerOfTab:(Tab*)tab {
426 if (![tab navigationManager]) 448 if (![tab navigationManager])
427 return nil; 449 return nil;
428 NSString* openerId = [tab navigationManager]->GetSessionController().openerId; 450 NSString* openerId = [tab navigationManager]->GetSessionController().openerId;
429 if (!openerId.length) // Short-circuit if opener is empty. 451 if (!openerId.length) // Short-circuit if opener is empty.
430 return nil; 452 return nil;
431 for (Tab* iteratedTab in _tabs.get()) { 453 for (Tab* iteratedTab in self) {
432 if ([iteratedTab.tabId isEqualToString:openerId]) 454 if ([iteratedTab.tabId isEqualToString:openerId])
433 return iteratedTab; 455 return iteratedTab;
434 } 456 }
435 return nil; 457 return nil;
436 } 458 }
437 459
438 - (Tab*)insertOrUpdateTabWithURL:(const GURL&)URL 460 - (Tab*)insertOrUpdateTabWithURL:(const GURL&)URL
439 referrer:(const web::Referrer&)referrer 461 referrer:(const web::Referrer&)referrer
440 transition:(ui::PageTransition)transition 462 transition:(ui::PageTransition)transition
441 windowName:(NSString*)windowName 463 windowName:(NSString*)windowName
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 DCHECK_EQ(webState->GetBrowserState(), _browserState); 536 DCHECK_EQ(webState->GetBrowserState(), _browserState);
515 base::scoped_nsobject<Tab> tab( 537 base::scoped_nsobject<Tab> tab(
516 [[Tab alloc] initWithWebState:std::move(webState) model:self]); 538 [[Tab alloc] initWithWebState:std::move(webState) model:self]);
517 [tab webController].webUsageEnabled = webUsageEnabled_; 539 [tab webController].webUsageEnabled = webUsageEnabled_;
518 [self insertTab:tab atIndex:index]; 540 [self insertTab:tab atIndex:index];
519 return tab; 541 return tab;
520 } 542 }
521 543
522 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index { 544 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index {
523 DCHECK(tab); 545 DCHECK(tab);
524 DCHECK(index <= [_tabs count]); 546 DCHECK(![_tabs containsObject:tab]);
525 [tab fetchFavicon]; 547 [tab fetchFavicon];
526 [_tabs insertObject:tab atIndex:index];
527 548
549 [_tabs addObject:tab];
550 _webStateList.InsertWebState(index, tab.webState);
528 TabParentingGlobalObserver::GetInstance()->OnTabParented(tab.webState); 551 TabParentingGlobalObserver::GetInstance()->OnTabParented(tab.webState);
529 [_observers tabModel:self didInsertTab:tab atIndex:index inForeground:NO]; 552 [_observers tabModel:self didInsertTab:tab atIndex:index inForeground:NO];
530 [_observers tabModelDidChangeTabCount:self]; 553 [_observers tabModelDidChangeTabCount:self];
531 554
532 base::RecordAction(base::UserMetricsAction("MobileNewTabOpened")); 555 base::RecordAction(base::UserMetricsAction("MobileNewTabOpened"));
533 // Persist the session due to a new tab being inserted. If this is a 556 // Persist the session due to a new tab being inserted. If this is a
534 // background tab (will not become active), saving now will capture the 557 // background tab (will not become active), saving now will capture the
535 // state properly. If it does eventually become active, another save will 558 // state properly. If it does eventually become active, another save will
536 // be triggered to properly capture the end result. 559 // be triggered to properly capture the end result.
537 [self saveSessionImmediately:NO]; 560 [self saveSessionImmediately:NO];
561
538 ++_newTabCount; 562 ++_newTabCount;
539 } 563 }
540 564
541 - (void)moveTab:(Tab*)tab toIndex:(NSUInteger)toIndex { 565 - (void)moveTab:(Tab*)tab toIndex:(NSUInteger)toIndex {
rohitrao (ping after 24h) 2017/02/14 14:37:12 DCHECK([_tabs containsObject:tab]);
542 NSUInteger fromIndex = [self indexOfTab:tab]; 566 size_t fromIndex = _webStateList.GetIndexOfWebState(tab.webState);
543 DCHECK_NE(NSNotFound, static_cast<NSInteger>(fromIndex)); 567 _webStateList.MoveWebStateAt(fromIndex, toIndex);
544 DCHECK_LT(toIndex, self.count);
545 if (fromIndex == NSNotFound || toIndex >= self.count ||
546 fromIndex == toIndex) {
547 return;
548 }
549
550 base::scoped_nsobject<Tab> tabSaver([tab retain]);
551 [_tabs removeObject:tab];
552 [_tabs insertObject:tab atIndex:toIndex];
553
554 [_observers tabModel:self didMoveTab:tab fromIndex:fromIndex toIndex:toIndex]; 568 [_observers tabModel:self didMoveTab:tab fromIndex:fromIndex toIndex:toIndex];
555 } 569 }
556 570
557 - (void)replaceTab:(Tab*)oldTab withTab:(Tab*)newTab { 571 - (void)replaceTab:(Tab*)oldTab withTab:(Tab*)newTab {
558 NSUInteger index = [self indexOfTab:oldTab]; 572 NSUInteger index = [self indexOfTab:oldTab];
559 DCHECK_NE(NSNotFound, static_cast<NSInteger>(index)); 573 DCHECK_NE(NSNotFound, static_cast<NSInteger>(index));
574 DCHECK([_tabs containsObject:oldTab]);
575 DCHECK(![_tabs containsObject:newTab]);
560 576
561 base::scoped_nsobject<Tab> tabSaver([oldTab retain]); 577 base::scoped_nsobject<Tab> tabSaver([oldTab retain]);
562 [newTab fetchFavicon]; 578 [newTab fetchFavicon];
563 [_tabs replaceObjectAtIndex:index withObject:newTab]; 579 [_tabs removeObject:oldTab];
580 [_tabs addObject:newTab];
564 [newTab setParentTabModel:self]; 581 [newTab setParentTabModel:self];
565 582
583 _webStateList.ReplaceWebStateAt(index, newTab.webState);
566 TabParentingGlobalObserver::GetInstance()->OnTabParented(newTab.webState); 584 TabParentingGlobalObserver::GetInstance()->OnTabParented(newTab.webState);
567 [_observers tabModel:self didReplaceTab:oldTab withTab:newTab atIndex:index]; 585 [_observers tabModel:self didReplaceTab:oldTab withTab:newTab atIndex:index];
568 586
569 if (self.currentTab == oldTab) 587 if (self.currentTab == oldTab)
570 [self changeSelectedTabFrom:nil to:newTab persistState:NO]; 588 [self changeSelectedTabFrom:nil to:newTab persistState:NO];
571 589
572 [oldTab setParentTabModel:nil]; 590 [oldTab setParentTabModel:nil];
573 [oldTab close]; 591 [oldTab close];
574 592
575 // Record a tab clobber, since swapping tabs bypasses the tab code that would 593 // Record a tab clobber, since swapping tabs bypasses the tab code that would
576 // normally log clobbers. 594 // normally log clobbers.
577 base::RecordAction(base::UserMetricsAction("MobileTabClobbered")); 595 base::RecordAction(base::UserMetricsAction("MobileTabClobbered"));
578 } 596 }
579 597
580 - (void)closeTabAtIndex:(NSUInteger)index { 598 - (void)closeTabAtIndex:(NSUInteger)index {
581 DCHECK(index < [_tabs count]); 599 DCHECK(index < _webStateList.count());
582 [self closeTab:[_tabs objectAtIndex:index]]; 600 [self closeTab:[self tabAtIndex:index]];
583 } 601 }
584 602
585 - (void)closeTab:(Tab*)tab { 603 - (void)closeTab:(Tab*)tab {
586 // Ensure the tab stays alive long enough for us to send out the 604 // Ensure the tab stays alive long enough for us to send out the
587 // notice of its destruction to the delegate. 605 // notice of its destruction to the delegate.
588 [_observers tabModel:self willRemoveTab:tab]; 606 [_observers tabModel:self willRemoveTab:tab];
589 [tab close]; // Note it is not safe to access the tab after 'close'. 607 [tab close]; // Note it is not safe to access the tab after 'close'.
590 } 608 }
591 609
592 - (void)closeAllTabs { 610 - (void)closeAllTabs {
593 // If this changes, _closedTabCount metrics need to be adjusted. 611 // If this changes, _closedTabCount metrics need to be adjusted.
594 for (NSInteger i = self.count - 1; i >= 0; --i) 612 for (NSInteger i = self.count - 1; i >= 0; --i)
595 [self closeTabAtIndex:i]; 613 [self closeTabAtIndex:i];
596 [[NSNotificationCenter defaultCenter] 614 [[NSNotificationCenter defaultCenter]
597 postNotificationName:kTabModelAllTabsDidCloseNotification 615 postNotificationName:kTabModelAllTabsDidCloseNotification
598 object:self]; 616 object:self];
599 } 617 }
600 618
601 - (void)haltAllTabs { 619 - (void)haltAllTabs {
602 for (Tab* tab in _tabs.get()) { 620 for (Tab* tab in self) {
603 [tab terminateNetworkActivity]; 621 [tab terminateNetworkActivity];
604 } 622 }
605 } 623 }
606 624
607 - (void)notifyTabChanged:(Tab*)tab { 625 - (void)notifyTabChanged:(Tab*)tab {
608 [_observers tabModel:self didChangeTab:tab]; 626 [_observers tabModel:self didChangeTab:tab];
609 } 627 }
610 628
611 - (void)addObserver:(id<TabModelObserver>)observer { 629 - (void)addObserver:(id<TabModelObserver>)observer {
612 [_observers addObserver:observer]; 630 [_observers addObserver:observer];
(...skipping 16 matching lines...) Expand all
629 200, 50); 647 200, 50);
630 UMA_HISTOGRAM_CUSTOM_COUNTS("Session.NewTabCounts", _newTabCount, 1, 200, 50); 648 UMA_HISTOGRAM_CUSTOM_COUNTS("Session.NewTabCounts", _newTabCount, 1, 200, 50);
631 } 649 }
632 650
633 - (void)notifyTabSnapshotChanged:(Tab*)tab withImage:(UIImage*)image { 651 - (void)notifyTabSnapshotChanged:(Tab*)tab withImage:(UIImage*)image {
634 DCHECK([NSThread isMainThread]); 652 DCHECK([NSThread isMainThread]);
635 [_observers tabModel:self didChangeTabSnapshot:tab withImage:image]; 653 [_observers tabModel:self didChangeTabSnapshot:tab withImage:image];
636 } 654 }
637 655
638 - (void)resetAllWebViews { 656 - (void)resetAllWebViews {
639 for (Tab* tab in _tabs.get()) { 657 for (Tab* tab in self) {
640 [tab.webController reinitializeWebViewAndReload:(tab == _currentTab)]; 658 [tab.webController reinitializeWebViewAndReload:(tab == _currentTab)];
641 } 659 }
642 } 660 }
643 661
644 - (void)setWebUsageEnabled:(BOOL)webUsageEnabled { 662 - (void)setWebUsageEnabled:(BOOL)webUsageEnabled {
645 if (webUsageEnabled_ == webUsageEnabled) 663 if (webUsageEnabled_ == webUsageEnabled)
646 return; 664 return;
647 webUsageEnabled_ = webUsageEnabled; 665 webUsageEnabled_ = webUsageEnabled;
648 for (Tab* tab in _tabs.get()) { 666 for (Tab* tab in self) {
649 tab.webUsageEnabled = webUsageEnabled; 667 tab.webUsageEnabled = webUsageEnabled;
650 } 668 }
651 } 669 }
652 670
653 - (void)setPrimary:(BOOL)primary { 671 - (void)setPrimary:(BOOL)primary {
654 if (_tabUsageRecorder) 672 if (_tabUsageRecorder)
655 _tabUsageRecorder->RecordPrimaryTabModelChange(primary, _currentTab); 673 _tabUsageRecorder->RecordPrimaryTabModelChange(primary, _currentTab);
656 } 674 }
657 675
658 - (NSSet*)currentlyReferencedExternalFiles { 676 - (NSSet*)currentlyReferencedExternalFiles {
659 NSMutableSet* referencedFiles = [NSMutableSet set]; 677 NSMutableSet* referencedFiles = [NSMutableSet set];
660 if (!_browserState) 678 if (!_browserState)
661 return referencedFiles; 679 return referencedFiles;
662 // Check the currently open tabs for external files. 680 // Check the currently open tabs for external files.
663 for (Tab* tab in _tabs.get()) { 681 for (Tab* tab in self) {
664 if (UrlIsExternalFileReference(tab.url)) { 682 if (UrlIsExternalFileReference(tab.url)) {
665 NSString* fileName = base::SysUTF8ToNSString(tab.url.ExtractFileName()); 683 NSString* fileName = base::SysUTF8ToNSString(tab.url.ExtractFileName());
666 [referencedFiles addObject:fileName]; 684 [referencedFiles addObject:fileName];
667 } 685 }
668 } 686 }
669 // Do the same for the recently closed tabs. 687 // Do the same for the recently closed tabs.
670 sessions::TabRestoreService* restoreService = 688 sessions::TabRestoreService* restoreService =
671 IOSChromeTabRestoreServiceFactory::GetForBrowserState(_browserState); 689 IOSChromeTabRestoreServiceFactory::GetForBrowserState(_browserState);
672 DCHECK(restoreService); 690 DCHECK(restoreService);
673 for (const auto& entry : restoreService->entries()) { 691 for (const auto& entry : restoreService->entries()) {
(...skipping 16 matching lines...) Expand all
690 [[NSNotificationCenter defaultCenter] removeObserver:self]; 708 [[NSNotificationCenter defaultCenter] removeObserver:self];
691 if (_browserState) { 709 if (_browserState) {
692 UnregisterTabModelFromChromeBrowserState(_browserState, self); 710 UnregisterTabModelFromChromeBrowserState(_browserState, self);
693 } 711 }
694 _browserState = nullptr; 712 _browserState = nullptr;
695 } 713 }
696 714
697 // Called when a tab is closing, but before its CRWWebController is destroyed. 715 // Called when a tab is closing, but before its CRWWebController is destroyed.
698 // Equivalent to DetachTabContentsAt() in Chrome's TabStripModel. 716 // Equivalent to DetachTabContentsAt() in Chrome's TabStripModel.
699 - (void)didCloseTab:(Tab*)closedTab { 717 - (void)didCloseTab:(Tab*)closedTab {
700 NSUInteger closedTabIndex = [_tabs indexOfObject:closedTab]; 718 NSUInteger closedTabIndex = [self indexOfTab:closedTab];
701 DCHECK(closedTab); 719 DCHECK(closedTab);
702 DCHECK(closedTabIndex != NSNotFound); 720 DCHECK(closedTabIndex != NSNotFound);
703 // Let the sessions::TabRestoreService know about that new tab. 721 // Let the sessions::TabRestoreService know about that new tab.
704 sessions::TabRestoreService* restoreService = 722 sessions::TabRestoreService* restoreService =
705 _browserState 723 _browserState
706 ? IOSChromeTabRestoreServiceFactory::GetForBrowserState(_browserState) 724 ? IOSChromeTabRestoreServiceFactory::GetForBrowserState(_browserState)
707 : nullptr; 725 : nullptr;
708 web::NavigationManagerImpl* navigationManager = [closedTab navigationManager]; 726 web::NavigationManagerImpl* navigationManager = [closedTab navigationManager];
709 DCHECK(navigationManager); 727 DCHECK(navigationManager);
710 int itemCount = navigationManager->GetItemCount(); 728 int itemCount = navigationManager->GetItemCount();
711 if (restoreService && (![self isNTPTab:closedTab] || itemCount > 1)) { 729 if (restoreService && (![self isNTPTab:closedTab] || itemCount > 1)) {
712 restoreService->CreateHistoricalTab( 730 restoreService->CreateHistoricalTab(
713 sessions::IOSLiveTab::GetForWebState(closedTab.webState), 731 sessions::IOSLiveTab::GetForWebState(closedTab.webState),
714 static_cast<int>(closedTabIndex)); 732 static_cast<int>(closedTabIndex));
715 } 733 }
716 // This needs to be called before the tab is removed from the list. 734 // This needs to be called before the tab is removed from the list.
717 Tab* newSelection = 735 Tab* newSelection =
718 [_orderController determineNewSelectedTabFromRemovedTab:closedTab]; 736 [_orderController determineNewSelectedTabFromRemovedTab:closedTab];
737
719 base::scoped_nsobject<Tab> kungFuDeathGrip([closedTab retain]); 738 base::scoped_nsobject<Tab> kungFuDeathGrip([closedTab retain]);
720 [_tabs removeObject:closedTab];
721 739
722 // If closing the current tab, clear |_currentTab| before sending any 740 // If closing the current tab, clear |_currentTab| before sending any
723 // notification. This avoids various parts of the code getting confused 741 // notification. This avoids various parts of the code getting confused
724 // when the current tab isn't in the tab model. 742 // when the current tab isn't in the tab model.
725 Tab* savedCurrentTab = _currentTab; 743 Tab* savedCurrentTab = _currentTab;
726 if (closedTab == _currentTab) 744 if (closedTab == _currentTab)
727 _currentTab.reset(nil); 745 _currentTab.reset(nil);
728 746
747 DCHECK([_tabs containsObject:closedTab]);
748 [_tabs removeObject:closedTab];
749
750 _webStateList.RemoveWebStateAt(closedTabIndex);
729 [_observers tabModel:self didRemoveTab:closedTab atIndex:closedTabIndex]; 751 [_observers tabModel:self didRemoveTab:closedTab atIndex:closedTabIndex];
730 [_observers tabModelDidChangeTabCount:self]; 752 [_observers tabModelDidChangeTabCount:self];
731 753
732 // Current tab has closed, update the selected tab and swap in its 754 // Current tab has closed, update the selected tab and swap in its
733 // contents. There is nothing to do if a non-selected tab is closed as 755 // contents. There is nothing to do if a non-selected tab is closed as
734 // the selection isn't index-based, therefore it hasn't changed. 756 // the selection isn't index-based, therefore it hasn't changed.
735 // -changeSelectedTabFrom: will persist the state change, so only do it 757 // -changeSelectedTabFrom: will persist the state change, so only do it
736 // if the selection isn't changing. 758 // if the selection isn't changing.
737 if (closedTab == savedCurrentTab) { 759 if (closedTab == savedCurrentTab) {
738 [self changeSelectedTabFrom:closedTab to:newSelection persistState:NO]; 760 [self changeSelectedTabFrom:closedTab to:newSelection persistState:NO];
(...skipping 27 matching lines...) Expand all
766 788
767 int tabCount = static_cast<int>(self.count); 789 int tabCount = static_cast<int>(self.count);
768 UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountPerLoad", tabCount, 1, 200, 50); 790 UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountPerLoad", tabCount, 1, 200, 50);
769 } 791 }
770 792
771 #pragma mark - NSFastEnumeration 793 #pragma mark - NSFastEnumeration
772 794
773 - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState*)state 795 - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState*)state
774 objects:(id*)objects 796 objects:(id*)objects
775 count:(NSUInteger)count { 797 count:(NSUInteger)count {
776 return [_tabs countByEnumeratingWithState:state objects:objects count:count]; 798 return [_fastEnumerationHelper countByEnumeratingWithState:state
799 objects:objects
800 count:count];
777 } 801 }
778 802
779 #pragma mark - TabUsageRecorderDelegate 803 #pragma mark - TabUsageRecorderDelegate
780 804
781 - (NSUInteger)liveTabsCount { 805 - (NSUInteger)liveTabsCount {
782 NSUInteger count = 0; 806 NSUInteger count = 0;
783 NSArray* tabs = _tabs.get(); 807 for (Tab* tab in self) {
784 for (Tab* tab in tabs) {
785 if ([tab.webController isViewAlive]) 808 if ([tab.webController isViewAlive])
786 count++; 809 count++;
787 } 810 }
788 return count; 811 return count;
789 } 812 }
790 813
814 #pragma mark - WebStateProxyFactory
815
816 - (id)proxyForWebState:(web::WebState*)webState {
rohitrao (ping after 24h) 2017/02/14 14:37:12 What is this for?
817 return LegacyTabHelper::GetTabForWebState(webState);
818 }
819
791 #pragma mark - Private methods 820 #pragma mark - Private methods
792 821
793 - (SessionWindowIOS*)windowForSavingSession { 822 - (SessionWindowIOS*)windowForSavingSession {
794 // Background tabs will already have their state preserved, but not the 823 // Background tabs will already have their state preserved, but not the
795 // fg tab. Do it now. 824 // fg tab. Do it now.
796 [_currentTab recordStateInHistory]; 825 [_currentTab recordStateInHistory];
797 826
798 // Build the array of sessions. Copy the session objects as the saving will 827 // Build the array of sessions. Copy the session objects as the saving will
799 // be done on a separate thread. 828 // be done on a separate thread.
800 // TODO(crbug.com/661986): This could get expensive especially since this 829 // TODO(crbug.com/661986): This could get expensive especially since this
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 974
946 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window 975 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window
947 persistState:(BOOL)persistState { 976 persistState:(BOOL)persistState {
948 DCHECK(_browserState); 977 DCHECK(_browserState);
949 DCHECK(window); 978 DCHECK(window);
950 979
951 NSArray* sessions = window.sessions; 980 NSArray* sessions = window.sessions;
952 if (!sessions.count) 981 if (!sessions.count)
953 return NO; 982 return NO;
954 983
955 size_t oldCount = [_tabs count]; 984 size_t oldCount = _webStateList.count();
956 web::WebState::CreateParams params(_browserState); 985 web::WebState::CreateParams params(_browserState);
957 scoped_refptr<web::CertificatePolicyCache> policyCache = 986 scoped_refptr<web::CertificatePolicyCache> policyCache =
958 web::BrowserState::GetCertificatePolicyCache(_browserState); 987 web::BrowserState::GetCertificatePolicyCache(_browserState);
959 988
960 for (CRWNavigationManagerStorage* session in sessions) { 989 for (CRWNavigationManagerStorage* session in sessions) {
961 std::unique_ptr<web::WebState> webState = 990 std::unique_ptr<web::WebState> webState =
962 web::WebState::Create(params, session); 991 web::WebState::Create(params, session);
963 DCHECK_EQ(webState->GetBrowserState(), _browserState); 992 DCHECK_EQ(webState->GetBrowserState(), _browserState);
964 Tab* tab = 993 Tab* tab = [self insertTabWithWebState:std::move(webState)
965 [self insertTabWithWebState:std::move(webState) atIndex:[_tabs count]]; 994 atIndex:_webStateList.count()];
966 tab.webController.usePlaceholderOverlay = YES; 995 tab.webController.usePlaceholderOverlay = YES;
967 996
968 // Restore the CertificatePolicyCache (note that webState is invalid after 997 // Restore the CertificatePolicyCache (note that webState is invalid after
969 // passing it via move semantic to -insertTabWithWebState:atIndex:). 998 // passing it via move semantic to -insertTabWithWebState:atIndex:).
970 UpdateCertificatePolicyCacheFromWebState(policyCache, tab.webState); 999 UpdateCertificatePolicyCacheFromWebState(policyCache, tab.webState);
971 } 1000 }
972 DCHECK_GT([_tabs count], oldCount); 1001 DCHECK_GT(_webStateList.count(), oldCount);
973 1002
974 // Update the selected tab if there was a selected Tab in the saved session. 1003 // Update the selected tab if there was a selected Tab in the saved session.
975 if (window.selectedIndex != NSNotFound) { 1004 if (window.selectedIndex != NSNotFound) {
976 NSUInteger selectedIndex = window.selectedIndex + oldCount; 1005 NSUInteger selectedIndex = window.selectedIndex + oldCount;
977 DCHECK_LT(selectedIndex, [_tabs count]); 1006 DCHECK_LT(selectedIndex, _webStateList.count());
978 DCHECK([self tabAtIndex:selectedIndex]); 1007 DCHECK([self tabAtIndex:selectedIndex]);
979 [self changeSelectedTabFrom:_currentTab 1008 [self changeSelectedTabFrom:_currentTab
980 to:[self tabAtIndex:selectedIndex] 1009 to:[self tabAtIndex:selectedIndex]
981 persistState:persistState]; 1010 persistState:persistState];
982 } 1011 }
983 1012
984 // If there was only one tab and it was the new tab page, clobber it. 1013 // If there was only one tab and it was the new tab page, clobber it.
985 BOOL closedNTPTab = NO; 1014 BOOL closedNTPTab = NO;
986 if (oldCount == 1) { 1015 if (oldCount == 1) {
987 Tab* tab = [_tabs objectAtIndex:0]; 1016 Tab* tab = [self tabAtIndex:0];
988 if (tab.url == GURL(kChromeUINewTabURL)) { 1017 if (tab.url == GURL(kChromeUINewTabURL)) {
989 [self closeTab:tab]; 1018 [self closeTab:tab];
990 closedNTPTab = YES; 1019 closedNTPTab = YES;
991 oldCount = 0; 1020 oldCount = 0;
992 } 1021 }
993 } 1022 }
994 if (_tabUsageRecorder) { 1023 if (_tabUsageRecorder) {
995 _tabUsageRecorder->InitialRestoredTabs( 1024 NSMutableArray<Tab*>* restoredTabs =
996 _currentTab, 1025 [NSMutableArray arrayWithCapacity:_webStateList.count() - oldCount];
997 [_tabs 1026 for (size_t index = oldCount; index < _webStateList.count(); ++index) {
998 subarrayWithRange:NSMakeRange(oldCount, [_tabs count] - oldCount)]); 1027 [restoredTabs addObject:[self tabAtIndex:index]];
1028 }
1029 _tabUsageRecorder->InitialRestoredTabs(_currentTab, restoredTabs);
999 } 1030 }
1000 return closedNTPTab; 1031 return closedNTPTab;
1001 } 1032 }
1002 1033
1003 #pragma mark - Notification Handlers 1034 #pragma mark - Notification Handlers
1004 1035
1005 // Called when UIApplicationWillResignActiveNotification is received. 1036 // Called when UIApplicationWillResignActiveNotification is received.
1006 - (void)willResignActive:(NSNotification*)notify { 1037 - (void)willResignActive:(NSNotification*)notify {
1007 if (webUsageEnabled_ && _currentTab) { 1038 if (webUsageEnabled_ && _currentTab) {
1008 [[SnapshotCache sharedInstance] 1039 [[SnapshotCache sharedInstance]
1009 willBeSavedGreyWhenBackgrounding:_currentTab.get().tabId]; 1040 willBeSavedGreyWhenBackgrounding:_currentTab.get().tabId];
1010 } 1041 }
1011 } 1042 }
1012 1043
1013 // Called when UIApplicationDidEnterBackgroundNotification is received. 1044 // Called when UIApplicationDidEnterBackgroundNotification is received.
1014 - (void)applicationDidEnterBackground:(NSNotification*)notify { 1045 - (void)applicationDidEnterBackground:(NSNotification*)notify {
1015 if (!_browserState) 1046 if (!_browserState)
1016 return; 1047 return;
1017 1048
1018 // Evict all the certificate policies except for the current entries of the 1049 // Evict all the certificate policies except for the current entries of the
1019 // active sessions. 1050 // active sessions.
1020 CleanCertificatePolicyCache( 1051 CleanCertificatePolicyCache(
1021 &_clearPoliciesTaskTracker, 1052 &_clearPoliciesTaskTracker,
1022 web::WebThread::GetTaskRunnerForThread(web::WebThread::IO), 1053 web::WebThread::GetTaskRunnerForThread(web::WebThread::IO),
1023 web::BrowserState::GetCertificatePolicyCache(_browserState), self); 1054 web::BrowserState::GetCertificatePolicyCache(_browserState),
1055 &_webStateList);
1024 1056
1025 if (_tabUsageRecorder) 1057 if (_tabUsageRecorder)
1026 _tabUsageRecorder->AppDidEnterBackground(); 1058 _tabUsageRecorder->AppDidEnterBackground();
1027 1059
1028 // Normally, the session is saved after some timer expires but since the app 1060 // Normally, the session is saved after some timer expires but since the app
1029 // is about to enter the background send YES to save the session immediately. 1061 // is about to enter the background send YES to save the session immediately.
1030 [self saveSessionImmediately:YES]; 1062 [self saveSessionImmediately:YES];
1031 1063
1032 // Write out a grey version of the current website to disk. 1064 // Write out a grey version of the current website to disk.
1033 if (webUsageEnabled_ && _currentTab) { 1065 if (webUsageEnabled_ && _currentTab) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 web::NavigationManager::WebLoadParams params(URL); 1104 web::NavigationManager::WebLoadParams params(URL);
1073 params.referrer = referrer; 1105 params.referrer = referrer;
1074 params.transition_type = ui::PAGE_TRANSITION_TYPED; 1106 params.transition_type = ui::PAGE_TRANSITION_TYPED;
1075 [[tab webController] loadWithParams:params]; 1107 [[tab webController] loadWithParams:params];
1076 [tab webController].webUsageEnabled = webUsageEnabled_; 1108 [tab webController].webUsageEnabled = webUsageEnabled_;
1077 [self insertTab:tab atIndex:index]; 1109 [self insertTab:tab atIndex:index];
1078 return tab; 1110 return tab;
1079 } 1111 }
1080 1112
1081 @end 1113 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/tabs/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698