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

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

Issue 2687303003: Convert some of TabModel logic to WebStateListObservers. (Closed)
Patch Set: 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
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 13 matching lines...) Expand all
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/legacy_tab_helper.h"
32 #import "ios/chrome/browser/tabs/tab.h" 32 #import "ios/chrome/browser/tabs/tab.h"
33 #import "ios/chrome/browser/tabs/tab_model_list.h" 33 #import "ios/chrome/browser/tabs/tab_model_list.h"
34 #import "ios/chrome/browser/tabs/tab_model_metrics_observer.h"
34 #import "ios/chrome/browser/tabs/tab_model_observers.h" 35 #import "ios/chrome/browser/tabs/tab_model_observers.h"
35 #import "ios/chrome/browser/tabs/tab_model_order_controller.h" 36 #import "ios/chrome/browser/tabs/tab_model_order_controller.h"
36 #import "ios/chrome/browser/tabs/tab_model_synced_window_delegate.h" 37 #import "ios/chrome/browser/tabs/tab_model_synced_window_delegate.h"
38 #import "ios/chrome/browser/tabs/tab_model_tab_model_observers_bridge.h"
39 #import "ios/chrome/browser/tabs/tab_model_tab_parenting_observer.h"
37 #import "ios/chrome/browser/xcallback_parameters.h" 40 #import "ios/chrome/browser/xcallback_parameters.h"
38 #import "ios/shared/chrome/browser/tabs/web_state_list.h" 41 #import "ios/shared/chrome/browser/tabs/web_state_list.h"
39 #import "ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper.h " 42 #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" 43 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h"
41 #import "ios/web/navigation/crw_session_certificate_policy_manager.h" 44 #import "ios/web/navigation/crw_session_certificate_policy_manager.h"
42 #import "ios/web/navigation/crw_session_controller.h" 45 #import "ios/web/navigation/crw_session_controller.h"
43 #include "ios/web/public/browser_state.h" 46 #include "ios/web/public/browser_state.h"
44 #include "ios/web/public/certificate_policy_cache.h" 47 #include "ios/web/public/certificate_policy_cache.h"
45 #include "ios/web/public/navigation_item.h" 48 #include "ios/web/public/navigation_item.h"
46 #import "ios/web/public/navigation_manager.h" 49 #import "ios/web/public/navigation_manager.h"
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 124
122 // Helper providing NSFastEnumeration implementation over the WebStateList. 125 // Helper providing NSFastEnumeration implementation over the WebStateList.
123 base::scoped_nsobject<WebStateListFastEnumerationHelper> 126 base::scoped_nsobject<WebStateListFastEnumerationHelper>
124 _fastEnumerationHelper; 127 _fastEnumerationHelper;
125 128
126 // Used to keep the Tabs alive while the corresponding WebStates are stored 129 // Used to keep the Tabs alive while the corresponding WebStates are stored
127 // in the WebStateList (as Tabs currently owns their WebState). Remove once 130 // in the WebStateList (as Tabs currently owns their WebState). Remove once
128 // WebState owns the associated Tab. 131 // WebState owns the associated Tab.
129 base::scoped_nsobject<NSMutableSet<Tab*>> _tabs; 132 base::scoped_nsobject<NSMutableSet<Tab*>> _tabs;
130 133
134 // WebStateListObserver bridges to react to modifications of the model (may
135 // send notification, translate and forward events, update metrics, ...).
136 std::vector<std::unique_ptr<WebStateListObserver>> _observerBridges;
137
131 // Maintains policy for where new tabs go and the selection when a tab 138 // Maintains policy for where new tabs go and the selection when a tab
132 // is removed. 139 // is removed.
133 base::scoped_nsobject<TabModelOrderController> _orderController; 140 base::scoped_nsobject<TabModelOrderController> _orderController;
134 // The delegate for sync. 141 // The delegate for sync.
135 std::unique_ptr<TabModelSyncedWindowDelegate> _syncedWindowDelegate; 142 std::unique_ptr<TabModelSyncedWindowDelegate> _syncedWindowDelegate;
136 // Currently selected tab. May be nil. 143 // Currently selected tab. May be nil.
137 base::WeakNSObject<Tab> _currentTab; 144 base::WeakNSObject<Tab> _currentTab;
138 145
139 // Counters for metrics. 146 // Counters for metrics.
140 int _openedTabCount; 147 int _openedTabCount;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 @synthesize webUsageEnabled = webUsageEnabled_; 214 @synthesize webUsageEnabled = webUsageEnabled_;
208 215
209 #pragma mark - Overriden 216 #pragma mark - Overriden
210 217
211 - (void)dealloc { 218 - (void)dealloc {
212 DCHECK([_observers empty]); 219 DCHECK([_observers empty]);
213 // browserStateDestroyed should always have been called before destruction. 220 // browserStateDestroyed should always have been called before destruction.
214 DCHECK(!_browserState); 221 DCHECK(!_browserState);
215 222
216 [[NSNotificationCenter defaultCenter] removeObserver:self]; 223 [[NSNotificationCenter defaultCenter] removeObserver:self];
224
225 // Unregister all listeners before closing all the tabs.
226 for (const auto& observerBridge : _observerBridges)
227 _webStateList.RemoveObserver(observerBridge.get());
228 _observerBridges.clear();
229
217 // Make sure the tabs do clean after themselves. It is important for 230 // Make sure the tabs do clean after themselves. It is important for
218 // removeObserver: to be called first otherwise a lot of unecessary work will 231 // removeObserver: to be called first otherwise a lot of unecessary work will
219 // happen on -closeAllTabs. 232 // happen on -closeAllTabs.
220 [self closeAllTabs]; 233 [self closeAllTabs];
221 234
222 _clearPoliciesTaskTracker.TryCancelAll(); 235 _clearPoliciesTaskTracker.TryCancelAll();
223 236
224 [super dealloc]; 237 [super dealloc];
225 } 238 }
226 239
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 sessionService:(SessionServiceIOS*)service 279 sessionService:(SessionServiceIOS*)service
267 browserState:(ios::ChromeBrowserState*)browserState { 280 browserState:(ios::ChromeBrowserState*)browserState {
268 if ((self = [super init])) { 281 if ((self = [super init])) {
269 _tabs.reset([[NSMutableSet alloc] init]); 282 _tabs.reset([[NSMutableSet alloc] init]);
270 _observers.reset([[TabModelObservers observers] retain]); 283 _observers.reset([[TabModelObservers observers] retain]);
271 284
272 _fastEnumerationHelper.reset([[WebStateListFastEnumerationHelper alloc] 285 _fastEnumerationHelper.reset([[WebStateListFastEnumerationHelper alloc]
273 initWithWebStateList:&_webStateList 286 initWithWebStateList:&_webStateList
274 proxyFactory:self]); 287 proxyFactory:self]);
275 288
289 _observerBridges.push_back(base::MakeUnique<WebStateListObserverBridge>(
290 [[TabModelTabParentingObserver alloc] init]));
291 _observerBridges.push_back(base::MakeUnique<WebStateListObserverBridge>(
292 [[TabModelTabModelObserversBridge alloc]
293 initWithTabModel:self
294 tabModelObservers:_observers.get()]));
295 _observerBridges.push_back(base::MakeUnique<WebStateListObserverBridge>(
296 [[TabModelMetricsObserver alloc] init]));
297 for (const auto& observerBridge : _observerBridges)
298 _webStateList.AddObserver(observerBridge.get());
299
276 _browserState = browserState; 300 _browserState = browserState;
277 DCHECK(_browserState); 301 DCHECK(_browserState);
278 302
279 // There must be a valid session service defined to consume session windows. 303 // There must be a valid session service defined to consume session windows.
280 DCHECK(service); 304 DCHECK(service);
281 _sessionService.reset([service retain]); 305 _sessionService.reset([service retain]);
282 306
283 // 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
284 // handles incognito browser states by filtering on profile, so it's 308 // handles incognito browser states by filtering on profile, so it's
285 // 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.
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 base::scoped_nsobject<Tab> tab( 561 base::scoped_nsobject<Tab> tab(
538 [[Tab alloc] initWithWebState:std::move(webState) model:self]); 562 [[Tab alloc] initWithWebState:std::move(webState) model:self]);
539 [tab webController].webUsageEnabled = webUsageEnabled_; 563 [tab webController].webUsageEnabled = webUsageEnabled_;
540 [self insertTab:tab atIndex:index]; 564 [self insertTab:tab atIndex:index];
541 return tab; 565 return tab;
542 } 566 }
543 567
544 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index { 568 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index {
545 DCHECK(tab); 569 DCHECK(tab);
546 DCHECK(![_tabs containsObject:tab]); 570 DCHECK(![_tabs containsObject:tab]);
547 [tab fetchFavicon];
marq (ping after 24h) 2017/02/13 17:06:54 Any idea why [tab setParentTabModel:self] isn't ca
sdefresne 2017/02/13 17:13:39 Yes, this is because this method is only ever call
548 571
549 [_tabs addObject:tab]; 572 [_tabs addObject:tab];
550 _webStateList.InsertWebState(index, tab.webState); 573 _webStateList.InsertWebState(index, tab.webState);
551 TabParentingGlobalObserver::GetInstance()->OnTabParented(tab.webState);
552 [_observers tabModel:self didInsertTab:tab atIndex:index inForeground:NO];
553 [_observers tabModelDidChangeTabCount:self];
554 574
555 base::RecordAction(base::UserMetricsAction("MobileNewTabOpened"));
556 // Persist the session due to a new tab being inserted. If this is a 575 // Persist the session due to a new tab being inserted. If this is a
557 // background tab (will not become active), saving now will capture the 576 // background tab (will not become active), saving now will capture the
558 // state properly. If it does eventually become active, another save will 577 // state properly. If it does eventually become active, another save will
559 // be triggered to properly capture the end result. 578 // be triggered to properly capture the end result.
560 [self saveSessionImmediately:NO]; 579 [self saveSessionImmediately:NO];
561 580
562 ++_newTabCount; 581 ++_newTabCount;
563 } 582 }
564 583
565 - (void)moveTab:(Tab*)tab toIndex:(NSUInteger)toIndex { 584 - (void)moveTab:(Tab*)tab toIndex:(NSUInteger)toIndex {
566 size_t fromIndex = _webStateList.GetIndexOfWebState(tab.webState); 585 size_t fromIndex = _webStateList.GetIndexOfWebState(tab.webState);
567 _webStateList.MoveWebStateAt(fromIndex, toIndex); 586 _webStateList.MoveWebStateAt(fromIndex, toIndex);
568 [_observers tabModel:self didMoveTab:tab fromIndex:fromIndex toIndex:toIndex];
569 } 587 }
570 588
571 - (void)replaceTab:(Tab*)oldTab withTab:(Tab*)newTab { 589 - (void)replaceTab:(Tab*)oldTab withTab:(Tab*)newTab {
572 NSUInteger index = [self indexOfTab:oldTab]; 590 NSUInteger index = [self indexOfTab:oldTab];
573 DCHECK_NE(NSNotFound, static_cast<NSInteger>(index)); 591 DCHECK_NE(NSNotFound, static_cast<NSInteger>(index));
592
574 DCHECK([_tabs containsObject:oldTab]); 593 DCHECK([_tabs containsObject:oldTab]);
575 DCHECK(![_tabs containsObject:newTab]); 594 DCHECK(![_tabs containsObject:newTab]);
576 595
577 base::scoped_nsobject<Tab> tabSaver([oldTab retain]); 596 base::scoped_nsobject<Tab> tabSaver([oldTab retain]);
578 [newTab fetchFavicon];
579 [_tabs removeObject:oldTab]; 597 [_tabs removeObject:oldTab];
580 [_tabs addObject:newTab]; 598 [_tabs addObject:newTab];
581 [newTab setParentTabModel:self]; 599 [newTab setParentTabModel:self];
582 600
583 _webStateList.ReplaceWebStateAt(index, newTab.webState); 601 _webStateList.ReplaceWebStateAt(index, newTab.webState);
584 TabParentingGlobalObserver::GetInstance()->OnTabParented(newTab.webState);
585 [_observers tabModel:self didReplaceTab:oldTab withTab:newTab atIndex:index];
586 602
587 if (self.currentTab == oldTab) 603 if (self.currentTab == oldTab)
588 [self changeSelectedTabFrom:nil to:newTab persistState:NO]; 604 [self changeSelectedTabFrom:nil to:newTab persistState:NO];
589 605
590 [oldTab setParentTabModel:nil]; 606 [oldTab setParentTabModel:nil];
591 [oldTab close]; 607 [oldTab close];
592
593 // Record a tab clobber, since swapping tabs bypasses the tab code that would
594 // normally log clobbers.
595 base::RecordAction(base::UserMetricsAction("MobileTabClobbered"));
596 } 608 }
597 609
598 - (void)closeTabAtIndex:(NSUInteger)index { 610 - (void)closeTabAtIndex:(NSUInteger)index {
599 DCHECK(index < _webStateList.count()); 611 DCHECK(index < _webStateList.count());
600 [self closeTab:[self tabAtIndex:index]]; 612 [self closeTab:[self tabAtIndex:index]];
601 } 613 }
602 614
603 - (void)closeTab:(Tab*)tab { 615 - (void)closeTab:(Tab*)tab {
604 // Ensure the tab stays alive long enough for us to send out the 616 // Ensure the tab stays alive long enough for us to send out the
605 // notice of its destruction to the delegate. 617 // notice of its destruction to the delegate.
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 // notification. This avoids various parts of the code getting confused 753 // notification. This avoids various parts of the code getting confused
742 // when the current tab isn't in the tab model. 754 // when the current tab isn't in the tab model.
743 Tab* savedCurrentTab = _currentTab; 755 Tab* savedCurrentTab = _currentTab;
744 if (closedTab == _currentTab) 756 if (closedTab == _currentTab)
745 _currentTab.reset(nil); 757 _currentTab.reset(nil);
746 758
747 DCHECK([_tabs containsObject:closedTab]); 759 DCHECK([_tabs containsObject:closedTab]);
748 [_tabs removeObject:closedTab]; 760 [_tabs removeObject:closedTab];
749 761
750 _webStateList.RemoveWebStateAt(closedTabIndex); 762 _webStateList.RemoveWebStateAt(closedTabIndex);
751 [_observers tabModel:self didRemoveTab:closedTab atIndex:closedTabIndex];
752 [_observers tabModelDidChangeTabCount:self];
753 763
754 // Current tab has closed, update the selected tab and swap in its 764 // Current tab has closed, update the selected tab and swap in its
755 // contents. There is nothing to do if a non-selected tab is closed as 765 // contents. There is nothing to do if a non-selected tab is closed as
756 // the selection isn't index-based, therefore it hasn't changed. 766 // the selection isn't index-based, therefore it hasn't changed.
757 // -changeSelectedTabFrom: will persist the state change, so only do it 767 // -changeSelectedTabFrom: will persist the state change, so only do it
758 // if the selection isn't changing. 768 // if the selection isn't changing.
759 if (closedTab == savedCurrentTab) { 769 if (closedTab == savedCurrentTab) {
760 [self changeSelectedTabFrom:closedTab to:newSelection persistState:NO]; 770 [self changeSelectedTabFrom:closedTab to:newSelection persistState:NO];
761 } else { 771 } else {
762 [self saveSessionImmediately:NO]; 772 [self saveSessionImmediately:NO];
763 } 773 }
764 base::RecordAction(base::UserMetricsAction("MobileTabClosed"));
765 ++_closedTabCount; 774 ++_closedTabCount;
766 } 775 }
767 776
768 - (void)navigationCommittedInTab:(Tab*)tab { 777 - (void)navigationCommittedInTab:(Tab*)tab {
769 if (self.offTheRecord) 778 if (self.offTheRecord)
770 return; 779 return;
771 if (![tab navigationManager]) 780 if (![tab navigationManager])
772 return; 781 return;
773 782
774 // See if the navigation was within a page; if so ignore it. 783 // See if the navigation was within a page; if so ignore it.
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 web::NavigationManager::WebLoadParams params(URL); 1113 web::NavigationManager::WebLoadParams params(URL);
1105 params.referrer = referrer; 1114 params.referrer = referrer;
1106 params.transition_type = ui::PAGE_TRANSITION_TYPED; 1115 params.transition_type = ui::PAGE_TRANSITION_TYPED;
1107 [[tab webController] loadWithParams:params]; 1116 [[tab webController] loadWithParams:params];
1108 [tab webController].webUsageEnabled = webUsageEnabled_; 1117 [tab webController].webUsageEnabled = webUsageEnabled_;
1109 [self insertTab:tab atIndex:index]; 1118 [self insertTab:tab atIndex:index];
1110 return tab; 1119 return tab;
1111 } 1120 }
1112 1121
1113 @end 1122 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698