| OLD | NEW |
| 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 <cstdint> | 7 #include <cstdint> |
| 8 #include <utility> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 #import "ios/chrome/browser/snapshots/snapshot_cache.h" | 31 #import "ios/chrome/browser/snapshots/snapshot_cache.h" |
| 32 #import "ios/chrome/browser/snapshots/snapshot_cache_web_state_list_observer.h" | 32 #import "ios/chrome/browser/snapshots/snapshot_cache_web_state_list_observer.h" |
| 33 #include "ios/chrome/browser/tab_parenting_global_observer.h" | 33 #include "ios/chrome/browser/tab_parenting_global_observer.h" |
| 34 #import "ios/chrome/browser/tabs/legacy_tab_helper.h" | 34 #import "ios/chrome/browser/tabs/legacy_tab_helper.h" |
| 35 #import "ios/chrome/browser/tabs/tab.h" | 35 #import "ios/chrome/browser/tabs/tab.h" |
| 36 #import "ios/chrome/browser/tabs/tab_model_list.h" | 36 #import "ios/chrome/browser/tabs/tab_model_list.h" |
| 37 #import "ios/chrome/browser/tabs/tab_model_observers.h" | 37 #import "ios/chrome/browser/tabs/tab_model_observers.h" |
| 38 #import "ios/chrome/browser/tabs/tab_model_observers_bridge.h" | 38 #import "ios/chrome/browser/tabs/tab_model_observers_bridge.h" |
| 39 #import "ios/chrome/browser/tabs/tab_model_selected_tab_observer.h" | 39 #import "ios/chrome/browser/tabs/tab_model_selected_tab_observer.h" |
| 40 #import "ios/chrome/browser/tabs/tab_model_synced_window_delegate.h" | 40 #import "ios/chrome/browser/tabs/tab_model_synced_window_delegate.h" |
| 41 #import "ios/chrome/browser/tabs/tab_model_web_state_list_delegate.h" |
| 41 #import "ios/chrome/browser/tabs/tab_parenting_observer.h" | 42 #import "ios/chrome/browser/tabs/tab_parenting_observer.h" |
| 42 #import "ios/chrome/browser/xcallback_parameters.h" | 43 #import "ios/chrome/browser/xcallback_parameters.h" |
| 43 #import "ios/shared/chrome/browser/tabs/web_state_list.h" | 44 #import "ios/shared/chrome/browser/tabs/web_state_list.h" |
| 44 #import "ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper.h
" | 45 #import "ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper.h
" |
| 45 #import "ios/shared/chrome/browser/tabs/web_state_list_metrics_observer.h" | 46 #import "ios/shared/chrome/browser/tabs/web_state_list_metrics_observer.h" |
| 46 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h" | 47 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h" |
| 47 #import "ios/web/navigation/crw_session_certificate_policy_manager.h" | 48 #import "ios/web/navigation/crw_session_certificate_policy_manager.h" |
| 48 #import "ios/web/navigation/crw_session_controller.h" | 49 #import "ios/web/navigation/crw_session_controller.h" |
| 49 #include "ios/web/public/browser_state.h" | 50 #include "ios/web/public/browser_state.h" |
| 50 #include "ios/web/public/certificate_policy_cache.h" | 51 #include "ios/web/public/certificate_policy_cache.h" |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 | 141 |
| 141 @implementation TabModelWebStateProxyFactory | 142 @implementation TabModelWebStateProxyFactory |
| 142 | 143 |
| 143 - (id)proxyForWebState:(web::WebState*)webState { | 144 - (id)proxyForWebState:(web::WebState*)webState { |
| 144 return LegacyTabHelper::GetTabForWebState(webState); | 145 return LegacyTabHelper::GetTabForWebState(webState); |
| 145 } | 146 } |
| 146 | 147 |
| 147 @end | 148 @end |
| 148 | 149 |
| 149 @interface TabModel ()<TabUsageRecorderDelegate> { | 150 @interface TabModel ()<TabUsageRecorderDelegate> { |
| 151 // Delegate for the WebStateList. |
| 152 std::unique_ptr<WebStateListDelegate> _webStateListDelegate; |
| 153 |
| 150 // Underlying shared model implementation. | 154 // Underlying shared model implementation. |
| 151 WebStateList _webStateList; | 155 std::unique_ptr<WebStateList> _webStateList; |
| 152 | 156 |
| 153 // Helper providing NSFastEnumeration implementation over the WebStateList. | 157 // Helper providing NSFastEnumeration implementation over the WebStateList. |
| 154 base::scoped_nsobject<WebStateListFastEnumerationHelper> | 158 base::scoped_nsobject<WebStateListFastEnumerationHelper> |
| 155 _fastEnumerationHelper; | 159 _fastEnumerationHelper; |
| 156 | 160 |
| 157 // Used to keep the Tabs alive while the corresponding WebStates are stored | 161 // Used to keep the Tabs alive while the corresponding WebStates are stored |
| 158 // in the WebStateList (as Tabs currently own their WebState). Remove once | 162 // in the WebStateList (as Tabs currently own their WebState). Remove once |
| 159 // WebState owns the associated Tab. | 163 // WebState owns the associated Tab. |
| 160 base::scoped_nsobject<NSMutableSet<Tab*>> _tabRetainer; | 164 base::scoped_nsobject<NSMutableSet<Tab*>> _tabRetainer; |
| 161 | 165 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 // browserStateDestroyed should always have been called before destruction. | 232 // browserStateDestroyed should always have been called before destruction. |
| 229 DCHECK(!_browserState); | 233 DCHECK(!_browserState); |
| 230 | 234 |
| 231 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 235 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 232 | 236 |
| 233 // Clear weak pointer to WebStateListMetricsObserver before destroying it. | 237 // Clear weak pointer to WebStateListMetricsObserver before destroying it. |
| 234 _webStateListMetricsObserver = nullptr; | 238 _webStateListMetricsObserver = nullptr; |
| 235 | 239 |
| 236 // Unregister all listeners before closing all the tabs. | 240 // Unregister all listeners before closing all the tabs. |
| 237 for (const auto& observerBridge : _observerBridges) | 241 for (const auto& observerBridge : _observerBridges) |
| 238 _webStateList.RemoveObserver(observerBridge.get()); | 242 _webStateList->RemoveObserver(observerBridge.get()); |
| 239 _observerBridges.clear(); | 243 _observerBridges.clear(); |
| 240 | 244 |
| 241 // Make sure the tabs do clean after themselves. It is important for | 245 // Make sure the tabs do clean after themselves. It is important for |
| 242 // removeObserver: to be called first otherwise a lot of unecessary work will | 246 // removeObserver: to be called first otherwise a lot of unecessary work will |
| 243 // happen on -closeAllTabs. | 247 // happen on -closeAllTabs. |
| 244 [self closeAllTabs]; | 248 [self closeAllTabs]; |
| 245 | 249 |
| 246 _clearPoliciesTaskTracker.TryCancelAll(); | 250 _clearPoliciesTaskTracker.TryCancelAll(); |
| 247 | 251 |
| 248 [super dealloc]; | 252 [super dealloc]; |
| 249 } | 253 } |
| 250 | 254 |
| 251 #pragma mark - Public methods | 255 #pragma mark - Public methods |
| 252 | 256 |
| 253 - (Tab*)currentTab { | 257 - (Tab*)currentTab { |
| 254 web::WebState* webState = _webStateList.GetActiveWebState(); | 258 web::WebState* webState = _webStateList->GetActiveWebState(); |
| 255 return webState ? LegacyTabHelper::GetTabForWebState(webState) : nil; | 259 return webState ? LegacyTabHelper::GetTabForWebState(webState) : nil; |
| 256 } | 260 } |
| 257 | 261 |
| 258 - (void)setCurrentTab:(Tab*)newTab { | 262 - (void)setCurrentTab:(Tab*)newTab { |
| 259 int indexOfTab = _webStateList.GetIndexOfWebState(newTab.webState); | 263 int indexOfTab = _webStateList->GetIndexOfWebState(newTab.webState); |
| 260 DCHECK_NE(indexOfTab, WebStateList::kInvalidIndex); | 264 DCHECK_NE(indexOfTab, WebStateList::kInvalidIndex); |
| 261 _webStateList.ActivateWebStateAt(indexOfTab); | 265 _webStateList->ActivateWebStateAt(indexOfTab); |
| 262 } | 266 } |
| 263 | 267 |
| 264 - (TabModelSyncedWindowDelegate*)syncedWindowDelegate { | 268 - (TabModelSyncedWindowDelegate*)syncedWindowDelegate { |
| 265 return _syncedWindowDelegate.get(); | 269 return _syncedWindowDelegate.get(); |
| 266 } | 270 } |
| 267 | 271 |
| 268 - (TabUsageRecorder*)tabUsageRecorder { | 272 - (TabUsageRecorder*)tabUsageRecorder { |
| 269 return _tabUsageRecorder.get(); | 273 return _tabUsageRecorder.get(); |
| 270 } | 274 } |
| 271 | 275 |
| 272 - (BOOL)isOffTheRecord { | 276 - (BOOL)isOffTheRecord { |
| 273 return _browserState && _browserState->IsOffTheRecord(); | 277 return _browserState && _browserState->IsOffTheRecord(); |
| 274 } | 278 } |
| 275 | 279 |
| 276 - (BOOL)isEmpty { | 280 - (BOOL)isEmpty { |
| 277 return _webStateList.empty(); | 281 return _webStateList->empty(); |
| 278 } | 282 } |
| 279 | 283 |
| 280 - (NSUInteger)count { | 284 - (NSUInteger)count { |
| 281 DCHECK_GE(_webStateList.count(), 0); | 285 DCHECK_GE(_webStateList->count(), 0); |
| 282 return static_cast<NSUInteger>(_webStateList.count()); | 286 return static_cast<NSUInteger>(_webStateList->count()); |
| 283 } | 287 } |
| 284 | 288 |
| 285 - (instancetype)initWithSessionWindow:(SessionWindowIOS*)window | 289 - (instancetype)initWithSessionWindow:(SessionWindowIOS*)window |
| 286 sessionService:(SessionServiceIOS*)service | 290 sessionService:(SessionServiceIOS*)service |
| 287 browserState:(ios::ChromeBrowserState*)browserState { | 291 browserState:(ios::ChromeBrowserState*)browserState { |
| 288 if ((self = [super init])) { | 292 if ((self = [super init])) { |
| 289 _tabRetainer.reset([[NSMutableSet alloc] init]); | 293 _tabRetainer.reset([[NSMutableSet alloc] init]); |
| 290 _observers.reset([[TabModelObservers observers] retain]); | 294 _observers.reset([[TabModelObservers observers] retain]); |
| 291 | 295 |
| 296 _webStateListDelegate = |
| 297 base::MakeUnique<TabModelWebStateListDelegate>(self); |
| 298 _webStateList = base::MakeUnique<WebStateList>( |
| 299 _webStateListDelegate.get(), WebStateList::WebStateBorrowed); |
| 300 |
| 292 _fastEnumerationHelper.reset([[WebStateListFastEnumerationHelper alloc] | 301 _fastEnumerationHelper.reset([[WebStateListFastEnumerationHelper alloc] |
| 293 initWithWebStateList:&_webStateList | 302 initWithWebStateList:_webStateList.get() |
| 294 proxyFactory:[[TabModelWebStateProxyFactory alloc] init]]); | 303 proxyFactory:[[TabModelWebStateProxyFactory alloc] init]]); |
| 295 | 304 |
| 296 _browserState = browserState; | 305 _browserState = browserState; |
| 297 DCHECK(_browserState); | 306 DCHECK(_browserState); |
| 298 | 307 |
| 299 // Normal browser states are the only ones to get tab restore. Tab sync | 308 // Normal browser states are the only ones to get tab restore. Tab sync |
| 300 // handles incognito browser states by filtering on profile, so it's | 309 // handles incognito browser states by filtering on profile, so it's |
| 301 // important to the backend code to always have a sync window delegate. | 310 // important to the backend code to always have a sync window delegate. |
| 302 if (!_browserState->IsOffTheRecord()) { | 311 if (!_browserState->IsOffTheRecord()) { |
| 303 // Set up the usage recorder before tabs are created. | 312 // Set up the usage recorder before tabs are created. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 324 _observerBridges.push_back(base::MakeUnique<WebStateListObserverBridge>( | 333 _observerBridges.push_back(base::MakeUnique<WebStateListObserverBridge>( |
| 325 [[TabModelObserversBridge alloc] initWithTabModel:self | 334 [[TabModelObserversBridge alloc] initWithTabModel:self |
| 326 tabModelObservers:_observers.get()])); | 335 tabModelObservers:_observers.get()])); |
| 327 | 336 |
| 328 auto webStateListMetricsObserver = | 337 auto webStateListMetricsObserver = |
| 329 base::MakeUnique<WebStateListMetricsObserver>(); | 338 base::MakeUnique<WebStateListMetricsObserver>(); |
| 330 _webStateListMetricsObserver = webStateListMetricsObserver.get(); | 339 _webStateListMetricsObserver = webStateListMetricsObserver.get(); |
| 331 _observerBridges.push_back(std::move(webStateListMetricsObserver)); | 340 _observerBridges.push_back(std::move(webStateListMetricsObserver)); |
| 332 | 341 |
| 333 for (const auto& observerBridge : _observerBridges) | 342 for (const auto& observerBridge : _observerBridges) |
| 334 _webStateList.AddObserver(observerBridge.get()); | 343 _webStateList->AddObserver(observerBridge.get()); |
| 335 | 344 |
| 336 if (window) { | 345 if (window) { |
| 337 DCHECK([_observers empty]); | 346 DCHECK([_observers empty]); |
| 338 // Restore the session and reset the session metrics (as the event have | 347 // Restore the session and reset the session metrics (as the event have |
| 339 // not been generated by the user but by a cold start cycle). | 348 // not been generated by the user but by a cold start cycle). |
| 340 [self restoreSessionWindow:window persistState:NO]; | 349 [self restoreSessionWindow:window persistState:NO]; |
| 341 [self resetSessionMetrics]; | 350 [self resetSessionMetrics]; |
| 342 } | 351 } |
| 343 | 352 |
| 344 // Register for resign active notification. | 353 // Register for resign active notification. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 371 return nil; | 380 return nil; |
| 372 } | 381 } |
| 373 | 382 |
| 374 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window { | 383 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window { |
| 375 return [self restoreSessionWindow:window persistState:YES]; | 384 return [self restoreSessionWindow:window persistState:YES]; |
| 376 } | 385 } |
| 377 | 386 |
| 378 - (void)saveSessionImmediately:(BOOL)immediately { | 387 - (void)saveSessionImmediately:(BOOL)immediately { |
| 379 // Do nothing if there are tabs in the model but no selected tab. This is | 388 // Do nothing if there are tabs in the model but no selected tab. This is |
| 380 // a transitional state. | 389 // a transitional state. |
| 381 if ((!self.currentTab && _webStateList.count()) || !_browserState) | 390 if ((!self.currentTab && _webStateList->count()) || !_browserState) |
| 382 return; | 391 return; |
| 383 [_sessionService saveWindow:self.windowForSavingSession | 392 [_sessionService saveWindow:self.windowForSavingSession |
| 384 forBrowserState:_browserState | 393 forBrowserState:_browserState |
| 385 immediately:immediately]; | 394 immediately:immediately]; |
| 386 } | 395 } |
| 387 | 396 |
| 388 - (Tab*)tabAtIndex:(NSUInteger)index { | 397 - (Tab*)tabAtIndex:(NSUInteger)index { |
| 389 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); | 398 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); |
| 390 return LegacyTabHelper::GetTabForWebState( | 399 return LegacyTabHelper::GetTabForWebState( |
| 391 _webStateList.GetWebStateAt(static_cast<int>(index))); | 400 _webStateList->GetWebStateAt(static_cast<int>(index))); |
| 392 } | 401 } |
| 393 | 402 |
| 394 - (NSUInteger)indexOfTab:(Tab*)tab { | 403 - (NSUInteger)indexOfTab:(Tab*)tab { |
| 395 int index = _webStateList.GetIndexOfWebState(tab.webState); | 404 int index = _webStateList->GetIndexOfWebState(tab.webState); |
| 396 if (index == WebStateList::kInvalidIndex) | 405 if (index == WebStateList::kInvalidIndex) |
| 397 return NSNotFound; | 406 return NSNotFound; |
| 398 | 407 |
| 399 DCHECK_GE(index, 0); | 408 DCHECK_GE(index, 0); |
| 400 return static_cast<NSUInteger>(index); | 409 return static_cast<NSUInteger>(index); |
| 401 } | 410 } |
| 402 | 411 |
| 403 - (Tab*)nextTabWithOpener:(Tab*)tab afterTab:(Tab*)afterTab { | 412 - (Tab*)nextTabWithOpener:(Tab*)tab afterTab:(Tab*)afterTab { |
| 404 int startIndex = WebStateList::kInvalidIndex; | 413 int startIndex = WebStateList::kInvalidIndex; |
| 405 if (afterTab) | 414 if (afterTab) |
| 406 startIndex = _webStateList.GetIndexOfWebState(afterTab.webState); | 415 startIndex = _webStateList->GetIndexOfWebState(afterTab.webState); |
| 407 | 416 |
| 408 if (startIndex == WebStateList::kInvalidIndex) | 417 if (startIndex == WebStateList::kInvalidIndex) |
| 409 startIndex = _webStateList.GetIndexOfWebState(tab.webState); | 418 startIndex = _webStateList->GetIndexOfWebState(tab.webState); |
| 410 | 419 |
| 411 const int index = _webStateList.GetIndexOfNextWebStateOpenedBy( | 420 const int index = _webStateList->GetIndexOfNextWebStateOpenedBy( |
| 412 tab.webState, startIndex, false); | 421 tab.webState, startIndex, false); |
| 413 if (index == WebStateList::kInvalidIndex) | 422 if (index == WebStateList::kInvalidIndex) |
| 414 return nil; | 423 return nil; |
| 415 | 424 |
| 416 DCHECK_GE(index, 0); | 425 DCHECK_GE(index, 0); |
| 417 return [self tabAtIndex:static_cast<NSUInteger>(index)]; | 426 return [self tabAtIndex:static_cast<NSUInteger>(index)]; |
| 418 } | 427 } |
| 419 | 428 |
| 420 - (Tab*)lastTabWithOpener:(Tab*)tab { | 429 - (Tab*)lastTabWithOpener:(Tab*)tab { |
| 421 int startIndex = _webStateList.GetIndexOfWebState(tab.webState); | 430 int startIndex = _webStateList->GetIndexOfWebState(tab.webState); |
| 422 if (startIndex == WebStateList::kInvalidIndex) | 431 if (startIndex == WebStateList::kInvalidIndex) |
| 423 return nil; | 432 return nil; |
| 424 | 433 |
| 425 const int index = _webStateList.GetIndexOfLastWebStateOpenedBy( | 434 const int index = _webStateList->GetIndexOfLastWebStateOpenedBy( |
| 426 tab.webState, startIndex, true); | 435 tab.webState, startIndex, true); |
| 427 if (index == WebStateList::kInvalidIndex) | 436 if (index == WebStateList::kInvalidIndex) |
| 428 return nil; | 437 return nil; |
| 429 | 438 |
| 430 DCHECK_GE(index, 0); | 439 DCHECK_GE(index, 0); |
| 431 return [self tabAtIndex:static_cast<NSUInteger>(index)]; | 440 return [self tabAtIndex:static_cast<NSUInteger>(index)]; |
| 432 } | 441 } |
| 433 | 442 |
| 434 - (Tab*)openerOfTab:(Tab*)tab { | 443 - (Tab*)openerOfTab:(Tab*)tab { |
| 435 int index = _webStateList.GetIndexOfWebState(tab.webState); | 444 int index = _webStateList->GetIndexOfWebState(tab.webState); |
| 436 if (index == WebStateList::kInvalidIndex) | 445 if (index == WebStateList::kInvalidIndex) |
| 437 return nil; | 446 return nil; |
| 438 | 447 |
| 439 web::WebState* opener = _webStateList.GetOpenerOfWebStateAt(index); | 448 web::WebState* opener = _webStateList->GetOpenerOfWebStateAt(index); |
| 440 return opener ? LegacyTabHelper::GetTabForWebState(opener) : nil; | 449 return opener ? LegacyTabHelper::GetTabForWebState(opener) : nil; |
| 441 } | 450 } |
| 442 | 451 |
| 443 - (Tab*)insertTabWithURL:(const GURL&)URL | 452 - (Tab*)insertTabWithURL:(const GURL&)URL |
| 444 referrer:(const web::Referrer&)referrer | 453 referrer:(const web::Referrer&)referrer |
| 445 transition:(ui::PageTransition)transition | 454 transition:(ui::PageTransition)transition |
| 446 opener:(Tab*)parentTab | 455 opener:(Tab*)parentTab |
| 447 openedByDOM:(BOOL)openedByDOM | 456 openedByDOM:(BOOL)openedByDOM |
| 448 atIndex:(NSUInteger)index | 457 atIndex:(NSUInteger)index |
| 449 inBackground:(BOOL)inBackground { | 458 inBackground:(BOOL)inBackground { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 | 519 |
| 511 - (void)insertTab:(Tab*)tab | 520 - (void)insertTab:(Tab*)tab |
| 512 atIndex:(NSUInteger)index | 521 atIndex:(NSUInteger)index |
| 513 opener:(Tab*)parentTab | 522 opener:(Tab*)parentTab |
| 514 transition:(ui::PageTransition)transition { | 523 transition:(ui::PageTransition)transition { |
| 515 DCHECK(tab); | 524 DCHECK(tab); |
| 516 DCHECK(![_tabRetainer containsObject:tab]); | 525 DCHECK(![_tabRetainer containsObject:tab]); |
| 517 | 526 |
| 518 [_tabRetainer addObject:tab]; | 527 [_tabRetainer addObject:tab]; |
| 519 if (index == TabModelConstants::kTabPositionAutomatically) { | 528 if (index == TabModelConstants::kTabPositionAutomatically) { |
| 520 _webStateList.AppendWebState(transition, tab.webState, parentTab.webState); | 529 _webStateList->AppendWebState(transition, tab.webState, parentTab.webState); |
| 521 } else { | 530 } else { |
| 522 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); | 531 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); |
| 523 const int insertion_index = static_cast<int>(index); | 532 const int insertion_index = static_cast<int>(index); |
| 524 _webStateList.InsertWebState(insertion_index, tab.webState, | 533 _webStateList->InsertWebState(insertion_index, tab.webState, |
| 525 parentTab.webState); | 534 parentTab.webState); |
| 526 } | 535 } |
| 527 | 536 |
| 528 // Persist the session due to a new tab being inserted. If this is a | 537 // Persist the session due to a new tab being inserted. If this is a |
| 529 // background tab (will not become active), saving now will capture the | 538 // background tab (will not become active), saving now will capture the |
| 530 // state properly. If it does eventually become active, another save will | 539 // state properly. If it does eventually become active, another save will |
| 531 // be triggered to properly capture the end result. | 540 // be triggered to properly capture the end result. |
| 532 [self saveSessionImmediately:NO]; | 541 [self saveSessionImmediately:NO]; |
| 533 } | 542 } |
| 534 | 543 |
| 535 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index opener:(Tab*)parentTab { | 544 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index opener:(Tab*)parentTab { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 547 DCHECK(tab); | 556 DCHECK(tab); |
| 548 DCHECK(![_tabRetainer containsObject:tab]); | 557 DCHECK(![_tabRetainer containsObject:tab]); |
| 549 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); | 558 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); |
| 550 | 559 |
| 551 [self insertTab:tab atIndex:index opener:GetOpenerForTab(self, tab)]; | 560 [self insertTab:tab atIndex:index opener:GetOpenerForTab(self, tab)]; |
| 552 } | 561 } |
| 553 | 562 |
| 554 - (void)moveTab:(Tab*)tab toIndex:(NSUInteger)toIndex { | 563 - (void)moveTab:(Tab*)tab toIndex:(NSUInteger)toIndex { |
| 555 DCHECK([_tabRetainer containsObject:tab]); | 564 DCHECK([_tabRetainer containsObject:tab]); |
| 556 DCHECK_LE(toIndex, static_cast<NSUInteger>(INT_MAX)); | 565 DCHECK_LE(toIndex, static_cast<NSUInteger>(INT_MAX)); |
| 557 int fromIndex = _webStateList.GetIndexOfWebState(tab.webState); | 566 int fromIndex = _webStateList->GetIndexOfWebState(tab.webState); |
| 558 _webStateList.MoveWebStateAt(fromIndex, static_cast<int>(toIndex)); | 567 _webStateList->MoveWebStateAt(fromIndex, static_cast<int>(toIndex)); |
| 559 } | 568 } |
| 560 | 569 |
| 561 - (void)replaceTab:(Tab*)oldTab withTab:(Tab*)newTab { | 570 - (void)replaceTab:(Tab*)oldTab withTab:(Tab*)newTab { |
| 562 DCHECK([_tabRetainer containsObject:oldTab]); | 571 DCHECK([_tabRetainer containsObject:oldTab]); |
| 563 DCHECK(![_tabRetainer containsObject:newTab]); | 572 DCHECK(![_tabRetainer containsObject:newTab]); |
| 564 | 573 |
| 565 int index = _webStateList.GetIndexOfWebState(oldTab.webState); | 574 int index = _webStateList->GetIndexOfWebState(oldTab.webState); |
| 566 DCHECK_NE(index, WebStateList::kInvalidIndex); | 575 DCHECK_NE(index, WebStateList::kInvalidIndex); |
| 567 DCHECK_GE(index, 0); | 576 DCHECK_GE(index, 0); |
| 568 | 577 |
| 569 base::scoped_nsobject<Tab> tabSaver([oldTab retain]); | 578 base::scoped_nsobject<Tab> tabSaver([oldTab retain]); |
| 570 [_tabRetainer removeObject:oldTab]; | 579 [_tabRetainer removeObject:oldTab]; |
| 571 [_tabRetainer addObject:newTab]; | 580 [_tabRetainer addObject:newTab]; |
| 572 [newTab setParentTabModel:self]; | 581 [newTab setParentTabModel:self]; |
| 573 | 582 |
| 574 // The WebState is owned by the associated Tab, so it is safe to ignore | 583 // The WebState is owned by the associated Tab, so it is safe to ignore |
| 575 // the result and won't cause a memory leak. Once the ownership is moved | 584 // the result and won't cause a memory leak. Once the ownership is moved |
| 576 // to WebStateList, this function will return a std::unique_ptr<> and the | 585 // to WebStateList, this function will return a std::unique_ptr<> and the |
| 577 // object destroyed as expected, so it will fine to ignore the result then | 586 // object destroyed as expected, so it will fine to ignore the result then |
| 578 // too. See http://crbug.com/546222 for progress of changing the ownership | 587 // too. See http://crbug.com/546222 for progress of changing the ownership |
| 579 // of the WebStates. | 588 // of the WebStates. |
| 580 ignore_result(_webStateList.ReplaceWebStateAt( | 589 ignore_result(_webStateList->ReplaceWebStateAt( |
| 581 index, newTab.webState, GetOpenerForTab(self, newTab).webState)); | 590 index, newTab.webState, GetOpenerForTab(self, newTab).webState)); |
| 582 | 591 |
| 583 [oldTab setParentTabModel:nil]; | 592 [oldTab setParentTabModel:nil]; |
| 584 [oldTab close]; | 593 [oldTab close]; |
| 585 } | 594 } |
| 586 | 595 |
| 587 - (void)closeTabAtIndex:(NSUInteger)index { | 596 - (void)closeTabAtIndex:(NSUInteger)index { |
| 588 DCHECK(index < self.count); | 597 DCHECK(index < self.count); |
| 589 [self closeTab:[self tabAtIndex:index]]; | 598 [self closeTab:[self tabAtIndex:index]]; |
| 590 } | 599 } |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 694 UnregisterTabModelFromChromeBrowserState(_browserState, self); | 703 UnregisterTabModelFromChromeBrowserState(_browserState, self); |
| 695 } | 704 } |
| 696 _browserState = nullptr; | 705 _browserState = nullptr; |
| 697 } | 706 } |
| 698 | 707 |
| 699 // Called when a tab is closing, but before its CRWWebController is destroyed. | 708 // Called when a tab is closing, but before its CRWWebController is destroyed. |
| 700 // Equivalent to DetachTabContentsAt() in Chrome's TabStripModel. | 709 // Equivalent to DetachTabContentsAt() in Chrome's TabStripModel. |
| 701 - (void)didCloseTab:(Tab*)closedTab { | 710 - (void)didCloseTab:(Tab*)closedTab { |
| 702 DCHECK(closedTab); | 711 DCHECK(closedTab); |
| 703 DCHECK([_tabRetainer containsObject:closedTab]); | 712 DCHECK([_tabRetainer containsObject:closedTab]); |
| 704 int closedTabIndex = _webStateList.GetIndexOfWebState(closedTab.webState); | 713 int closedTabIndex = _webStateList->GetIndexOfWebState(closedTab.webState); |
| 705 DCHECK_NE(closedTabIndex, WebStateList::kInvalidIndex); | 714 DCHECK_NE(closedTabIndex, WebStateList::kInvalidIndex); |
| 706 DCHECK_GE(closedTabIndex, 0); | 715 DCHECK_GE(closedTabIndex, 0); |
| 707 | 716 |
| 708 // Let the sessions::TabRestoreService know about that new tab. | 717 // Let the sessions::TabRestoreService know about that new tab. |
| 709 sessions::TabRestoreService* restoreService = | 718 sessions::TabRestoreService* restoreService = |
| 710 _browserState | 719 _browserState |
| 711 ? IOSChromeTabRestoreServiceFactory::GetForBrowserState(_browserState) | 720 ? IOSChromeTabRestoreServiceFactory::GetForBrowserState(_browserState) |
| 712 : nullptr; | 721 : nullptr; |
| 713 web::NavigationManager* navigationManager = [closedTab navigationManager]; | 722 web::NavigationManager* navigationManager = [closedTab navigationManager]; |
| 714 DCHECK(navigationManager); | 723 DCHECK(navigationManager); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 727 | 736 |
| 728 DCHECK([_tabRetainer containsObject:closedTab]); | 737 DCHECK([_tabRetainer containsObject:closedTab]); |
| 729 [_tabRetainer removeObject:closedTab]; | 738 [_tabRetainer removeObject:closedTab]; |
| 730 | 739 |
| 731 // The WebState is owned by the associated Tab, so it is safe to ignore | 740 // The WebState is owned by the associated Tab, so it is safe to ignore |
| 732 // the result and won't cause a memory leak. Once the ownership is moved | 741 // the result and won't cause a memory leak. Once the ownership is moved |
| 733 // to WebStateList, this function will return a std::unique_ptr<> and the | 742 // to WebStateList, this function will return a std::unique_ptr<> and the |
| 734 // object destroyed as expected, so it will fine to ignore the result then | 743 // object destroyed as expected, so it will fine to ignore the result then |
| 735 // too. See http://crbug.com/546222 for progress of changing the ownership | 744 // too. See http://crbug.com/546222 for progress of changing the ownership |
| 736 // of the WebStates. | 745 // of the WebStates. |
| 737 ignore_result(_webStateList.DetachWebStateAt(closedTabIndex)); | 746 ignore_result(_webStateList->DetachWebStateAt(closedTabIndex)); |
| 738 | 747 |
| 739 if (needToSaveSession) | 748 if (needToSaveSession) |
| 740 [self saveSessionImmediately:NO]; | 749 [self saveSessionImmediately:NO]; |
| 741 } | 750 } |
| 742 | 751 |
| 743 - (void)navigationCommittedInTab:(Tab*)tab | 752 - (void)navigationCommittedInTab:(Tab*)tab |
| 744 previousItem:(web::NavigationItem*)previousItem { | 753 previousItem:(web::NavigationItem*)previousItem { |
| 745 if (self.offTheRecord) | 754 if (self.offTheRecord) |
| 746 return; | 755 return; |
| 747 if (![tab navigationManager]) | 756 if (![tab navigationManager]) |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 | 834 |
| 826 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window | 835 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window |
| 827 persistState:(BOOL)persistState { | 836 persistState:(BOOL)persistState { |
| 828 DCHECK(_browserState); | 837 DCHECK(_browserState); |
| 829 DCHECK(window); | 838 DCHECK(window); |
| 830 | 839 |
| 831 NSArray* sessions = window.sessions; | 840 NSArray* sessions = window.sessions; |
| 832 if (!sessions.count) | 841 if (!sessions.count) |
| 833 return NO; | 842 return NO; |
| 834 | 843 |
| 835 int oldCount = _webStateList.count(); | 844 int oldCount = _webStateList->count(); |
| 836 DCHECK_GE(oldCount, 0); | 845 DCHECK_GE(oldCount, 0); |
| 837 | 846 |
| 838 web::WebState::CreateParams params(_browserState); | 847 web::WebState::CreateParams params(_browserState); |
| 839 scoped_refptr<web::CertificatePolicyCache> policyCache = | 848 scoped_refptr<web::CertificatePolicyCache> policyCache = |
| 840 web::BrowserState::GetCertificatePolicyCache(_browserState); | 849 web::BrowserState::GetCertificatePolicyCache(_browserState); |
| 841 | 850 |
| 842 base::scoped_nsobject<NSMutableArray<Tab*>> restoredTabs( | 851 base::scoped_nsobject<NSMutableArray<Tab*>> restoredTabs( |
| 843 [[NSMutableArray alloc] initWithCapacity:sessions.count]); | 852 [[NSMutableArray alloc] initWithCapacity:sessions.count]); |
| 844 | 853 |
| 845 // Recreate all the restored Tabs and add them to the WebStateList without | 854 // Recreate all the restored Tabs and add them to the WebStateList without |
| 846 // any opener-opened relationship (as the n-th restored Tab opener may be | 855 // any opener-opened relationship (as the n-th restored Tab opener may be |
| 847 // at an index larger than n). Then in a second pass fix the openers. | 856 // at an index larger than n). Then in a second pass fix the openers. |
| 848 for (CRWSessionStorage* session in sessions) { | 857 for (CRWSessionStorage* session in sessions) { |
| 849 std::unique_ptr<web::WebState> webState = | 858 std::unique_ptr<web::WebState> webState = |
| 850 web::WebState::Create(params, session); | 859 web::WebState::Create(params, session); |
| 851 base::scoped_nsobject<Tab> tab( | 860 base::scoped_nsobject<Tab> tab( |
| 852 [[Tab alloc] initWithWebState:std::move(webState) model:self]); | 861 [[Tab alloc] initWithWebState:std::move(webState) model:self]); |
| 853 [tab webController].webUsageEnabled = webUsageEnabled_; | 862 [tab webController].webUsageEnabled = webUsageEnabled_; |
| 854 [tab webController].usePlaceholderOverlay = YES; | 863 [tab webController].usePlaceholderOverlay = YES; |
| 855 | 864 |
| 856 // Restore the CertificatePolicyCache (note that webState is invalid after | 865 // Restore the CertificatePolicyCache (note that webState is invalid after |
| 857 // passing it via move semantic to -initWithWebState:model:). | 866 // passing it via move semantic to -initWithWebState:model:). |
| 858 UpdateCertificatePolicyCacheFromWebState(policyCache, [tab webState]); | 867 UpdateCertificatePolicyCacheFromWebState(policyCache, [tab webState]); |
| 859 [self insertTab:tab atIndex:self.count opener:nil]; | 868 [self insertTab:tab atIndex:self.count opener:nil]; |
| 860 [restoredTabs addObject:tab.get()]; | 869 [restoredTabs addObject:tab.get()]; |
| 861 } | 870 } |
| 862 | 871 |
| 863 DCHECK_EQ(sessions.count, [restoredTabs count]); | 872 DCHECK_EQ(sessions.count, [restoredTabs count]); |
| 864 DCHECK_GT(_webStateList.count(), oldCount); | 873 DCHECK_GT(_webStateList->count(), oldCount); |
| 865 | 874 |
| 866 // Fix openers now that all Tabs have been restored. Only look for an opener | 875 // Fix openers now that all Tabs have been restored. Only look for an opener |
| 867 // Tab in the newly restored Tabs and not in the already open Tabs. | 876 // Tab in the newly restored Tabs and not in the already open Tabs. |
| 868 for (int index = oldCount; index < _webStateList.count(); ++index) { | 877 for (int index = oldCount; index < _webStateList->count(); ++index) { |
| 869 DCHECK_GE(index, oldCount); | 878 DCHECK_GE(index, oldCount); |
| 870 NSUInteger tabIndex = static_cast<NSUInteger>(index - oldCount); | 879 NSUInteger tabIndex = static_cast<NSUInteger>(index - oldCount); |
| 871 Tab* tab = [restoredTabs objectAtIndex:tabIndex]; | 880 Tab* tab = [restoredTabs objectAtIndex:tabIndex]; |
| 872 Tab* opener = GetOpenerForTab(restoredTabs.get(), tab); | 881 Tab* opener = GetOpenerForTab(restoredTabs.get(), tab); |
| 873 if (opener) { | 882 if (opener) { |
| 874 DCHECK(opener.webState); | 883 DCHECK(opener.webState); |
| 875 _webStateList.SetOpenerOfWebStateAt(index, opener.webState); | 884 _webStateList->SetOpenerOfWebStateAt(index, opener.webState); |
| 876 } | 885 } |
| 877 } | 886 } |
| 878 | 887 |
| 879 // Update the selected tab if there was a selected Tab in the saved session. | 888 // Update the selected tab if there was a selected Tab in the saved session. |
| 880 if (window.selectedIndex != NSNotFound) { | 889 if (window.selectedIndex != NSNotFound) { |
| 881 NSUInteger selectedIndex = window.selectedIndex + oldCount; | 890 NSUInteger selectedIndex = window.selectedIndex + oldCount; |
| 882 DCHECK_LT(selectedIndex, self.count); | 891 DCHECK_LT(selectedIndex, self.count); |
| 883 DCHECK([self tabAtIndex:selectedIndex]); | 892 DCHECK([self tabAtIndex:selectedIndex]); |
| 884 | 893 |
| 885 if (persistState && self.currentTab) | 894 if (persistState && self.currentTab) |
| 886 [self.currentTab recordStateInHistory]; | 895 [self.currentTab recordStateInHistory]; |
| 887 _webStateList.ActivateWebStateAt(static_cast<int>(selectedIndex)); | 896 _webStateList->ActivateWebStateAt(static_cast<int>(selectedIndex)); |
| 888 } | 897 } |
| 889 | 898 |
| 890 // If there was only one tab and it was the new tab page, clobber it. | 899 // If there was only one tab and it was the new tab page, clobber it. |
| 891 BOOL closedNTPTab = NO; | 900 BOOL closedNTPTab = NO; |
| 892 if (oldCount == 1) { | 901 if (oldCount == 1) { |
| 893 Tab* tab = [self tabAtIndex:0]; | 902 Tab* tab = [self tabAtIndex:0]; |
| 894 if (tab.url == GURL(kChromeUINewTabURL)) { | 903 if (tab.url == GURL(kChromeUINewTabURL)) { |
| 895 [self closeTab:tab]; | 904 [self closeTab:tab]; |
| 896 closedNTPTab = YES; | 905 closedNTPTab = YES; |
| 897 oldCount = 0; | 906 oldCount = 0; |
| 898 } | 907 } |
| 899 } | 908 } |
| 900 if (_tabUsageRecorder) { | 909 if (_tabUsageRecorder) { |
| 901 NSMutableArray<Tab*>* restoredTabs = | 910 NSMutableArray<Tab*>* restoredTabs = |
| 902 [NSMutableArray arrayWithCapacity:_webStateList.count() - oldCount]; | 911 [NSMutableArray arrayWithCapacity:_webStateList->count() - oldCount]; |
| 903 for (int index = oldCount; index < _webStateList.count(); ++index) { | 912 for (int index = oldCount; index < _webStateList->count(); ++index) { |
| 904 web::WebState* webState = _webStateList.GetWebStateAt(index); | 913 web::WebState* webState = _webStateList->GetWebStateAt(index); |
| 905 [restoredTabs addObject:LegacyTabHelper::GetTabForWebState(webState)]; | 914 [restoredTabs addObject:LegacyTabHelper::GetTabForWebState(webState)]; |
| 906 } | 915 } |
| 907 _tabUsageRecorder->InitialRestoredTabs(self.currentTab, restoredTabs); | 916 _tabUsageRecorder->InitialRestoredTabs(self.currentTab, restoredTabs); |
| 908 } | 917 } |
| 909 return closedNTPTab; | 918 return closedNTPTab; |
| 910 } | 919 } |
| 911 | 920 |
| 912 #pragma mark - Notification Handlers | 921 #pragma mark - Notification Handlers |
| 913 | 922 |
| 914 // Called when UIApplicationWillResignActiveNotification is received. | 923 // Called when UIApplicationWillResignActiveNotification is received. |
| 915 - (void)willResignActive:(NSNotification*)notify { | 924 - (void)willResignActive:(NSNotification*)notify { |
| 916 if (webUsageEnabled_ && self.currentTab) { | 925 if (webUsageEnabled_ && self.currentTab) { |
| 917 [[SnapshotCache sharedInstance] | 926 [[SnapshotCache sharedInstance] |
| 918 willBeSavedGreyWhenBackgrounding:self.currentTab.tabId]; | 927 willBeSavedGreyWhenBackgrounding:self.currentTab.tabId]; |
| 919 } | 928 } |
| 920 } | 929 } |
| 921 | 930 |
| 922 // Called when UIApplicationDidEnterBackgroundNotification is received. | 931 // Called when UIApplicationDidEnterBackgroundNotification is received. |
| 923 - (void)applicationDidEnterBackground:(NSNotification*)notify { | 932 - (void)applicationDidEnterBackground:(NSNotification*)notify { |
| 924 if (!_browserState) | 933 if (!_browserState) |
| 925 return; | 934 return; |
| 926 | 935 |
| 927 // Evict all the certificate policies except for the current entries of the | 936 // Evict all the certificate policies except for the current entries of the |
| 928 // active sessions. | 937 // active sessions. |
| 929 CleanCertificatePolicyCache( | 938 CleanCertificatePolicyCache( |
| 930 &_clearPoliciesTaskTracker, | 939 &_clearPoliciesTaskTracker, |
| 931 web::WebThread::GetTaskRunnerForThread(web::WebThread::IO), | 940 web::WebThread::GetTaskRunnerForThread(web::WebThread::IO), |
| 932 web::BrowserState::GetCertificatePolicyCache(_browserState), | 941 web::BrowserState::GetCertificatePolicyCache(_browserState), |
| 933 &_webStateList); | 942 _webStateList.get()); |
| 934 | 943 |
| 935 if (_tabUsageRecorder) | 944 if (_tabUsageRecorder) |
| 936 _tabUsageRecorder->AppDidEnterBackground(); | 945 _tabUsageRecorder->AppDidEnterBackground(); |
| 937 | 946 |
| 938 // Normally, the session is saved after some timer expires but since the app | 947 // Normally, the session is saved after some timer expires but since the app |
| 939 // is about to enter the background send YES to save the session immediately. | 948 // is about to enter the background send YES to save the session immediately. |
| 940 [self saveSessionImmediately:YES]; | 949 [self saveSessionImmediately:YES]; |
| 941 | 950 |
| 942 // Write out a grey version of the current website to disk. | 951 // Write out a grey version of the current website to disk. |
| 943 if (webUsageEnabled_ && self.currentTab) { | 952 if (webUsageEnabled_ && self.currentTab) { |
| 944 [[SnapshotCache sharedInstance] | 953 [[SnapshotCache sharedInstance] |
| 945 saveGreyInBackgroundForSessionID:self.currentTab.tabId]; | 954 saveGreyInBackgroundForSessionID:self.currentTab.tabId]; |
| 946 } | 955 } |
| 947 } | 956 } |
| 948 | 957 |
| 949 // Called when UIApplicationWillEnterForegroundNotification is received. | 958 // Called when UIApplicationWillEnterForegroundNotification is received. |
| 950 - (void)applicationWillEnterForeground:(NSNotification*)notify { | 959 - (void)applicationWillEnterForeground:(NSNotification*)notify { |
| 951 if (_tabUsageRecorder) { | 960 if (_tabUsageRecorder) { |
| 952 _tabUsageRecorder->AppWillEnterForeground(); | 961 _tabUsageRecorder->AppWillEnterForeground(); |
| 953 } | 962 } |
| 954 } | 963 } |
| 955 | 964 |
| 956 @end | 965 @end |
| OLD | NEW |