| 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 = base::MakeUnique<TabModelWebStateListDelegate>(); |
| 297 _webStateList = base::MakeUnique<WebStateList>( |
| 298 _webStateListDelegate.get(), WebStateList::WebStateBorrowed); |
| 299 |
| 292 _fastEnumerationHelper.reset([[WebStateListFastEnumerationHelper alloc] | 300 _fastEnumerationHelper.reset([[WebStateListFastEnumerationHelper alloc] |
| 293 initWithWebStateList:&_webStateList | 301 initWithWebStateList:_webStateList.get() |
| 294 proxyFactory:[[TabModelWebStateProxyFactory alloc] init]]); | 302 proxyFactory:[[TabModelWebStateProxyFactory alloc] init]]); |
| 295 | 303 |
| 296 _browserState = browserState; | 304 _browserState = browserState; |
| 297 DCHECK(_browserState); | 305 DCHECK(_browserState); |
| 298 | 306 |
| 299 // Normal browser states are the only ones to get tab restore. Tab sync | 307 // 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 | 308 // handles incognito browser states by filtering on profile, so it's |
| 301 // important to the backend code to always have a sync window delegate. | 309 // important to the backend code to always have a sync window delegate. |
| 302 if (!_browserState->IsOffTheRecord()) { | 310 if (!_browserState->IsOffTheRecord()) { |
| 303 // Set up the usage recorder before tabs are created. | 311 // Set up the usage recorder before tabs are created. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 324 _observerBridges.push_back(base::MakeUnique<WebStateListObserverBridge>( | 332 _observerBridges.push_back(base::MakeUnique<WebStateListObserverBridge>( |
| 325 [[TabModelObserversBridge alloc] initWithTabModel:self | 333 [[TabModelObserversBridge alloc] initWithTabModel:self |
| 326 tabModelObservers:_observers.get()])); | 334 tabModelObservers:_observers.get()])); |
| 327 | 335 |
| 328 auto webStateListMetricsObserver = | 336 auto webStateListMetricsObserver = |
| 329 base::MakeUnique<WebStateListMetricsObserver>(); | 337 base::MakeUnique<WebStateListMetricsObserver>(); |
| 330 _webStateListMetricsObserver = webStateListMetricsObserver.get(); | 338 _webStateListMetricsObserver = webStateListMetricsObserver.get(); |
| 331 _observerBridges.push_back(std::move(webStateListMetricsObserver)); | 339 _observerBridges.push_back(std::move(webStateListMetricsObserver)); |
| 332 | 340 |
| 333 for (const auto& observerBridge : _observerBridges) | 341 for (const auto& observerBridge : _observerBridges) |
| 334 _webStateList.AddObserver(observerBridge.get()); | 342 _webStateList->AddObserver(observerBridge.get()); |
| 335 | 343 |
| 336 if (window) { | 344 if (window) { |
| 337 DCHECK([_observers empty]); | 345 DCHECK([_observers empty]); |
| 338 // Restore the session and reset the session metrics (as the event have | 346 // 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). | 347 // not been generated by the user but by a cold start cycle). |
| 340 [self restoreSessionWindow:window persistState:NO]; | 348 [self restoreSessionWindow:window persistState:NO]; |
| 341 [self resetSessionMetrics]; | 349 [self resetSessionMetrics]; |
| 342 } | 350 } |
| 343 | 351 |
| 344 // Register for resign active notification. | 352 // Register for resign active notification. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 371 return nil; | 379 return nil; |
| 372 } | 380 } |
| 373 | 381 |
| 374 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window { | 382 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window { |
| 375 return [self restoreSessionWindow:window persistState:YES]; | 383 return [self restoreSessionWindow:window persistState:YES]; |
| 376 } | 384 } |
| 377 | 385 |
| 378 - (void)saveSessionImmediately:(BOOL)immediately { | 386 - (void)saveSessionImmediately:(BOOL)immediately { |
| 379 // Do nothing if there are tabs in the model but no selected tab. This is | 387 // Do nothing if there are tabs in the model but no selected tab. This is |
| 380 // a transitional state. | 388 // a transitional state. |
| 381 if ((!self.currentTab && _webStateList.count()) || !_browserState) | 389 if ((!self.currentTab && _webStateList->count()) || !_browserState) |
| 382 return; | 390 return; |
| 383 [_sessionService saveWindow:self.windowForSavingSession | 391 [_sessionService saveWindow:self.windowForSavingSession |
| 384 forBrowserState:_browserState | 392 forBrowserState:_browserState |
| 385 immediately:immediately]; | 393 immediately:immediately]; |
| 386 } | 394 } |
| 387 | 395 |
| 388 - (Tab*)tabAtIndex:(NSUInteger)index { | 396 - (Tab*)tabAtIndex:(NSUInteger)index { |
| 389 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); | 397 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); |
| 390 return LegacyTabHelper::GetTabForWebState( | 398 return LegacyTabHelper::GetTabForWebState( |
| 391 _webStateList.GetWebStateAt(static_cast<int>(index))); | 399 _webStateList->GetWebStateAt(static_cast<int>(index))); |
| 392 } | 400 } |
| 393 | 401 |
| 394 - (NSUInteger)indexOfTab:(Tab*)tab { | 402 - (NSUInteger)indexOfTab:(Tab*)tab { |
| 395 int index = _webStateList.GetIndexOfWebState(tab.webState); | 403 int index = _webStateList->GetIndexOfWebState(tab.webState); |
| 396 if (index == WebStateList::kInvalidIndex) | 404 if (index == WebStateList::kInvalidIndex) |
| 397 return NSNotFound; | 405 return NSNotFound; |
| 398 | 406 |
| 399 DCHECK_GE(index, 0); | 407 DCHECK_GE(index, 0); |
| 400 return static_cast<NSUInteger>(index); | 408 return static_cast<NSUInteger>(index); |
| 401 } | 409 } |
| 402 | 410 |
| 403 - (Tab*)nextTabWithOpener:(Tab*)tab afterTab:(Tab*)afterTab { | 411 - (Tab*)nextTabWithOpener:(Tab*)tab afterTab:(Tab*)afterTab { |
| 404 int startIndex = WebStateList::kInvalidIndex; | 412 int startIndex = WebStateList::kInvalidIndex; |
| 405 if (afterTab) | 413 if (afterTab) |
| 406 startIndex = _webStateList.GetIndexOfWebState(afterTab.webState); | 414 startIndex = _webStateList->GetIndexOfWebState(afterTab.webState); |
| 407 | 415 |
| 408 if (startIndex == WebStateList::kInvalidIndex) | 416 if (startIndex == WebStateList::kInvalidIndex) |
| 409 startIndex = _webStateList.GetIndexOfWebState(tab.webState); | 417 startIndex = _webStateList->GetIndexOfWebState(tab.webState); |
| 410 | 418 |
| 411 const int index = _webStateList.GetIndexOfNextWebStateOpenedBy( | 419 const int index = _webStateList->GetIndexOfNextWebStateOpenedBy( |
| 412 tab.webState, startIndex, false); | 420 tab.webState, startIndex, false); |
| 413 if (index == WebStateList::kInvalidIndex) | 421 if (index == WebStateList::kInvalidIndex) |
| 414 return nil; | 422 return nil; |
| 415 | 423 |
| 416 DCHECK_GE(index, 0); | 424 DCHECK_GE(index, 0); |
| 417 return [self tabAtIndex:static_cast<NSUInteger>(index)]; | 425 return [self tabAtIndex:static_cast<NSUInteger>(index)]; |
| 418 } | 426 } |
| 419 | 427 |
| 420 - (Tab*)lastTabWithOpener:(Tab*)tab { | 428 - (Tab*)lastTabWithOpener:(Tab*)tab { |
| 421 int startIndex = _webStateList.GetIndexOfWebState(tab.webState); | 429 int startIndex = _webStateList->GetIndexOfWebState(tab.webState); |
| 422 if (startIndex == WebStateList::kInvalidIndex) | 430 if (startIndex == WebStateList::kInvalidIndex) |
| 423 return nil; | 431 return nil; |
| 424 | 432 |
| 425 const int index = _webStateList.GetIndexOfLastWebStateOpenedBy( | 433 const int index = _webStateList->GetIndexOfLastWebStateOpenedBy( |
| 426 tab.webState, startIndex, true); | 434 tab.webState, startIndex, true); |
| 427 if (index == WebStateList::kInvalidIndex) | 435 if (index == WebStateList::kInvalidIndex) |
| 428 return nil; | 436 return nil; |
| 429 | 437 |
| 430 DCHECK_GE(index, 0); | 438 DCHECK_GE(index, 0); |
| 431 return [self tabAtIndex:static_cast<NSUInteger>(index)]; | 439 return [self tabAtIndex:static_cast<NSUInteger>(index)]; |
| 432 } | 440 } |
| 433 | 441 |
| 434 - (Tab*)openerOfTab:(Tab*)tab { | 442 - (Tab*)openerOfTab:(Tab*)tab { |
| 435 int index = _webStateList.GetIndexOfWebState(tab.webState); | 443 int index = _webStateList->GetIndexOfWebState(tab.webState); |
| 436 if (index == WebStateList::kInvalidIndex) | 444 if (index == WebStateList::kInvalidIndex) |
| 437 return nil; | 445 return nil; |
| 438 | 446 |
| 439 web::WebState* opener = _webStateList.GetOpenerOfWebStateAt(index); | 447 web::WebState* opener = _webStateList->GetOpenerOfWebStateAt(index); |
| 440 return opener ? LegacyTabHelper::GetTabForWebState(opener) : nil; | 448 return opener ? LegacyTabHelper::GetTabForWebState(opener) : nil; |
| 441 } | 449 } |
| 442 | 450 |
| 443 - (Tab*)insertTabWithURL:(const GURL&)URL | 451 - (Tab*)insertTabWithURL:(const GURL&)URL |
| 444 referrer:(const web::Referrer&)referrer | 452 referrer:(const web::Referrer&)referrer |
| 445 transition:(ui::PageTransition)transition | 453 transition:(ui::PageTransition)transition |
| 446 opener:(Tab*)parentTab | 454 opener:(Tab*)parentTab |
| 447 openedByDOM:(BOOL)openedByDOM | 455 openedByDOM:(BOOL)openedByDOM |
| 448 atIndex:(NSUInteger)index | 456 atIndex:(NSUInteger)index |
| 449 inBackground:(BOOL)inBackground { | 457 inBackground:(BOOL)inBackground { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 | 518 |
| 511 - (void)insertTab:(Tab*)tab | 519 - (void)insertTab:(Tab*)tab |
| 512 atIndex:(NSUInteger)index | 520 atIndex:(NSUInteger)index |
| 513 opener:(Tab*)parentTab | 521 opener:(Tab*)parentTab |
| 514 transition:(ui::PageTransition)transition { | 522 transition:(ui::PageTransition)transition { |
| 515 DCHECK(tab); | 523 DCHECK(tab); |
| 516 DCHECK(![_tabRetainer containsObject:tab]); | 524 DCHECK(![_tabRetainer containsObject:tab]); |
| 517 | 525 |
| 518 [_tabRetainer addObject:tab]; | 526 [_tabRetainer addObject:tab]; |
| 519 if (index == TabModelConstants::kTabPositionAutomatically) { | 527 if (index == TabModelConstants::kTabPositionAutomatically) { |
| 520 _webStateList.AppendWebState(transition, tab.webState, parentTab.webState); | 528 _webStateList->AppendWebState(transition, tab.webState, parentTab.webState); |
| 521 } else { | 529 } else { |
| 522 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); | 530 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); |
| 523 const int insertion_index = static_cast<int>(index); | 531 const int insertion_index = static_cast<int>(index); |
| 524 _webStateList.InsertWebState(insertion_index, tab.webState, | 532 _webStateList->InsertWebState(insertion_index, tab.webState, |
| 525 parentTab.webState); | 533 parentTab.webState); |
| 526 } | 534 } |
| 527 | 535 |
| 528 // Persist the session due to a new tab being inserted. If this is a | 536 // 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 | 537 // background tab (will not become active), saving now will capture the |
| 530 // state properly. If it does eventually become active, another save will | 538 // state properly. If it does eventually become active, another save will |
| 531 // be triggered to properly capture the end result. | 539 // be triggered to properly capture the end result. |
| 532 [self saveSessionImmediately:NO]; | 540 [self saveSessionImmediately:NO]; |
| 533 } | 541 } |
| 534 | 542 |
| 535 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index opener:(Tab*)parentTab { | 543 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index opener:(Tab*)parentTab { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 547 DCHECK(tab); | 555 DCHECK(tab); |
| 548 DCHECK(![_tabRetainer containsObject:tab]); | 556 DCHECK(![_tabRetainer containsObject:tab]); |
| 549 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); | 557 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); |
| 550 | 558 |
| 551 [self insertTab:tab atIndex:index opener:GetOpenerForTab(self, tab)]; | 559 [self insertTab:tab atIndex:index opener:GetOpenerForTab(self, tab)]; |
| 552 } | 560 } |
| 553 | 561 |
| 554 - (void)moveTab:(Tab*)tab toIndex:(NSUInteger)toIndex { | 562 - (void)moveTab:(Tab*)tab toIndex:(NSUInteger)toIndex { |
| 555 DCHECK([_tabRetainer containsObject:tab]); | 563 DCHECK([_tabRetainer containsObject:tab]); |
| 556 DCHECK_LE(toIndex, static_cast<NSUInteger>(INT_MAX)); | 564 DCHECK_LE(toIndex, static_cast<NSUInteger>(INT_MAX)); |
| 557 int fromIndex = _webStateList.GetIndexOfWebState(tab.webState); | 565 int fromIndex = _webStateList->GetIndexOfWebState(tab.webState); |
| 558 _webStateList.MoveWebStateAt(fromIndex, static_cast<int>(toIndex)); | 566 _webStateList->MoveWebStateAt(fromIndex, static_cast<int>(toIndex)); |
| 559 } | 567 } |
| 560 | 568 |
| 561 - (void)replaceTab:(Tab*)oldTab withTab:(Tab*)newTab { | 569 - (void)replaceTab:(Tab*)oldTab withTab:(Tab*)newTab { |
| 562 DCHECK([_tabRetainer containsObject:oldTab]); | 570 DCHECK([_tabRetainer containsObject:oldTab]); |
| 563 DCHECK(![_tabRetainer containsObject:newTab]); | 571 DCHECK(![_tabRetainer containsObject:newTab]); |
| 564 | 572 |
| 565 int index = _webStateList.GetIndexOfWebState(oldTab.webState); | 573 int index = _webStateList->GetIndexOfWebState(oldTab.webState); |
| 566 DCHECK_NE(index, WebStateList::kInvalidIndex); | 574 DCHECK_NE(index, WebStateList::kInvalidIndex); |
| 567 DCHECK_GE(index, 0); | 575 DCHECK_GE(index, 0); |
| 568 | 576 |
| 569 base::scoped_nsobject<Tab> tabSaver([oldTab retain]); | 577 base::scoped_nsobject<Tab> tabSaver([oldTab retain]); |
| 570 [_tabRetainer removeObject:oldTab]; | 578 [_tabRetainer removeObject:oldTab]; |
| 571 [_tabRetainer addObject:newTab]; | 579 [_tabRetainer addObject:newTab]; |
| 572 [newTab setParentTabModel:self]; | 580 [newTab setParentTabModel:self]; |
| 573 | 581 |
| 574 // The WebState is owned by the associated Tab, so it is safe to ignore | 582 // 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 | 583 // 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 | 584 // 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 | 585 // 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 | 586 // too. See http://crbug.com/546222 for progress of changing the ownership |
| 579 // of the WebStates. | 587 // of the WebStates. |
| 580 ignore_result(_webStateList.ReplaceWebStateAt( | 588 ignore_result(_webStateList->ReplaceWebStateAt( |
| 581 index, newTab.webState, GetOpenerForTab(self, newTab).webState)); | 589 index, newTab.webState, GetOpenerForTab(self, newTab).webState)); |
| 582 | 590 |
| 583 [oldTab setParentTabModel:nil]; | 591 [oldTab setParentTabModel:nil]; |
| 584 [oldTab close]; | 592 [oldTab close]; |
| 585 } | 593 } |
| 586 | 594 |
| 587 - (void)closeTabAtIndex:(NSUInteger)index { | 595 - (void)closeTabAtIndex:(NSUInteger)index { |
| 588 DCHECK(index < self.count); | 596 DCHECK(index < self.count); |
| 589 [self closeTab:[self tabAtIndex:index]]; | 597 [self closeTab:[self tabAtIndex:index]]; |
| 590 } | 598 } |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 694 UnregisterTabModelFromChromeBrowserState(_browserState, self); | 702 UnregisterTabModelFromChromeBrowserState(_browserState, self); |
| 695 } | 703 } |
| 696 _browserState = nullptr; | 704 _browserState = nullptr; |
| 697 } | 705 } |
| 698 | 706 |
| 699 // Called when a tab is closing, but before its CRWWebController is destroyed. | 707 // Called when a tab is closing, but before its CRWWebController is destroyed. |
| 700 // Equivalent to DetachTabContentsAt() in Chrome's TabStripModel. | 708 // Equivalent to DetachTabContentsAt() in Chrome's TabStripModel. |
| 701 - (void)didCloseTab:(Tab*)closedTab { | 709 - (void)didCloseTab:(Tab*)closedTab { |
| 702 DCHECK(closedTab); | 710 DCHECK(closedTab); |
| 703 DCHECK([_tabRetainer containsObject:closedTab]); | 711 DCHECK([_tabRetainer containsObject:closedTab]); |
| 704 int closedTabIndex = _webStateList.GetIndexOfWebState(closedTab.webState); | 712 int closedTabIndex = _webStateList->GetIndexOfWebState(closedTab.webState); |
| 705 DCHECK_NE(closedTabIndex, WebStateList::kInvalidIndex); | 713 DCHECK_NE(closedTabIndex, WebStateList::kInvalidIndex); |
| 706 DCHECK_GE(closedTabIndex, 0); | 714 DCHECK_GE(closedTabIndex, 0); |
| 707 | 715 |
| 708 // Let the sessions::TabRestoreService know about that new tab. | 716 // Let the sessions::TabRestoreService know about that new tab. |
| 709 sessions::TabRestoreService* restoreService = | 717 sessions::TabRestoreService* restoreService = |
| 710 _browserState | 718 _browserState |
| 711 ? IOSChromeTabRestoreServiceFactory::GetForBrowserState(_browserState) | 719 ? IOSChromeTabRestoreServiceFactory::GetForBrowserState(_browserState) |
| 712 : nullptr; | 720 : nullptr; |
| 713 web::NavigationManager* navigationManager = [closedTab navigationManager]; | 721 web::NavigationManager* navigationManager = [closedTab navigationManager]; |
| 714 DCHECK(navigationManager); | 722 DCHECK(navigationManager); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 727 | 735 |
| 728 DCHECK([_tabRetainer containsObject:closedTab]); | 736 DCHECK([_tabRetainer containsObject:closedTab]); |
| 729 [_tabRetainer removeObject:closedTab]; | 737 [_tabRetainer removeObject:closedTab]; |
| 730 | 738 |
| 731 // The WebState is owned by the associated Tab, so it is safe to ignore | 739 // 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 | 740 // 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 | 741 // 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 | 742 // 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 | 743 // too. See http://crbug.com/546222 for progress of changing the ownership |
| 736 // of the WebStates. | 744 // of the WebStates. |
| 737 ignore_result(_webStateList.DetachWebStateAt(closedTabIndex)); | 745 ignore_result(_webStateList->DetachWebStateAt(closedTabIndex)); |
| 738 | 746 |
| 739 if (needToSaveSession) | 747 if (needToSaveSession) |
| 740 [self saveSessionImmediately:NO]; | 748 [self saveSessionImmediately:NO]; |
| 741 } | 749 } |
| 742 | 750 |
| 743 - (void)navigationCommittedInTab:(Tab*)tab | 751 - (void)navigationCommittedInTab:(Tab*)tab |
| 744 previousItem:(web::NavigationItem*)previousItem { | 752 previousItem:(web::NavigationItem*)previousItem { |
| 745 if (self.offTheRecord) | 753 if (self.offTheRecord) |
| 746 return; | 754 return; |
| 747 if (![tab navigationManager]) | 755 if (![tab navigationManager]) |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 | 833 |
| 826 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window | 834 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window |
| 827 persistState:(BOOL)persistState { | 835 persistState:(BOOL)persistState { |
| 828 DCHECK(_browserState); | 836 DCHECK(_browserState); |
| 829 DCHECK(window); | 837 DCHECK(window); |
| 830 | 838 |
| 831 NSArray* sessions = window.sessions; | 839 NSArray* sessions = window.sessions; |
| 832 if (!sessions.count) | 840 if (!sessions.count) |
| 833 return NO; | 841 return NO; |
| 834 | 842 |
| 835 int oldCount = _webStateList.count(); | 843 int oldCount = _webStateList->count(); |
| 836 DCHECK_GE(oldCount, 0); | 844 DCHECK_GE(oldCount, 0); |
| 837 | 845 |
| 838 web::WebState::CreateParams params(_browserState); | 846 web::WebState::CreateParams params(_browserState); |
| 839 scoped_refptr<web::CertificatePolicyCache> policyCache = | 847 scoped_refptr<web::CertificatePolicyCache> policyCache = |
| 840 web::BrowserState::GetCertificatePolicyCache(_browserState); | 848 web::BrowserState::GetCertificatePolicyCache(_browserState); |
| 841 | 849 |
| 842 base::scoped_nsobject<NSMutableArray<Tab*>> restoredTabs( | 850 base::scoped_nsobject<NSMutableArray<Tab*>> restoredTabs( |
| 843 [[NSMutableArray alloc] initWithCapacity:sessions.count]); | 851 [[NSMutableArray alloc] initWithCapacity:sessions.count]); |
| 844 | 852 |
| 845 // Recreate all the restored Tabs and add them to the WebStateList without | 853 // 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 | 854 // 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. | 855 // at an index larger than n). Then in a second pass fix the openers. |
| 848 for (CRWSessionStorage* session in sessions) { | 856 for (CRWSessionStorage* session in sessions) { |
| 849 std::unique_ptr<web::WebState> webState = | 857 std::unique_ptr<web::WebState> webState = |
| 850 web::WebState::Create(params, session); | 858 web::WebState::Create(params, session); |
| 851 base::scoped_nsobject<Tab> tab( | 859 base::scoped_nsobject<Tab> tab( |
| 852 [[Tab alloc] initWithWebState:std::move(webState) model:self]); | 860 [[Tab alloc] initWithWebState:std::move(webState) model:self]); |
| 853 [tab webController].webUsageEnabled = webUsageEnabled_; | 861 [tab webController].webUsageEnabled = webUsageEnabled_; |
| 854 [tab webController].usePlaceholderOverlay = YES; | 862 [tab webController].usePlaceholderOverlay = YES; |
| 855 | 863 |
| 856 // Restore the CertificatePolicyCache (note that webState is invalid after | 864 // Restore the CertificatePolicyCache (note that webState is invalid after |
| 857 // passing it via move semantic to -initWithWebState:model:). | 865 // passing it via move semantic to -initWithWebState:model:). |
| 858 UpdateCertificatePolicyCacheFromWebState(policyCache, [tab webState]); | 866 UpdateCertificatePolicyCacheFromWebState(policyCache, [tab webState]); |
| 859 [self insertTab:tab atIndex:self.count opener:nil]; | 867 [self insertTab:tab atIndex:self.count opener:nil]; |
| 860 [restoredTabs addObject:tab.get()]; | 868 [restoredTabs addObject:tab.get()]; |
| 861 } | 869 } |
| 862 | 870 |
| 863 DCHECK_EQ(sessions.count, [restoredTabs count]); | 871 DCHECK_EQ(sessions.count, [restoredTabs count]); |
| 864 DCHECK_GT(_webStateList.count(), oldCount); | 872 DCHECK_GT(_webStateList->count(), oldCount); |
| 865 | 873 |
| 866 // Fix openers now that all Tabs have been restored. Only look for an opener | 874 // 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. | 875 // Tab in the newly restored Tabs and not in the already open Tabs. |
| 868 for (int index = oldCount; index < _webStateList.count(); ++index) { | 876 for (int index = oldCount; index < _webStateList->count(); ++index) { |
| 869 DCHECK_GE(index, oldCount); | 877 DCHECK_GE(index, oldCount); |
| 870 NSUInteger tabIndex = static_cast<NSUInteger>(index - oldCount); | 878 NSUInteger tabIndex = static_cast<NSUInteger>(index - oldCount); |
| 871 Tab* tab = [restoredTabs objectAtIndex:tabIndex]; | 879 Tab* tab = [restoredTabs objectAtIndex:tabIndex]; |
| 872 Tab* opener = GetOpenerForTab(restoredTabs.get(), tab); | 880 Tab* opener = GetOpenerForTab(restoredTabs.get(), tab); |
| 873 if (opener) { | 881 if (opener) { |
| 874 DCHECK(opener.webState); | 882 DCHECK(opener.webState); |
| 875 _webStateList.SetOpenerOfWebStateAt(index, opener.webState); | 883 _webStateList->SetOpenerOfWebStateAt(index, opener.webState); |
| 876 } | 884 } |
| 877 } | 885 } |
| 878 | 886 |
| 879 // Update the selected tab if there was a selected Tab in the saved session. | 887 // Update the selected tab if there was a selected Tab in the saved session. |
| 880 if (window.selectedIndex != NSNotFound) { | 888 if (window.selectedIndex != NSNotFound) { |
| 881 NSUInteger selectedIndex = window.selectedIndex + oldCount; | 889 NSUInteger selectedIndex = window.selectedIndex + oldCount; |
| 882 DCHECK_LT(selectedIndex, self.count); | 890 DCHECK_LT(selectedIndex, self.count); |
| 883 DCHECK([self tabAtIndex:selectedIndex]); | 891 DCHECK([self tabAtIndex:selectedIndex]); |
| 884 | 892 |
| 885 if (persistState && self.currentTab) | 893 if (persistState && self.currentTab) |
| 886 [self.currentTab recordStateInHistory]; | 894 [self.currentTab recordStateInHistory]; |
| 887 _webStateList.ActivateWebStateAt(static_cast<int>(selectedIndex)); | 895 _webStateList->ActivateWebStateAt(static_cast<int>(selectedIndex)); |
| 888 } | 896 } |
| 889 | 897 |
| 890 // If there was only one tab and it was the new tab page, clobber it. | 898 // If there was only one tab and it was the new tab page, clobber it. |
| 891 BOOL closedNTPTab = NO; | 899 BOOL closedNTPTab = NO; |
| 892 if (oldCount == 1) { | 900 if (oldCount == 1) { |
| 893 Tab* tab = [self tabAtIndex:0]; | 901 Tab* tab = [self tabAtIndex:0]; |
| 894 if (tab.url == GURL(kChromeUINewTabURL)) { | 902 if (tab.url == GURL(kChromeUINewTabURL)) { |
| 895 [self closeTab:tab]; | 903 [self closeTab:tab]; |
| 896 closedNTPTab = YES; | 904 closedNTPTab = YES; |
| 897 oldCount = 0; | 905 oldCount = 0; |
| 898 } | 906 } |
| 899 } | 907 } |
| 900 if (_tabUsageRecorder) { | 908 if (_tabUsageRecorder) { |
| 901 NSMutableArray<Tab*>* restoredTabs = | 909 NSMutableArray<Tab*>* restoredTabs = |
| 902 [NSMutableArray arrayWithCapacity:_webStateList.count() - oldCount]; | 910 [NSMutableArray arrayWithCapacity:_webStateList->count() - oldCount]; |
| 903 for (int index = oldCount; index < _webStateList.count(); ++index) { | 911 for (int index = oldCount; index < _webStateList->count(); ++index) { |
| 904 web::WebState* webState = _webStateList.GetWebStateAt(index); | 912 web::WebState* webState = _webStateList->GetWebStateAt(index); |
| 905 [restoredTabs addObject:LegacyTabHelper::GetTabForWebState(webState)]; | 913 [restoredTabs addObject:LegacyTabHelper::GetTabForWebState(webState)]; |
| 906 } | 914 } |
| 907 _tabUsageRecorder->InitialRestoredTabs(self.currentTab, restoredTabs); | 915 _tabUsageRecorder->InitialRestoredTabs(self.currentTab, restoredTabs); |
| 908 } | 916 } |
| 909 return closedNTPTab; | 917 return closedNTPTab; |
| 910 } | 918 } |
| 911 | 919 |
| 912 #pragma mark - Notification Handlers | 920 #pragma mark - Notification Handlers |
| 913 | 921 |
| 914 // Called when UIApplicationWillResignActiveNotification is received. | 922 // Called when UIApplicationWillResignActiveNotification is received. |
| 915 - (void)willResignActive:(NSNotification*)notify { | 923 - (void)willResignActive:(NSNotification*)notify { |
| 916 if (webUsageEnabled_ && self.currentTab) { | 924 if (webUsageEnabled_ && self.currentTab) { |
| 917 [[SnapshotCache sharedInstance] | 925 [[SnapshotCache sharedInstance] |
| 918 willBeSavedGreyWhenBackgrounding:self.currentTab.tabId]; | 926 willBeSavedGreyWhenBackgrounding:self.currentTab.tabId]; |
| 919 } | 927 } |
| 920 } | 928 } |
| 921 | 929 |
| 922 // Called when UIApplicationDidEnterBackgroundNotification is received. | 930 // Called when UIApplicationDidEnterBackgroundNotification is received. |
| 923 - (void)applicationDidEnterBackground:(NSNotification*)notify { | 931 - (void)applicationDidEnterBackground:(NSNotification*)notify { |
| 924 if (!_browserState) | 932 if (!_browserState) |
| 925 return; | 933 return; |
| 926 | 934 |
| 927 // Evict all the certificate policies except for the current entries of the | 935 // Evict all the certificate policies except for the current entries of the |
| 928 // active sessions. | 936 // active sessions. |
| 929 CleanCertificatePolicyCache( | 937 CleanCertificatePolicyCache( |
| 930 &_clearPoliciesTaskTracker, | 938 &_clearPoliciesTaskTracker, |
| 931 web::WebThread::GetTaskRunnerForThread(web::WebThread::IO), | 939 web::WebThread::GetTaskRunnerForThread(web::WebThread::IO), |
| 932 web::BrowserState::GetCertificatePolicyCache(_browserState), | 940 web::BrowserState::GetCertificatePolicyCache(_browserState), |
| 933 &_webStateList); | 941 _webStateList.get()); |
| 934 | 942 |
| 935 if (_tabUsageRecorder) | 943 if (_tabUsageRecorder) |
| 936 _tabUsageRecorder->AppDidEnterBackground(); | 944 _tabUsageRecorder->AppDidEnterBackground(); |
| 937 | 945 |
| 938 // Normally, the session is saved after some timer expires but since the app | 946 // 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. | 947 // is about to enter the background send YES to save the session immediately. |
| 940 [self saveSessionImmediately:YES]; | 948 [self saveSessionImmediately:YES]; |
| 941 | 949 |
| 942 // Write out a grey version of the current website to disk. | 950 // Write out a grey version of the current website to disk. |
| 943 if (webUsageEnabled_ && self.currentTab) { | 951 if (webUsageEnabled_ && self.currentTab) { |
| 944 [[SnapshotCache sharedInstance] | 952 [[SnapshotCache sharedInstance] |
| 945 saveGreyInBackgroundForSessionID:self.currentTab.tabId]; | 953 saveGreyInBackgroundForSessionID:self.currentTab.tabId]; |
| 946 } | 954 } |
| 947 } | 955 } |
| 948 | 956 |
| 949 // Called when UIApplicationWillEnterForegroundNotification is received. | 957 // Called when UIApplicationWillEnterForegroundNotification is received. |
| 950 - (void)applicationWillEnterForeground:(NSNotification*)notify { | 958 - (void)applicationWillEnterForeground:(NSNotification*)notify { |
| 951 if (_tabUsageRecorder) { | 959 if (_tabUsageRecorder) { |
| 952 _tabUsageRecorder->AppWillEnterForeground(); | 960 _tabUsageRecorder->AppWillEnterForeground(); |
| 953 } | 961 } |
| 954 } | 962 } |
| 955 | 963 |
| 956 @end | 964 @end |
| OLD | NEW |