| Index: ios/chrome/browser/tabs/tab_model.mm
|
| diff --git a/ios/chrome/browser/tabs/tab_model.mm b/ios/chrome/browser/tabs/tab_model.mm
|
| index c9799c0721c30102ab1d53e2f204d053cc2c7a69..65d18358c971db75aebe3552ece1f4bbf88df1a3 100644
|
| --- a/ios/chrome/browser/tabs/tab_model.mm
|
| +++ b/ios/chrome/browser/tabs/tab_model.mm
|
| @@ -33,11 +33,14 @@
|
| #import "ios/chrome/browser/tabs/tab.h"
|
| #import "ios/chrome/browser/tabs/tab_model_list.h"
|
| #import "ios/chrome/browser/tabs/tab_model_observers.h"
|
| +#import "ios/chrome/browser/tabs/tab_model_observers_bridge.h"
|
| #import "ios/chrome/browser/tabs/tab_model_order_controller.h"
|
| #import "ios/chrome/browser/tabs/tab_model_synced_window_delegate.h"
|
| +#import "ios/chrome/browser/tabs/tab_parenting_observer.h"
|
| #import "ios/chrome/browser/xcallback_parameters.h"
|
| #import "ios/shared/chrome/browser/tabs/web_state_list.h"
|
| #import "ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper.h"
|
| +#import "ios/shared/chrome/browser/tabs/web_state_list_metrics_observer.h"
|
| #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h"
|
| #import "ios/web/navigation/crw_session_certificate_policy_manager.h"
|
| #import "ios/web/navigation/crw_session_controller.h"
|
| @@ -140,6 +143,10 @@ void CleanCertificatePolicyCache(
|
| // WebState owns the associated Tab.
|
| base::scoped_nsobject<NSMutableSet<Tab*>> _tabRetainer;
|
|
|
| + // WebStateListObserver bridges to react to modifications of the model (may
|
| + // send notification, translate and forward events, update metrics, ...).
|
| + std::vector<std::unique_ptr<WebStateListObserver>> _observerBridges;
|
| +
|
| // Maintains policy for where new tabs go and the selection when a tab
|
| // is removed.
|
| base::scoped_nsobject<TabModelOrderController> _orderController;
|
| @@ -226,6 +233,12 @@ void CleanCertificatePolicyCache(
|
| DCHECK(!_browserState);
|
|
|
| [[NSNotificationCenter defaultCenter] removeObserver:self];
|
| +
|
| + // Unregister all listeners before closing all the tabs.
|
| + for (const auto& observerBridge : _observerBridges)
|
| + _webStateList.RemoveObserver(observerBridge.get());
|
| + _observerBridges.clear();
|
| +
|
| // Make sure the tabs do clean after themselves. It is important for
|
| // removeObserver: to be called first otherwise a lot of unecessary work will
|
| // happen on -closeAllTabs.
|
| @@ -286,6 +299,14 @@ void CleanCertificatePolicyCache(
|
| initWithWebStateList:&_webStateList
|
| proxyFactory:[[TabModelWebStateProxyFactory alloc] init]]);
|
|
|
| + _observerBridges.push_back(base::MakeUnique<TabParentingObserver>());
|
| + _observerBridges.push_back(base::MakeUnique<WebStateListObserverBridge>(
|
| + [[TabModelObserversBridge alloc] initWithTabModel:self
|
| + tabModelObservers:_observers.get()]));
|
| + _observerBridges.push_back(base::MakeUnique<WebStateListMetricsObserver>());
|
| + for (const auto& observerBridge : _observerBridges)
|
| + _webStateList.AddObserver(observerBridge.get());
|
| +
|
| _browserState = browserState;
|
| DCHECK(_browserState);
|
|
|
| @@ -536,15 +557,10 @@ void CleanCertificatePolicyCache(
|
| DCHECK(tab);
|
| DCHECK(![_tabRetainer containsObject:tab]);
|
| DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX));
|
| - [tab fetchFavicon];
|
|
|
| [_tabRetainer addObject:tab];
|
| _webStateList.InsertWebState(static_cast<int>(index), tab.webState);
|
| - TabParentingGlobalObserver::GetInstance()->OnTabParented(tab.webState);
|
| - [_observers tabModel:self didInsertTab:tab atIndex:index inForeground:NO];
|
| - [_observers tabModelDidChangeTabCount:self];
|
|
|
| - base::RecordAction(base::UserMetricsAction("MobileNewTabOpened"));
|
| // Persist the session due to a new tab being inserted. If this is a
|
| // background tab (will not become active), saving now will capture the
|
| // state properly. If it does eventually become active, another save will
|
| @@ -555,14 +571,10 @@ void CleanCertificatePolicyCache(
|
| }
|
|
|
| - (void)moveTab:(Tab*)tab toIndex:(NSUInteger)toIndex {
|
| - if ([self tabAtIndex:toIndex] == tab)
|
| - return;
|
| -
|
| DCHECK([_tabRetainer containsObject:tab]);
|
| DCHECK_LE(toIndex, static_cast<NSUInteger>(INT_MAX));
|
| int fromIndex = _webStateList.GetIndexOfWebState(tab.webState);
|
| _webStateList.MoveWebStateAt(fromIndex, static_cast<int>(toIndex));
|
| - [_observers tabModel:self didMoveTab:tab fromIndex:fromIndex toIndex:toIndex];
|
| }
|
|
|
| - (void)replaceTab:(Tab*)oldTab withTab:(Tab*)newTab {
|
| @@ -574,27 +586,17 @@ void CleanCertificatePolicyCache(
|
| DCHECK_GE(index, 0);
|
|
|
| base::scoped_nsobject<Tab> tabSaver([oldTab retain]);
|
| - [newTab fetchFavicon];
|
| [_tabRetainer removeObject:oldTab];
|
| [_tabRetainer addObject:newTab];
|
| [newTab setParentTabModel:self];
|
|
|
| _webStateList.ReplaceWebStateAt(index, newTab.webState);
|
| - TabParentingGlobalObserver::GetInstance()->OnTabParented(newTab.webState);
|
| - [_observers tabModel:self
|
| - didReplaceTab:oldTab
|
| - withTab:newTab
|
| - atIndex:static_cast<NSUInteger>(index)];
|
|
|
| if (self.currentTab == oldTab)
|
| [self changeSelectedTabFrom:nil to:newTab persistState:NO];
|
|
|
| [oldTab setParentTabModel:nil];
|
| [oldTab close];
|
| -
|
| - // Record a tab clobber, since swapping tabs bypasses the tab code that would
|
| - // normally log clobbers.
|
| - base::RecordAction(base::UserMetricsAction("MobileTabClobbered"));
|
| }
|
|
|
| - (void)closeTabAtIndex:(NSUInteger)index {
|
| @@ -753,10 +755,6 @@ void CleanCertificatePolicyCache(
|
| [_tabRetainer removeObject:closedTab];
|
|
|
| _webStateList.DetachWebStateAt(closedTabIndex);
|
| - [_observers tabModel:self
|
| - didRemoveTab:closedTab
|
| - atIndex:static_cast<NSUInteger>(closedTabIndex)];
|
| - [_observers tabModelDidChangeTabCount:self];
|
|
|
| // Current tab has closed, update the selected tab and swap in its
|
| // contents. There is nothing to do if a non-selected tab is closed as
|
| @@ -768,7 +766,6 @@ void CleanCertificatePolicyCache(
|
| } else {
|
| [self saveSessionImmediately:NO];
|
| }
|
| - base::RecordAction(base::UserMetricsAction("MobileTabClosed"));
|
| ++_closedTabCount;
|
| }
|
|
|
|
|