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

Unified Diff: ios/chrome/browser/tabs/tab_model.mm

Issue 2640093004: WebStateList is an array of web::WebState* wrappers. (Closed)
Patch Set: Fix leaks (caught by unit tests). Created 3 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ios/chrome/browser/tabs/tab_model.h ('k') | ios/chrome/browser/tabs/tab_model_unittest.mm » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 aa4cd9a93b6ded6d85a11f2ac00b0feecfecdb49..2edb40ac8b26fc78dc2cad12a4393a7a59ed5704 100644
--- a/ios/chrome/browser/tabs/tab_model.mm
+++ b/ios/chrome/browser/tabs/tab_model.mm
@@ -66,23 +66,24 @@ NSString* const kTabModelOpenInBackgroundKey = @"shouldOpenInBackground";
namespace {
// Updates CRWSessionCertificatePolicyManager's certificate policy cache.
-void UpdateCertificatePolicyCacheFromWebState(web::WebStateImpl* webState) {
+void UpdateCertificatePolicyCacheFromWebState(web::WebStateImpl* web_state) {
DCHECK([NSThread isMainThread]);
- DCHECK(webState);
+ DCHECK(web_state);
scoped_refptr<web::CertificatePolicyCache> policy_cache =
- web::BrowserState::GetCertificatePolicyCache(webState->GetBrowserState());
+ web::BrowserState::GetCertificatePolicyCache(
+ web_state->GetBrowserState());
CRWSessionController* controller =
- webState->GetNavigationManagerImpl().GetSessionController();
+ web_state->GetNavigationManagerImpl().GetSessionController();
[[controller sessionCertificatePolicyManager]
updateCertificatePolicyCache:policy_cache];
}
// Populates the certificate policy cache based on the current entries of the
// given tabs.
-void RestoreCertificatePolicyCacheFromTabs(NSArray* tabs) {
+void RestoreCertificatePolicyCacheFromTabs(WebStateList* web_state_list) {
DCHECK([NSThread isMainThread]);
- for (Tab* tab in tabs) {
- UpdateCertificatePolicyCacheFromWebState(tab.webStateImpl);
+ for (id<WebStateHandle> web_state in web_state_list) {
+ UpdateCertificatePolicyCacheFromWebState(web_state.webStateImpl);
}
}
@@ -90,13 +91,29 @@ void RestoreCertificatePolicyCacheFromTabs(NSArray* tabs) {
// those for the current entries of the given tabs.
void CleanCertificatePolicyCache(
scoped_refptr<web::CertificatePolicyCache> policy_cache,
- NSArray* tabs) {
+ WebStateList* web_state_list) {
DCHECK_CURRENTLY_ON(web::WebThread::IO);
DCHECK(policy_cache);
policy_cache->ClearCertificatePolicies();
web::WebThread::PostTask(
web::WebThread::UI, FROM_HERE,
- base::Bind(&RestoreCertificatePolicyCacheFromTabs, tabs));
+ base::Bind(&RestoreCertificatePolicyCacheFromTabs, web_state_list));
+}
+
+// Creates a NSArray<Tab*>* with elements from |web_state_list| falling into
+// |range|. This is for compatibility with TabUsageRecorder existing API. That
+// API will be refactored in later CL and this method removed, see
+// http://crbug.com/681867 for details.
+NSArray<Tab*>* GetTabsFromWebStateList(WebStateList* web_state_list,
+ NSRange range) {
+ base::scoped_nsobject<NSMutableArray<Tab*>> mutableArray(
+ [[NSMutableArray alloc] initWithCapacity:range.length]);
+
+ for (NSUInteger ii = range.location; NSLocationInRange(ii, range); ++ii) {
+ [mutableArray addObject:[web_state_list webStateAtIndex:ii]];
+ }
+
+ return [[mutableArray copy] autorelease];
}
} // anonymous namespace
@@ -107,8 +124,6 @@ void CleanCertificatePolicyCache(
@end
@interface TabModel ()<TabUsageRecorderDelegate> {
- // Array of |Tab| objects.
- base::scoped_nsobject<NSMutableArray> _tabs;
// Maintains policy for where new tabs go and the selection when a tab
// is removed.
base::scoped_nsobject<TabModelOrderController> _orderController;
@@ -197,7 +212,7 @@ void CleanCertificatePolicyCache(
}
- (void)setCurrentTab:(Tab*)newTab {
- DCHECK([_tabs containsObject:newTab]);
+ DCHECK([self containsWebState:newTab]);
if (_currentTab != newTab) {
base::RecordAction(base::UserMetricsAction("MobileTabSwitched"));
[self updateSnapshotCache:newTab];
@@ -224,10 +239,6 @@ void CleanCertificatePolicyCache(
return self.count == 0;
}
-- (NSUInteger)count {
- return [_tabs count];
-}
-
- (instancetype)initWithSessionWindow:(SessionWindowIOS*)window
sessionService:(SessionServiceIOS*)service
browserState:(ios::ChromeBrowserState*)browserState {
@@ -251,7 +262,6 @@ void CleanCertificatePolicyCache(
}
_syncedWindowDelegate.reset(new TabModelSyncedWindowDelegate(self));
- _tabs.reset([[NSMutableArray alloc] init]);
NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
if (window) {
while (window.unclaimedSessions) {
@@ -265,17 +275,20 @@ void CleanCertificatePolicyCache(
[[Tab alloc] initWithWebState:std::move(webState) model:self]);
[tab webController].usePlaceholderOverlay = YES;
[tab fetchFavicon];
- [_tabs addObject:tab];
+ [self addWebState:tab];
TabParentingGlobalObserver::GetInstance()->OnTabParented(
[tab webStateImpl]);
}
- if ([_tabs count]) {
- DCHECK(window.selectedIndex < [_tabs count]);
+ if (self.count) {
+ DCHECK(window.selectedIndex < self.count);
_currentTab.reset([self tabAtIndex:window.selectedIndex]);
DCHECK(_currentTab);
- if (_tabUsageRecorder)
- _tabUsageRecorder->InitialRestoredTabs(_currentTab, _tabs);
+ if (_tabUsageRecorder) {
+ _tabUsageRecorder->InitialRestoredTabs(
+ _currentTab,
+ GetTabsFromWebStateList(self, NSMakeRange(0, self.count)));
+ }
// Perform initializations for affiliated objects which update the
// session information related to the current tab.
[_currentTab updateLastVisitedTimestamp];
@@ -317,7 +330,7 @@ void CleanCertificatePolicyCache(
DCHECK(window);
if (!window.unclaimedSessions)
return NO;
- size_t oldCount = [_tabs count];
+ size_t oldCount = self.count;
size_t index = oldCount;
while (window.unclaimedSessions) {
std::unique_ptr<web::WebStateImpl> webState = [window nextSession];
@@ -328,34 +341,36 @@ void CleanCertificatePolicyCache(
// |webState| is invalid, so we need to get the webstate from |tab|.
UpdateCertificatePolicyCacheFromWebState(tab.webStateImpl);
}
- DCHECK([_tabs count] > oldCount);
+ DCHECK(self.count > oldCount);
// If any tab was restored, the saved selected tab must be selected.
- if ([_tabs count] > oldCount) {
+ if (self.count > oldCount) {
NSUInteger selectedIndex = window.selectedIndex;
if (selectedIndex == NSNotFound)
selectedIndex = oldCount;
else
selectedIndex += oldCount;
- DCHECK(selectedIndex < [_tabs count]);
+ DCHECK(selectedIndex < self.count);
Tab* newTab = [self tabAtIndex:selectedIndex];
DCHECK(newTab);
[self changeSelectedTabFrom:_currentTab to:newTab persistState:YES];
// If there was only one tab and it was the new tab page, clobber it.
if (oldCount == 1) {
- Tab* tab = [_tabs objectAtIndex:0];
+ Tab* tab = [self firstWebState];
if (tab.url == GURL(kChromeUINewTabURL)) {
[self closeTab:tab];
- if (_tabUsageRecorder)
- _tabUsageRecorder->InitialRestoredTabs(_currentTab, _tabs);
+ if (_tabUsageRecorder) {
+ _tabUsageRecorder->InitialRestoredTabs(
+ _currentTab,
+ GetTabsFromWebStateList(self, NSMakeRange(0, self.count)));
+ }
return YES;
}
}
if (_tabUsageRecorder) {
_tabUsageRecorder->InitialRestoredTabs(
- _currentTab,
- [_tabs subarrayWithRange:NSMakeRange(oldCount,
- [_tabs count] - oldCount)]);
+ _currentTab, GetTabsFromWebStateList(
+ self, NSMakeRange(oldCount, self.count - oldCount)));
}
}
return NO;
@@ -364,7 +379,7 @@ void CleanCertificatePolicyCache(
- (void)saveSessionImmediately:(BOOL)immediately {
// Do nothing if there are tabs in the model but no selected tab. This is
// a transitional state.
- if ((!_currentTab && [_tabs count]) || !_browserState)
+ if ((!_currentTab && self.count) || !_browserState)
return;
[_sessionService saveWindow:self.windowForSavingSession
forBrowserState:_browserState
@@ -372,17 +387,17 @@ void CleanCertificatePolicyCache(
}
- (Tab*)tabAtIndex:(NSUInteger)index {
- return [_tabs objectAtIndex:index];
+ return [self webStateAtIndex:index];
}
- (NSUInteger)indexOfTab:(Tab*)tab {
- return [_tabs indexOfObject:tab];
+ return [self indexOfWebState:tab];
}
- (Tab*)tabWithWindowName:(NSString*)windowName {
if (!windowName)
return nil;
- for (Tab* tab in _tabs.get()) {
+ for (Tab* tab in self) {
if ([windowName isEqualToString:tab.windowName]) {
return tab;
}
@@ -401,8 +416,8 @@ void CleanCertificatePolicyCache(
if (startIndex == NSNotFound)
return nil;
NSString* parentID = [tab currentSessionID];
- for (NSUInteger i = startIndex + 1; i < [_tabs count]; ++i) {
- Tab* current = [_tabs objectAtIndex:i];
+ for (NSUInteger i = startIndex + 1; i < self.count; ++i) {
+ Tab* current = [self webStateAtIndex:i];
DCHECK([current navigationManager]);
CRWSessionController* sessionController =
[current navigationManager]->GetSessionController();
@@ -427,7 +442,7 @@ void CleanCertificatePolicyCache(
DCHECK([tab navigationManager]);
NSInteger parentNavIndex = [tab navigationManager]->GetCurrentItemIndex();
for (NSUInteger i = 0; i < stopIndex; ++i) {
- Tab* tabToCheck = [_tabs objectAtIndex:i];
+ Tab* tabToCheck = [self webStateAtIndex:i];
DCHECK([tabToCheck navigationManager]);
CRWSessionController* sessionController =
[tabToCheck navigationManager]->GetSessionController();
@@ -454,8 +469,8 @@ void CleanCertificatePolicyCache(
// tabs whose opener's id and opener's navigation index match. The navigation
// index is used in addition to the session id to detect navigations changes
// within the same session.
- for (NSUInteger i = startIndex + 1; i < [_tabs count]; ++i) {
- Tab* tabToCheck = [_tabs objectAtIndex:i];
+ for (NSUInteger i = startIndex + 1; i < self.count; ++i) {
+ Tab* tabToCheck = [self webStateAtIndex:i];
DCHECK([tabToCheck navigationManager]);
CRWSessionController* sessionController =
[tabToCheck navigationManager]->GetSessionController();
@@ -475,7 +490,7 @@ void CleanCertificatePolicyCache(
NSString* opener = [tab navigationManager]->GetSessionController().openerId;
if (!opener.length) // Short-circuit if opener is empty.
return nil;
- for (Tab* iteratedTab in _tabs.get()) {
+ for (Tab* iteratedTab in self) {
if ([[iteratedTab currentSessionID] isEqualToString:opener])
return iteratedTab;
}
@@ -568,9 +583,9 @@ void CleanCertificatePolicyCache(
- (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index {
DCHECK(tab);
- DCHECK(index <= [_tabs count]);
+ DCHECK(index <= self.count);
[tab fetchFavicon];
- [_tabs insertObject:tab atIndex:index];
+ [self insertWebState:tab atIndex:index];
[_observers tabModel:self didInsertTab:tab atIndex:index inForeground:NO];
[_observers tabModelDidChangeTabCount:self];
@@ -594,8 +609,8 @@ void CleanCertificatePolicyCache(
}
base::scoped_nsobject<Tab> tabSaver([tab retain]);
- [_tabs removeObject:tab];
- [_tabs insertObject:tab atIndex:toIndex];
+ [self removeWebState:tab];
+ [self insertWebState:tab atIndex:toIndex];
[_observers tabModel:self didMoveTab:tab fromIndex:fromIndex toIndex:toIndex];
}
@@ -608,7 +623,7 @@ void CleanCertificatePolicyCache(
base::scoped_nsobject<Tab> tabSaver([oldTab retain]);
[newTab fetchFavicon];
- [_tabs replaceObjectAtIndex:index withObject:newTab];
+ [self replaceWebStateAtIndex:index withWebState:newTab];
[newTab setParentTabModel:self];
[_observers tabModel:self didReplaceTab:oldTab withTab:newTab atIndex:index];
@@ -626,8 +641,8 @@ void CleanCertificatePolicyCache(
}
- (void)closeTabAtIndex:(NSUInteger)index {
- DCHECK(index < [_tabs count]);
- [self closeTab:[_tabs objectAtIndex:index]];
+ DCHECK(index < self.count);
+ [self closeTab:[self webStateAtIndex:index]];
}
- (void)closeTab:(Tab*)tab {
@@ -647,7 +662,7 @@ void CleanCertificatePolicyCache(
}
- (void)haltAllTabs {
- for (Tab* tab in _tabs.get()) {
+ for (Tab* tab in self) {
[tab terminateNetworkActivity];
}
}
@@ -684,7 +699,7 @@ void CleanCertificatePolicyCache(
}
- (void)resetAllWebViews {
- for (Tab* tab in _tabs.get()) {
+ for (Tab* tab in self) {
[tab.webController reinitializeWebViewAndReload:(tab == _currentTab)];
}
}
@@ -693,7 +708,7 @@ void CleanCertificatePolicyCache(
if (webUsageEnabled_ == webUsageEnabled)
return;
webUsageEnabled_ = webUsageEnabled;
- for (Tab* tab in _tabs.get()) {
+ for (Tab* tab in self) {
tab.webUsageEnabled = webUsageEnabled;
}
}
@@ -708,7 +723,7 @@ void CleanCertificatePolicyCache(
if (!_browserState)
return referencedFiles;
// Check the currently open tabs for external files.
- for (Tab* tab in _tabs.get()) {
+ for (Tab* tab in self) {
if (UrlIsExternalFileReference(tab.url)) {
NSString* fileName = base::SysUTF8ToNSString(tab.url.ExtractFileName());
[referencedFiles addObject:fileName];
@@ -745,7 +760,7 @@ void CleanCertificatePolicyCache(
// Called when a tab is closing, but before its CRWWebController is destroyed.
// Equivalent to DetachTabContentsAt() in Chrome's TabStripModel.
- (void)didCloseTab:(Tab*)closedTab {
- NSUInteger closedTabIndex = [_tabs indexOfObject:closedTab];
+ NSUInteger closedTabIndex = [self indexOfWebState:closedTab];
DCHECK(closedTab);
DCHECK(closedTabIndex != NSNotFound);
// Let the sessions::TabRestoreService know about that new tab.
@@ -765,7 +780,7 @@ void CleanCertificatePolicyCache(
Tab* newSelection =
[_orderController determineNewSelectedTabFromRemovedTab:closedTab];
base::scoped_nsobject<Tab> kungFuDeathGrip([closedTab retain]);
- [_tabs removeObject:closedTab];
+ [self removeWebState:closedTab];
// If closing the current tab, clear |_currentTab| before sending any
// notification. This avoids various parts of the code getting confused
@@ -816,20 +831,11 @@ void CleanCertificatePolicyCache(
UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountPerLoad", tabCount, 1, 200, 50);
}
-#pragma mark - NSFastEnumeration
-
-- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState*)state
- objects:(id*)objects
- count:(NSUInteger)count {
- return [_tabs countByEnumeratingWithState:state objects:objects count:count];
-}
-
#pragma mark - TabUsageRecorderDelegate
- (NSUInteger)liveTabsCount {
NSUInteger count = 0;
- NSArray* tabs = _tabs.get();
- for (Tab* tab in tabs) {
+ for (Tab* tab in self) {
if ([tab.webController isViewAlive])
count++;
}
@@ -848,7 +854,7 @@ void CleanCertificatePolicyCache(
// TODO(crbug.com/661986): This could get expensive especially since this
// window may never be saved (if another call comes in before the delay).
SessionWindowIOS* window = [[[SessionWindowIOS alloc] init] autorelease];
- for (Tab* tab in _tabs.get()) {
+ for (Tab* tab in self) {
DCHECK(tab.webStateImpl);
std::unique_ptr<web::WebStateImpl> webStateCopy(
tab.webStateImpl->CopyForSessionWindow());
@@ -1013,7 +1019,7 @@ void CleanCertificatePolicyCache(
DCHECK(policy_cache);
web::WebThread::PostTask(
web::WebThread::IO, FROM_HERE,
- base::Bind(&CleanCertificatePolicyCache, policy_cache, _tabs));
+ base::Bind(&CleanCertificatePolicyCache, policy_cache, self));
if (_tabUsageRecorder)
_tabUsageRecorder->AppDidEnterBackground();
« no previous file with comments | « ios/chrome/browser/tabs/tab_model.h ('k') | ios/chrome/browser/tabs/tab_model_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698