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

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

Issue 2775623002: [ios] WebStateList owns all WebState it manages. (Closed)
Patch Set: Fix ios_chrome_unittests. Created 3 years, 9 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 <cstdint> 7 #include <cstdint>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #import "base/mac/foundation_util.h"
13 #import "base/mac/scoped_nsobject.h" 14 #import "base/mac/scoped_nsobject.h"
14 #include "base/metrics/histogram_macros.h" 15 #include "base/metrics/histogram_macros.h"
15 #include "base/metrics/user_metrics.h" 16 #include "base/metrics/user_metrics.h"
16 #include "base/metrics/user_metrics_action.h" 17 #include "base/metrics/user_metrics_action.h"
17 #include "base/strings/sys_string_conversions.h" 18 #include "base/strings/sys_string_conversions.h"
18 #include "base/task/cancelable_task_tracker.h" 19 #include "base/task/cancelable_task_tracker.h"
19 #include "components/sessions/core/serialized_navigation_entry.h" 20 #include "components/sessions/core/serialized_navigation_entry.h"
20 #include "components/sessions/core/session_id.h" 21 #include "components/sessions/core/session_id.h"
21 #include "components/sessions/core/tab_restore_service.h" 22 #include "components/sessions/core/tab_restore_service.h"
22 #include "components/sessions/ios/ios_live_tab.h" 23 #include "components/sessions/ios/ios_live_tab.h"
23 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" 24 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
24 #include "ios/chrome/browser/chrome_url_constants.h" 25 #include "ios/chrome/browser/chrome_url_constants.h"
25 #import "ios/chrome/browser/chrome_url_util.h" 26 #import "ios/chrome/browser/chrome_url_util.h"
26 #import "ios/chrome/browser/metrics/tab_usage_recorder.h" 27 #import "ios/chrome/browser/metrics/tab_usage_recorder.h"
27 #import "ios/chrome/browser/metrics/tab_usage_recorder_web_state_list_observer.h " 28 #import "ios/chrome/browser/metrics/tab_usage_recorder_web_state_list_observer.h "
28 #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h" 29 #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h"
29 #import "ios/chrome/browser/sessions/session_service.h" 30 #import "ios/chrome/browser/sessions/session_service.h"
30 #import "ios/chrome/browser/sessions/session_window_ios.h" 31 #import "ios/chrome/browser/sessions/session_window_ios.h"
31 #import "ios/chrome/browser/snapshots/snapshot_cache.h" 32 #import "ios/chrome/browser/snapshots/snapshot_cache.h"
32 #import "ios/chrome/browser/snapshots/snapshot_cache_web_state_list_observer.h" 33 #import "ios/chrome/browser/snapshots/snapshot_cache_web_state_list_observer.h"
33 #include "ios/chrome/browser/tab_parenting_global_observer.h" 34 #include "ios/chrome/browser/tab_parenting_global_observer.h"
34 #import "ios/chrome/browser/tabs/legacy_tab_helper.h" 35 #import "ios/chrome/browser/tabs/legacy_tab_helper.h"
35 #import "ios/chrome/browser/tabs/tab.h" 36 #import "ios/chrome/browser/tabs/tab.h"
37 #import "ios/chrome/browser/tabs/tab_model_closing_web_state_observer.h"
36 #import "ios/chrome/browser/tabs/tab_model_list.h" 38 #import "ios/chrome/browser/tabs/tab_model_list.h"
37 #import "ios/chrome/browser/tabs/tab_model_observers.h" 39 #import "ios/chrome/browser/tabs/tab_model_observers.h"
38 #import "ios/chrome/browser/tabs/tab_model_observers_bridge.h" 40 #import "ios/chrome/browser/tabs/tab_model_observers_bridge.h"
39 #import "ios/chrome/browser/tabs/tab_model_selected_tab_observer.h" 41 #import "ios/chrome/browser/tabs/tab_model_selected_tab_observer.h"
40 #import "ios/chrome/browser/tabs/tab_model_synced_window_delegate.h" 42 #import "ios/chrome/browser/tabs/tab_model_synced_window_delegate.h"
41 #import "ios/chrome/browser/tabs/tab_model_web_state_list_delegate.h" 43 #import "ios/chrome/browser/tabs/tab_model_web_state_list_delegate.h"
42 #import "ios/chrome/browser/tabs/tab_parenting_observer.h" 44 #import "ios/chrome/browser/tabs/tab_parenting_observer.h"
43 #import "ios/chrome/browser/xcallback_parameters.h" 45 #import "ios/chrome/browser/xcallback_parameters.h"
44 #import "ios/shared/chrome/browser/tabs/web_state_list.h" 46 #import "ios/shared/chrome/browser/tabs/web_state_list.h"
45 #import "ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper.h " 47 #import "ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper.h "
46 #import "ios/shared/chrome/browser/tabs/web_state_list_metrics_observer.h" 48 #import "ios/shared/chrome/browser/tabs/web_state_list_metrics_observer.h"
47 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h" 49 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h"
48 #import "ios/shared/chrome/browser/tabs/web_state_opener.h" 50 #import "ios/shared/chrome/browser/tabs/web_state_opener.h"
49 #import "ios/web/navigation/crw_session_certificate_policy_manager.h" 51 #import "ios/web/navigation/crw_session_certificate_policy_manager.h"
50 #import "ios/web/navigation/crw_session_controller.h" 52 #import "ios/web/navigation/crw_session_controller.h"
51 #include "ios/web/public/browser_state.h" 53 #include "ios/web/public/browser_state.h"
52 #include "ios/web/public/certificate_policy_cache.h" 54 #include "ios/web/public/certificate_policy_cache.h"
53 #include "ios/web/public/navigation_item.h" 55 #include "ios/web/public/navigation_item.h"
54 #import "ios/web/public/navigation_manager.h" 56 #import "ios/web/public/navigation_manager.h"
57 #import "ios/web/public/serializable_user_data_manager.h"
55 #include "ios/web/public/web_thread.h" 58 #include "ios/web/public/web_thread.h"
56 #import "ios/web/web_state/ui/crw_web_controller.h" 59 #import "ios/web/web_state/ui/crw_web_controller.h"
57 #import "ios/web/web_state/web_state_impl.h" 60 #import "ios/web/web_state/web_state_impl.h"
58 #include "url/gurl.h" 61 #include "url/gurl.h"
59 62
60 NSString* const kTabModelTabWillStartLoadingNotification = 63 NSString* const kTabModelTabWillStartLoadingNotification =
61 @"kTabModelTabWillStartLoadingNotification"; 64 @"kTabModelTabWillStartLoadingNotification";
62 NSString* const kTabModelTabDidStartLoadingNotification = 65 NSString* const kTabModelTabDidStartLoadingNotification =
63 @"kTabModelTabDidStartLoadingNotification"; 66 @"kTabModelTabDidStartLoadingNotification";
64 NSString* const kTabModelTabDidFinishLoadingNotification = 67 NSString* const kTabModelTabDidFinishLoadingNotification =
65 @"kTabModelTabDidFinishLoadingNotification"; 68 @"kTabModelTabDidFinishLoadingNotification";
66 NSString* const kTabModelAllTabsDidCloseNotification = 69 NSString* const kTabModelAllTabsDidCloseNotification =
67 @"kTabModelAllTabsDidCloseNotification"; 70 @"kTabModelAllTabsDidCloseNotification";
68 NSString* const kTabModelTabDeselectedNotification = 71 NSString* const kTabModelTabDeselectedNotification =
69 @"kTabModelTabDeselectedNotification"; 72 @"kTabModelTabDeselectedNotification";
70 NSString* const kTabModelNewTabWillOpenNotification = 73 NSString* const kTabModelNewTabWillOpenNotification =
71 @"kTabModelNewTabWillOpenNotification"; 74 @"kTabModelNewTabWillOpenNotification";
72 NSString* const kTabModelTabKey = @"tab"; 75 NSString* const kTabModelTabKey = @"tab";
73 NSString* const kTabModelPageLoadSuccess = @"pageLoadSuccess"; 76 NSString* const kTabModelPageLoadSuccess = @"pageLoadSuccess";
74 NSString* const kTabModelOpenInBackgroundKey = @"shouldOpenInBackground"; 77 NSString* const kTabModelOpenInBackgroundKey = @"shouldOpenInBackground";
75 78
76 namespace { 79 namespace {
77 80
81 // The key under which the opener Tab ID is stored in the WebState's
82 // serializable user data.
83 NSString* const kOpenerIDKey = @"OpenerID";
84
85 // The key under which the opener navigation index is stored in the WebState's
86 // serializable user data.
87 NSString* const kOpenerNavigationIndexKey = @"OpenerNavigationIndex";
88
78 // Updates CRWSessionCertificatePolicyManager's certificate policy cache. 89 // Updates CRWSessionCertificatePolicyManager's certificate policy cache.
79 void UpdateCertificatePolicyCacheFromWebState( 90 void UpdateCertificatePolicyCacheFromWebState(
80 const scoped_refptr<web::CertificatePolicyCache>& policy_cache, 91 const scoped_refptr<web::CertificatePolicyCache>& policy_cache,
81 web::WebState* web_state) { 92 web::WebState* web_state) {
82 DCHECK(web_state); 93 DCHECK(web_state);
83 DCHECK_CURRENTLY_ON(web::WebThread::UI); 94 DCHECK_CURRENTLY_ON(web::WebThread::UI);
84 // TODO(crbug.com/454984): Remove CRWSessionController usage once certificate 95 // TODO(crbug.com/454984): Remove CRWSessionController usage once certificate
85 // policy manager is moved to NavigationManager. 96 // policy manager is moved to NavigationManager.
86 CRWSessionController* controller = static_cast<web::WebStateImpl*>(web_state) 97 CRWSessionController* controller = static_cast<web::WebStateImpl*>(web_state)
87 ->GetNavigationManagerImpl() 98 ->GetNavigationManagerImpl()
(...skipping 28 matching lines...) Expand all
116 task_runner.get(), FROM_HERE, 127 task_runner.get(), FROM_HERE,
117 base::Bind(&web::CertificatePolicyCache::ClearCertificatePolicies, 128 base::Bind(&web::CertificatePolicyCache::ClearCertificatePolicies,
118 policy_cache), 129 policy_cache),
119 base::Bind(&RestoreCertificatePolicyCacheFromModel, policy_cache, 130 base::Bind(&RestoreCertificatePolicyCacheFromModel, policy_cache,
120 base::Unretained(web_state_list))); 131 base::Unretained(web_state_list)));
121 } 132 }
122 133
123 // Internal helper function returning the opener for a given Tab by 134 // Internal helper function returning the opener for a given Tab by
124 // checking the associated Tab tabId (should be removed once the opener 135 // checking the associated Tab tabId (should be removed once the opener
125 // is passed to the insertTab:atIndex: and replaceTab:withTab: methods). 136 // is passed to the insertTab:atIndex: and replaceTab:withTab: methods).
126 Tab* GetOpenerForTab(id<NSFastEnumeration> tabs, Tab* tab) { 137 WebStateOpener GetOpenerForTab(id<NSFastEnumeration> tabs, Tab* tab) {
127 if (!tab.openerID) 138 web::SerializableUserDataManager* user_data_manager =
rohitrao (ping after 24h) 2017/03/26 23:21:22 Where did this move from?
sdefresne 2017/03/28 15:15:05 From Tab -openerId & Tab -openerNavigationIndex. N
128 return nullptr; 139 web::SerializableUserDataManager::FromWebState(tab.webState);
129 140
130 for (Tab* currentTab in tabs) { 141 NSString* opener_id = base::mac::ObjCCast<NSString>(
131 if ([tab.openerID isEqualToString:currentTab.tabId]) 142 user_data_manager->GetValueForSerializationKey(kOpenerIDKey));
132 return currentTab; 143 if (!opener_id || ![opener_id length])
144 return WebStateOpener(nullptr);
145
146 NSNumber* boxed_opener_navigation_index = base::mac::ObjCCast<NSNumber>(
147 user_data_manager->GetValueForSerializationKey(
148 kOpenerNavigationIndexKey));
149 if (!boxed_opener_navigation_index)
150 return WebStateOpener(nullptr);
151
152 for (Tab* current_tab in tabs) {
153 if ([opener_id isEqualToString:current_tab.tabId]) {
154 return WebStateOpener(current_tab.webState,
155 [boxed_opener_navigation_index intValue]);
156 }
133 } 157 }
134 158
135 return nullptr; 159 return WebStateOpener(nullptr);
136 } 160 }
137 161
138 } // anonymous namespace 162 } // anonymous namespace
139 163
140 @interface TabModelWebStateProxyFactory : NSObject<WebStateProxyFactory> 164 @interface TabModelWebStateProxyFactory : NSObject<WebStateProxyFactory>
141 @end 165 @end
142 166
143 @implementation TabModelWebStateProxyFactory 167 @implementation TabModelWebStateProxyFactory
144 168
145 - (id)proxyForWebState:(web::WebState*)webState { 169 - (id)proxyForWebState:(web::WebState*)webState {
146 return LegacyTabHelper::GetTabForWebState(webState); 170 return LegacyTabHelper::GetTabForWebState(webState);
147 } 171 }
148 172
149 @end 173 @end
150 174
151 @interface TabModel ()<TabUsageRecorderDelegate> { 175 @interface TabModel ()<TabUsageRecorderDelegate> {
152 // Delegate for the WebStateList. 176 // Delegate for the WebStateList.
153 std::unique_ptr<WebStateListDelegate> _webStateListDelegate; 177 std::unique_ptr<WebStateListDelegate> _webStateListDelegate;
154 178
155 // Underlying shared model implementation. 179 // Underlying shared model implementation.
156 std::unique_ptr<WebStateList> _webStateList; 180 std::unique_ptr<WebStateList> _webStateList;
157 181
158 // Helper providing NSFastEnumeration implementation over the WebStateList. 182 // Helper providing NSFastEnumeration implementation over the WebStateList.
159 base::scoped_nsobject<WebStateListFastEnumerationHelper> 183 base::scoped_nsobject<WebStateListFastEnumerationHelper>
160 _fastEnumerationHelper; 184 _fastEnumerationHelper;
161 185
162 // Used to keep the Tabs alive while the corresponding WebStates are stored
163 // in the WebStateList (as Tabs currently own their WebState). Remove once
164 // WebState owns the associated Tab.
165 base::scoped_nsobject<NSMutableSet<Tab*>> _tabRetainer;
166
167 // WebStateListObservers reacting to modifications of the model (may send 186 // WebStateListObservers reacting to modifications of the model (may send
168 // notification, translate and forward events, update metrics, ...). 187 // notification, translate and forward events, update metrics, ...).
169 std::vector<std::unique_ptr<WebStateListObserver>> _webStateListObservers; 188 std::vector<std::unique_ptr<WebStateListObserver>> _webStateListObservers;
170 189
171 // The delegate for sync. 190 // The delegate for sync.
172 std::unique_ptr<TabModelSyncedWindowDelegate> _syncedWindowDelegate; 191 std::unique_ptr<TabModelSyncedWindowDelegate> _syncedWindowDelegate;
173 192
174 // Counters for metrics. 193 // Counters for metrics.
175 WebStateListMetricsObserver* _webStateListMetricsObserver; 194 WebStateListMetricsObserver* _webStateListMetricsObserver;
176 195
177 // Backs up property with the same name. 196 // Backs up property with the same name.
178 std::unique_ptr<TabUsageRecorder> _tabUsageRecorder; 197 std::unique_ptr<TabUsageRecorder> _tabUsageRecorder;
179 // Backs up property with the same name. 198 // Backs up property with the same name.
180 const SessionID _sessionID; 199 const SessionID _sessionID;
181 // Saves session's state. 200 // Saves session's state.
182 base::scoped_nsobject<SessionServiceIOS> _sessionService; 201 base::scoped_nsobject<SessionServiceIOS> _sessionService;
183 // List of TabModelObservers. 202 // List of TabModelObservers.
184 base::scoped_nsobject<TabModelObservers> _observers; 203 base::scoped_nsobject<TabModelObservers> _observers;
185 204
186 // Used to ensure thread-safety of the certificate policy management code. 205 // Used to ensure thread-safety of the certificate policy management code.
187 base::CancelableTaskTracker _clearPoliciesTaskTracker; 206 base::CancelableTaskTracker _clearPoliciesTaskTracker;
188 } 207 }
189 208
190 // Session window for the contents of the tab model. 209 // Session window for the contents of the tab model.
191 @property(nonatomic, readonly) SessionWindowIOS* windowForSavingSession; 210 @property(nonatomic, readonly) SessionWindowIOS* windowForSavingSession;
192 211
193 // Returns YES if tab URL host indicates that tab is an NTP tab.
194 - (BOOL)isNTPTab:(Tab*)tab;
195
196 // Helper method that posts a notification with the given name with |tab| 212 // Helper method that posts a notification with the given name with |tab|
197 // in the userInfo dictionary under the kTabModelTabKey. 213 // in the userInfo dictionary under the kTabModelTabKey.
198 - (void)postNotificationName:(NSString*)notificationName withTab:(Tab*)tab; 214 - (void)postNotificationName:(NSString*)notificationName withTab:(Tab*)tab;
199 215
200 // Helper method to restore a saved session and control if the state should 216 // Helper method to restore a saved session and control if the state should
201 // be persisted or not. Used to implement the public -restoreSessionWindow: 217 // be persisted or not. Used to implement the public -restoreSessionWindow:
202 // method and restoring session in the initialiser. 218 // method and restoring session in the initialiser.
203 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window 219 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window
204 persistState:(BOOL)persistState; 220 persistState:(BOOL)persistState;
205 221
206 // Helper method to insert |tab| at the given |index| recording |parentTab| as
207 // the opener. Broadcasts the proper notifications about the change. The
208 // receiver should be set as the parentTabModel for |tab|; this method doesn't
209 // check that.
210 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index opener:(Tab*)parentTab;
211
212 // Helper method to insert |tab| at the given |index| recording |parentTab| as
213 // the opener. Broadcasts the proper notifications about the change. The
214 // receiver should be set as the parentTabModel for |tab|; this method doesn't
215 // check that.
216 - (void)insertTab:(Tab*)tab
217 atIndex:(NSUInteger)index
218 opener:(Tab*)parentTab
219 transition:(ui::PageTransition)transition;
220
221 @end 222 @end
222 223
223 @implementation TabModel 224 @implementation TabModel
224 225
225 @synthesize browserState = _browserState; 226 @synthesize browserState = _browserState;
226 @synthesize sessionID = _sessionID; 227 @synthesize sessionID = _sessionID;
227 @synthesize webUsageEnabled = webUsageEnabled_; 228 @synthesize webUsageEnabled = webUsageEnabled_;
228 229
229 #pragma mark - Overriden 230 #pragma mark - Overriden
230 231
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 } 289 }
289 290
290 - (WebStateList*)webStateList { 291 - (WebStateList*)webStateList {
291 return _webStateList.get(); 292 return _webStateList.get();
292 } 293 }
293 294
294 - (instancetype)initWithSessionWindow:(SessionWindowIOS*)window 295 - (instancetype)initWithSessionWindow:(SessionWindowIOS*)window
295 sessionService:(SessionServiceIOS*)service 296 sessionService:(SessionServiceIOS*)service
296 browserState:(ios::ChromeBrowserState*)browserState { 297 browserState:(ios::ChromeBrowserState*)browserState {
297 if ((self = [super init])) { 298 if ((self = [super init])) {
298 _tabRetainer.reset([[NSMutableSet alloc] init]);
299 _observers.reset([[TabModelObservers observers] retain]); 299 _observers.reset([[TabModelObservers observers] retain]);
300 300
301 _webStateListDelegate = 301 _webStateListDelegate =
302 base::MakeUnique<TabModelWebStateListDelegate>(self); 302 base::MakeUnique<TabModelWebStateListDelegate>(self);
303 _webStateList = base::MakeUnique<WebStateList>( 303 _webStateList = base::MakeUnique<WebStateList>(_webStateListDelegate.get());
304 _webStateListDelegate.get(), WebStateList::WebStateBorrowed);
305 304
306 _fastEnumerationHelper.reset([[WebStateListFastEnumerationHelper alloc] 305 _fastEnumerationHelper.reset([[WebStateListFastEnumerationHelper alloc]
307 initWithWebStateList:_webStateList.get() 306 initWithWebStateList:_webStateList.get()
308 proxyFactory:[[TabModelWebStateProxyFactory alloc] init]]); 307 proxyFactory:[[TabModelWebStateProxyFactory alloc] init]]);
309 308
310 _browserState = browserState; 309 _browserState = browserState;
311 DCHECK(_browserState); 310 DCHECK(_browserState);
312 311
313 // Normal browser states are the only ones to get tab restore. Tab sync 312 // Normal browser states are the only ones to get tab restore. Tab sync
314 // handles incognito browser states by filtering on profile, so it's 313 // handles incognito browser states by filtering on profile, so it's
315 // important to the backend code to always have a sync window delegate. 314 // important to the backend code to always have a sync window delegate.
316 if (!_browserState->IsOffTheRecord()) { 315 if (!_browserState->IsOffTheRecord()) {
317 // Set up the usage recorder before tabs are created. 316 // Set up the usage recorder before tabs are created.
318 _tabUsageRecorder = base::MakeUnique<TabUsageRecorder>(self); 317 _tabUsageRecorder = base::MakeUnique<TabUsageRecorder>(self);
319 } 318 }
320 _syncedWindowDelegate = 319 _syncedWindowDelegate =
321 base::MakeUnique<TabModelSyncedWindowDelegate>(self); 320 base::MakeUnique<TabModelSyncedWindowDelegate>(self);
322 321
323 // There must be a valid session service defined to consume session windows. 322 // There must be a valid session service defined to consume session windows.
324 DCHECK(service); 323 DCHECK(service);
325 _sessionService.reset([service retain]); 324 _sessionService.reset([service retain]);
326 325
326 _webStateListObservers.push_back(base::MakeUnique<
327 WebStateListObserverBridge>([
328 [TabModelClosingWebStateObserver alloc]
329 initWithTabModel:self
330 restoreService:IOSChromeTabRestoreServiceFactory::GetForBrowserState(
331 _browserState)]));
327 _webStateListObservers.push_back( 332 _webStateListObservers.push_back(
328 base::MakeUnique<SnapshotCacheWebStateListObserver>( 333 base::MakeUnique<SnapshotCacheWebStateListObserver>(
329 [SnapshotCache sharedInstance])); 334 [SnapshotCache sharedInstance]));
330 if (_tabUsageRecorder) { 335 if (_tabUsageRecorder) {
331 _webStateListObservers.push_back( 336 _webStateListObservers.push_back(
332 base::MakeUnique<TabUsageRecorderWebStateListObserver>( 337 base::MakeUnique<TabUsageRecorderWebStateListObserver>(
333 _tabUsageRecorder.get())); 338 _tabUsageRecorder.get()));
334 } 339 }
335 _webStateListObservers.push_back(base::MakeUnique<TabParentingObserver>()); 340 _webStateListObservers.push_back(base::MakeUnique<TabParentingObserver>());
336 _webStateListObservers.push_back( 341 _webStateListObservers.push_back(
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 params.referrer = referrer; 474 params.referrer = referrer;
470 params.transition_type = transition; 475 params.transition_type = transition;
471 return [self insertTabWithLoadParams:params 476 return [self insertTabWithLoadParams:params
472 opener:parentTab 477 opener:parentTab
473 openedByDOM:openedByDOM 478 openedByDOM:openedByDOM
474 atIndex:index 479 atIndex:index
475 inBackground:inBackground]; 480 inBackground:inBackground];
476 } 481 }
477 482
478 - (Tab*)insertTabWithLoadParams: 483 - (Tab*)insertTabWithLoadParams:
479 (const web::NavigationManager::WebLoadParams&)params 484 (const web::NavigationManager::WebLoadParams&)loadParams
480 opener:(Tab*)parentTab 485 opener:(Tab*)parentTab
481 openedByDOM:(BOOL)openedByDOM 486 openedByDOM:(BOOL)openedByDOM
482 atIndex:(NSUInteger)index 487 atIndex:(NSUInteger)index
483 inBackground:(BOOL)inBackground { 488 inBackground:(BOOL)inBackground {
484 DCHECK(_browserState); 489 DCHECK(_browserState);
485 base::scoped_nsobject<Tab> tab([[Tab alloc] initWithBrowserState:_browserState 490
486 opener:parentTab 491 web::WebState::CreateParams createParams(self.browserState);
487 openedByDOM:openedByDOM 492 createParams.created_with_opener = openedByDOM;
488 model:self]); 493 std::unique_ptr<web::WebState> webState = web::WebState::Create(createParams);
494
495 web::WebState* webStatePtr = webState.get();
496 if (index == TabModelConstants::kTabPositionAutomatically) {
497 _webStateList->AppendWebState(loadParams.transition_type,
498 std::move(webState),
499 WebStateOpener(parentTab.webState));
500 } else {
501 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX));
502 const int insertion_index = static_cast<int>(index);
503 _webStateList->InsertWebState(insertion_index, std::move(webState));
504 if (parentTab.webState) {
505 _webStateList->SetOpenerOfWebStateAt(insertion_index,
506 WebStateOpener(parentTab.webState));
507 }
508 }
509
510 Tab* tab = LegacyTabHelper::GetTabForWebState(webStatePtr);
511 DCHECK(tab);
512
489 [tab webController].webUsageEnabled = webUsageEnabled_; 513 [tab webController].webUsageEnabled = webUsageEnabled_;
490 514
491 [self insertTab:tab
492 atIndex:index
493 opener:parentTab
494 transition:params.transition_type];
495
496 if (!inBackground && _tabUsageRecorder) 515 if (!inBackground && _tabUsageRecorder)
497 _tabUsageRecorder->TabCreatedForSelection(tab); 516 _tabUsageRecorder->TabCreatedForSelection(tab);
498 517
499 [[tab webController] loadWithParams:params]; 518 [[tab webController] loadWithParams:loadParams];
519
500 // Force the page to start loading even if it's in the background. 520 // Force the page to start loading even if it's in the background.
501 if (webUsageEnabled_) 521 if (webUsageEnabled_)
502 [[tab webController] triggerPendingLoad]; 522 [[tab webController] triggerPendingLoad];
503 NSDictionary* userInfo = @{ 523 NSDictionary* userInfo = @{
504 kTabModelTabKey : tab, 524 kTabModelTabKey : tab,
505 kTabModelOpenInBackgroundKey : @(inBackground), 525 kTabModelOpenInBackgroundKey : @(inBackground),
506 }; 526 };
507 [[NSNotificationCenter defaultCenter] 527 [[NSNotificationCenter defaultCenter]
508 postNotificationName:kTabModelNewTabWillOpenNotification 528 postNotificationName:kTabModelNewTabWillOpenNotification
509 object:self 529 object:self
510 userInfo:userInfo]; 530 userInfo:userInfo];
511 531
512 if (!inBackground) 532 if (!inBackground)
513 [self setCurrentTab:tab]; 533 [self setCurrentTab:tab];
514 534
515 return tab; 535 return tab;
516 } 536 }
517 537
518 - (Tab*)insertTabWithWebState:(std::unique_ptr<web::WebState>)webState
519 atIndex:(NSUInteger)index {
520 DCHECK(_browserState);
521 DCHECK_EQ(webState->GetBrowserState(), _browserState);
522 base::scoped_nsobject<Tab> tab(
523 [[Tab alloc] initWithWebState:std::move(webState) model:self]);
524 [tab webController].webUsageEnabled = webUsageEnabled_;
525 [self insertTab:tab atIndex:index];
526 return tab;
527 }
528
529 - (void)insertTab:(Tab*)tab
530 atIndex:(NSUInteger)index
531 opener:(Tab*)parentTab
532 transition:(ui::PageTransition)transition {
533 DCHECK(tab);
534 DCHECK(![_tabRetainer containsObject:tab]);
535
536 [_tabRetainer addObject:tab];
537 if (index == TabModelConstants::kTabPositionAutomatically) {
538 _webStateList->AppendWebState(
539 transition, tab.webState,
540 WebStateOpener(parentTab.webState, tab.openerNavigationIndex));
541 } else {
542 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX));
543 const int insertion_index = static_cast<int>(index);
544 _webStateList->InsertWebState(insertion_index, tab.webState);
545 if (parentTab.webState) {
546 _webStateList->SetOpenerOfWebStateAt(
547 insertion_index,
548 WebStateOpener(parentTab.webState, tab.openerNavigationIndex));
549 }
550 }
551
552 // Persist the session due to a new tab being inserted. If this is a
553 // background tab (will not become active), saving now will capture the
554 // state properly. If it does eventually become active, another save will
555 // be triggered to properly capture the end result.
556 [self saveSessionImmediately:NO];
557 }
558
559 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index opener:(Tab*)parentTab {
560 DCHECK(tab);
561 DCHECK(![_tabRetainer containsObject:tab]);
562 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX));
563
564 [self insertTab:tab
565 atIndex:index
566 opener:parentTab
567 transition:ui::PAGE_TRANSITION_GENERATED];
568 }
569
570 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index {
571 DCHECK(tab);
572 DCHECK(![_tabRetainer containsObject:tab]);
573 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX));
574
575 [self insertTab:tab atIndex:index opener:GetOpenerForTab(self, tab)];
576 }
577
578 - (void)moveTab:(Tab*)tab toIndex:(NSUInteger)toIndex { 538 - (void)moveTab:(Tab*)tab toIndex:(NSUInteger)toIndex {
579 DCHECK([_tabRetainer containsObject:tab]);
580 DCHECK_LE(toIndex, static_cast<NSUInteger>(INT_MAX)); 539 DCHECK_LE(toIndex, static_cast<NSUInteger>(INT_MAX));
581 int fromIndex = _webStateList->GetIndexOfWebState(tab.webState); 540 int fromIndex = _webStateList->GetIndexOfWebState(tab.webState);
582 _webStateList->MoveWebStateAt(fromIndex, static_cast<int>(toIndex)); 541 _webStateList->MoveWebStateAt(fromIndex, static_cast<int>(toIndex));
583 } 542 }
584 543
585 - (void)replaceTab:(Tab*)oldTab withTab:(Tab*)newTab {
586 DCHECK([_tabRetainer containsObject:oldTab]);
587 DCHECK(![_tabRetainer containsObject:newTab]);
588
589 int index = _webStateList->GetIndexOfWebState(oldTab.webState);
590 DCHECK_NE(index, WebStateList::kInvalidIndex);
591 DCHECK_GE(index, 0);
592
593 base::scoped_nsobject<Tab> tabSaver([oldTab retain]);
594 [_tabRetainer removeObject:oldTab];
595 [_tabRetainer addObject:newTab];
596 [newTab setParentTabModel:self];
597
598 // The WebState is owned by the associated Tab, so it is safe to ignore
599 // the result and won't cause a memory leak. Once the ownership is moved
600 // to WebStateList, this function will return a std::unique_ptr<> and the
601 // object destroyed as expected, so it will fine to ignore the result then
602 // too. See http://crbug.com/546222 for progress of changing the ownership
603 // of the WebStates.
604 ignore_result(_webStateList->ReplaceWebStateAt(index, newTab.webState));
605
606 Tab* parentTab = GetOpenerForTab(self, newTab);
607 if (parentTab) {
608 _webStateList->SetOpenerOfWebStateAt(
609 index,
610 WebStateOpener(parentTab.webState, newTab.openerNavigationIndex));
611 }
612
613 [oldTab setParentTabModel:nil];
614 [oldTab close];
615 }
616
617 - (void)closeTabAtIndex:(NSUInteger)index { 544 - (void)closeTabAtIndex:(NSUInteger)index {
618 DCHECK(index < self.count); 545 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX));
619 [self closeTab:[self tabAtIndex:index]]; 546 _webStateList->CloseWebStateAt(static_cast<int>(index));
620 } 547 }
621 548
622 - (void)closeTab:(Tab*)tab { 549 - (void)closeTab:(Tab*)tab {
623 // Ensure the tab stays alive long enough for us to send out the 550 [self closeTabAtIndex:[self indexOfTab:tab]];
624 // notice of its destruction to the delegate.
625 [_observers tabModel:self willRemoveTab:tab];
626 [tab close]; // Note it is not safe to access the tab after 'close'.
627 } 551 }
628 552
629 - (void)closeAllTabs { 553 - (void)closeAllTabs {
630 for (NSInteger i = self.count - 1; i >= 0; --i) 554 _webStateList->CloseAllWebStates();
631 [self closeTabAtIndex:i];
632 [[NSNotificationCenter defaultCenter] 555 [[NSNotificationCenter defaultCenter]
633 postNotificationName:kTabModelAllTabsDidCloseNotification 556 postNotificationName:kTabModelAllTabsDidCloseNotification
634 object:self]; 557 object:self];
635 } 558 }
636 559
637 - (void)haltAllTabs { 560 - (void)haltAllTabs {
638 for (Tab* tab in self) { 561 for (Tab* tab in self) {
639 [tab terminateNetworkActivity]; 562 [tab terminateNetworkActivity];
640 } 563 }
641 } 564 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 642
720 // NOTE: This can be called multiple times, so must be robust against that. 643 // NOTE: This can be called multiple times, so must be robust against that.
721 - (void)browserStateDestroyed { 644 - (void)browserStateDestroyed {
722 [[NSNotificationCenter defaultCenter] removeObserver:self]; 645 [[NSNotificationCenter defaultCenter] removeObserver:self];
723 if (_browserState) { 646 if (_browserState) {
724 UnregisterTabModelFromChromeBrowserState(_browserState, self); 647 UnregisterTabModelFromChromeBrowserState(_browserState, self);
725 } 648 }
726 _browserState = nullptr; 649 _browserState = nullptr;
727 } 650 }
728 651
729 // Called when a tab is closing, but before its CRWWebController is destroyed.
730 // Equivalent to DetachTabContentsAt() in Chrome's TabStripModel.
731 - (void)didCloseTab:(Tab*)closedTab {
732 DCHECK(closedTab);
733 DCHECK([_tabRetainer containsObject:closedTab]);
734 int closedTabIndex = _webStateList->GetIndexOfWebState(closedTab.webState);
735 DCHECK_NE(closedTabIndex, WebStateList::kInvalidIndex);
736 DCHECK_GE(closedTabIndex, 0);
737
738 // Let the sessions::TabRestoreService know about that new tab.
739 sessions::TabRestoreService* restoreService =
740 _browserState
741 ? IOSChromeTabRestoreServiceFactory::GetForBrowserState(_browserState)
742 : nullptr;
743 web::NavigationManager* navigationManager = [closedTab navigationManager];
744 DCHECK(navigationManager);
745 int itemCount = navigationManager->GetItemCount();
746 if (restoreService && (![self isNTPTab:closedTab] || itemCount > 1)) {
747 restoreService->CreateHistoricalTab(
748 sessions::IOSLiveTab::GetForWebState(closedTab.webState),
749 closedTabIndex);
750 }
751
752 base::scoped_nsobject<Tab> kungFuDeathGrip([closedTab retain]);
753
754 // If a non-current Tab is closed, save the session (it will be saved by
755 // TabModelObserversBridge if the currentTab has been closed).
756 BOOL needToSaveSession = (closedTab != self.currentTab);
757
758 DCHECK([_tabRetainer containsObject:closedTab]);
759 [_tabRetainer removeObject:closedTab];
760
761 // The WebState is owned by the associated Tab, so it is safe to ignore
762 // the result and won't cause a memory leak. Once the ownership is moved
763 // to WebStateList, this function will return a std::unique_ptr<> and the
764 // object destroyed as expected, so it will fine to ignore the result then
765 // too. See http://crbug.com/546222 for progress of changing the ownership
766 // of the WebStates.
767 ignore_result(_webStateList->DetachWebStateAt(closedTabIndex));
768
769 if (needToSaveSession)
770 [self saveSessionImmediately:NO];
771 }
772
773 - (void)navigationCommittedInTab:(Tab*)tab 652 - (void)navigationCommittedInTab:(Tab*)tab
774 previousItem:(web::NavigationItem*)previousItem { 653 previousItem:(web::NavigationItem*)previousItem {
775 if (self.offTheRecord) 654 if (self.offTheRecord)
776 return; 655 return;
777 if (![tab navigationManager]) 656 if (![tab navigationManager])
778 return; 657 return;
779 658
780 // See if the navigation was within a page; if so ignore it. 659 // See if the navigation was within a page; if so ignore it.
781 if (previousItem) { 660 if (previousItem) {
782 GURL previousURL = previousItem->GetURL(); 661 GURL previousURL = previousItem->GetURL();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 // fg tab. Do it now. 701 // fg tab. Do it now.
823 [self.currentTab recordStateInHistory]; 702 [self.currentTab recordStateInHistory];
824 703
825 // Build the array of sessions. Copy the session objects as the saving will 704 // Build the array of sessions. Copy the session objects as the saving will
826 // be done on a separate thread. 705 // be done on a separate thread.
827 // TODO(crbug.com/661986): This could get expensive especially since this 706 // TODO(crbug.com/661986): This could get expensive especially since this
828 // window may never be saved (if another call comes in before the delay). 707 // window may never be saved (if another call comes in before the delay).
829 NSMutableArray<CRWSessionStorage*>* sessions = 708 NSMutableArray<CRWSessionStorage*>* sessions =
830 [NSMutableArray arrayWithCapacity:[self count]]; 709 [NSMutableArray arrayWithCapacity:[self count]];
831 710
832 for (Tab* tab in self) { 711 for (int index = 0; index < _webStateList->count(); ++index) {
833 DCHECK(tab.webState); 712 web::WebState* webState = _webStateList->GetWebStateAt(index);
834 [sessions addObject:tab.webState->BuildSessionStorage()]; 713 web::SerializableUserDataManager* userDataManager =
714 web::SerializableUserDataManager::FromWebState(webState);
715
716 WebStateOpener opener = _webStateList->GetOpenerOfWebStateAt(index);
717 if (opener.opener) {
718 Tab* parentTab = LegacyTabHelper::GetTabForWebState(opener.opener);
719 userDataManager->AddSerializableData(parentTab.tabId, kOpenerIDKey);
720 userDataManager->AddSerializableData(@(opener.navigation_index),
721 kOpenerNavigationIndexKey);
722 } else {
723 userDataManager->AddSerializableData([NSNull null], kOpenerIDKey);
724 userDataManager->AddSerializableData([NSNull null],
725 kOpenerNavigationIndexKey);
726 }
727
728 [sessions addObject:webState->BuildSessionStorage()];
835 } 729 }
836 730
837 return [[[SessionWindowIOS alloc] 731 return [[[SessionWindowIOS alloc]
838 initWithSessions:sessions 732 initWithSessions:sessions
839 selectedIndex:[self indexOfTab:self.currentTab]] autorelease]; 733 selectedIndex:[self indexOfTab:self.currentTab]] autorelease];
840 } 734 }
841 735
842 - (BOOL)isNTPTab:(Tab*)tab {
843 std::string host = tab.url.host();
844 return host == kChromeUINewTabHost || host == kChromeUIBookmarksHost;
845 }
846
847 - (void)postNotificationName:(NSString*)notificationName withTab:(Tab*)tab { 736 - (void)postNotificationName:(NSString*)notificationName withTab:(Tab*)tab {
848 // A scoped_nsobject is used rather than an NSDictionary with static 737 // A scoped_nsobject is used rather than an NSDictionary with static
849 // initializer dictionaryWithObject, because that approach adds the dictionary 738 // initializer dictionaryWithObject, because that approach adds the dictionary
850 // to the autorelease pool, which in turn holds Tab alive longer than 739 // to the autorelease pool, which in turn holds Tab alive longer than
851 // necessary. 740 // necessary.
852 base::scoped_nsobject<NSDictionary> userInfo( 741 base::scoped_nsobject<NSDictionary> userInfo(
853 [[NSDictionary alloc] initWithObjectsAndKeys:tab, kTabModelTabKey, nil]); 742 [[NSDictionary alloc] initWithObjectsAndKeys:tab, kTabModelTabKey, nil]);
854 [[NSNotificationCenter defaultCenter] postNotificationName:notificationName 743 [[NSNotificationCenter defaultCenter] postNotificationName:notificationName
855 object:self 744 object:self
856 userInfo:userInfo]; 745 userInfo:userInfo];
(...skipping 17 matching lines...) Expand all
874 763
875 base::scoped_nsobject<NSMutableArray<Tab*>> restoredTabs( 764 base::scoped_nsobject<NSMutableArray<Tab*>> restoredTabs(
876 [[NSMutableArray alloc] initWithCapacity:sessions.count]); 765 [[NSMutableArray alloc] initWithCapacity:sessions.count]);
877 766
878 // Recreate all the restored Tabs and add them to the WebStateList without 767 // Recreate all the restored Tabs and add them to the WebStateList without
879 // any opener-opened relationship (as the n-th restored Tab opener may be 768 // any opener-opened relationship (as the n-th restored Tab opener may be
880 // at an index larger than n). Then in a second pass fix the openers. 769 // at an index larger than n). Then in a second pass fix the openers.
881 for (CRWSessionStorage* session in sessions) { 770 for (CRWSessionStorage* session in sessions) {
882 std::unique_ptr<web::WebState> webState = 771 std::unique_ptr<web::WebState> webState =
883 web::WebState::Create(params, session); 772 web::WebState::Create(params, session);
884 base::scoped_nsobject<Tab> tab( 773 _webStateList->InsertWebState(_webStateList->count(), std::move(webState));
885 [[Tab alloc] initWithWebState:std::move(webState) model:self]); 774 }
886 [tab webController].webUsageEnabled = webUsageEnabled_; 775
887 [tab webController].usePlaceholderOverlay = YES; 776 for (int index = oldCount; index < _webStateList->count(); ++index) {
777 web::WebState* webState = _webStateList->GetWebStateAt(index);
778 Tab* tab = LegacyTabHelper::GetTabForWebState(webState);
779 tab.webController.webUsageEnabled = webUsageEnabled_;
780 tab.webController.usePlaceholderOverlay = YES;
888 781
889 // Restore the CertificatePolicyCache (note that webState is invalid after 782 // Restore the CertificatePolicyCache (note that webState is invalid after
890 // passing it via move semantic to -initWithWebState:model:). 783 // passing it via move semantic to -initWithWebState:model:).
891 UpdateCertificatePolicyCacheFromWebState(policyCache, [tab webState]); 784 UpdateCertificatePolicyCacheFromWebState(policyCache, [tab webState]);
892 [self insertTab:tab atIndex:self.count opener:nil]; 785 [restoredTabs addObject:tab];
893 [restoredTabs addObject:tab.get()];
894 } 786 }
895 787
896 DCHECK_EQ(sessions.count, [restoredTabs count]); 788 DCHECK_EQ(sessions.count, [restoredTabs count]);
897 DCHECK_GT(_webStateList->count(), oldCount); 789 DCHECK_GT(_webStateList->count(), oldCount);
898 790
899 // Fix openers now that all Tabs have been restored. Only look for an opener 791 // Fix openers now that all Tabs have been restored. Only look for an opener
900 // Tab in the newly restored Tabs and not in the already open Tabs. 792 // Tab in the newly restored Tabs and not in the already open Tabs.
901 for (int index = oldCount; index < _webStateList->count(); ++index) { 793 for (int index = oldCount; index < _webStateList->count(); ++index) {
902 DCHECK_GE(index, oldCount); 794 DCHECK_GE(index, oldCount);
903 NSUInteger tabIndex = static_cast<NSUInteger>(index - oldCount); 795 NSUInteger tabIndex = static_cast<NSUInteger>(index - oldCount);
904 Tab* tab = [restoredTabs objectAtIndex:tabIndex]; 796 Tab* tab = [restoredTabs objectAtIndex:tabIndex];
905 Tab* opener = GetOpenerForTab(restoredTabs.get(), tab); 797 WebStateOpener opener = GetOpenerForTab(restoredTabs.get(), tab);
906 if (opener) { 798 if (opener.opener)
907 DCHECK(opener.webState); 799 _webStateList->SetOpenerOfWebStateAt(index, opener);
908 _webStateList->SetOpenerOfWebStateAt(
909 index, WebStateOpener(opener.webState, tab.openerNavigationIndex));
910 }
911 } 800 }
912 801
913 // Update the selected tab if there was a selected Tab in the saved session. 802 // Update the selected tab if there was a selected Tab in the saved session.
914 if (window.selectedIndex != NSNotFound) { 803 if (window.selectedIndex != NSNotFound) {
915 NSUInteger selectedIndex = window.selectedIndex + oldCount; 804 NSUInteger selectedIndex = window.selectedIndex + oldCount;
916 DCHECK_LT(selectedIndex, self.count); 805 DCHECK_LT(selectedIndex, self.count);
917 DCHECK([self tabAtIndex:selectedIndex]); 806 DCHECK([self tabAtIndex:selectedIndex]);
918 807
919 if (persistState && self.currentTab) 808 if (persistState && self.currentTab)
920 [self.currentTab recordStateInHistory]; 809 [self.currentTab recordStateInHistory];
921 _webStateList->ActivateWebStateAt(static_cast<int>(selectedIndex)); 810 _webStateList->ActivateWebStateAt(static_cast<int>(selectedIndex));
922 } 811 }
923 812
924 // If there was only one tab and it was the new tab page, clobber it. 813 // If there was only one tab and it was the new tab page, clobber it.
925 BOOL closedNTPTab = NO; 814 BOOL closedNTPTab = NO;
926 if (oldCount == 1) { 815 if (oldCount == 1) {
927 Tab* tab = [self tabAtIndex:0]; 816 Tab* tab = [self tabAtIndex:0];
928 if (tab.url == GURL(kChromeUINewTabURL)) { 817 if (tab.url == GURL(kChromeUINewTabURL)) {
929 [self closeTab:tab]; 818 [self closeTab:tab];
930 closedNTPTab = YES; 819 closedNTPTab = YES;
931 oldCount = 0; 820 oldCount = 0;
932 } 821 }
933 } 822 }
934 if (_tabUsageRecorder) { 823 if (_tabUsageRecorder)
935 NSMutableArray<Tab*>* restoredTabs =
936 [NSMutableArray arrayWithCapacity:_webStateList->count() - oldCount];
937 for (int index = oldCount; index < _webStateList->count(); ++index) {
938 web::WebState* webState = _webStateList->GetWebStateAt(index);
939 [restoredTabs addObject:LegacyTabHelper::GetTabForWebState(webState)];
940 }
941 _tabUsageRecorder->InitialRestoredTabs(self.currentTab, restoredTabs); 824 _tabUsageRecorder->InitialRestoredTabs(self.currentTab, restoredTabs);
942 }
943 return closedNTPTab; 825 return closedNTPTab;
944 } 826 }
945 827
946 #pragma mark - Notification Handlers 828 #pragma mark - Notification Handlers
947 829
948 // Called when UIApplicationWillResignActiveNotification is received. 830 // Called when UIApplicationWillResignActiveNotification is received.
949 - (void)willResignActive:(NSNotification*)notify { 831 - (void)willResignActive:(NSNotification*)notify {
950 if (webUsageEnabled_ && self.currentTab) { 832 if (webUsageEnabled_ && self.currentTab) {
951 [[SnapshotCache sharedInstance] 833 [[SnapshotCache sharedInstance]
952 willBeSavedGreyWhenBackgrounding:self.currentTab.tabId]; 834 willBeSavedGreyWhenBackgrounding:self.currentTab.tabId];
(...skipping 28 matching lines...) Expand all
981 } 863 }
982 864
983 // Called when UIApplicationWillEnterForegroundNotification is received. 865 // Called when UIApplicationWillEnterForegroundNotification is received.
984 - (void)applicationWillEnterForeground:(NSNotification*)notify { 866 - (void)applicationWillEnterForeground:(NSNotification*)notify {
985 if (_tabUsageRecorder) { 867 if (_tabUsageRecorder) {
986 _tabUsageRecorder->AppWillEnterForeground(); 868 _tabUsageRecorder->AppWillEnterForeground();
987 } 869 }
988 } 870 }
989 871
990 @end 872 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698