| 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 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #import "base/mac/scoped_nsobject.h" | 13 #import "base/mac/scoped_nsobject.h" |
| 14 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
| 15 #include "base/metrics/user_metrics.h" | 15 #include "base/metrics/user_metrics.h" |
| 16 #include "base/metrics/user_metrics_action.h" | 16 #include "base/metrics/user_metrics_action.h" |
| 17 #include "base/strings/sys_string_conversions.h" | 17 #include "base/strings/sys_string_conversions.h" |
| 18 #include "base/task/cancelable_task_tracker.h" | 18 #include "base/task/cancelable_task_tracker.h" |
| 19 #include "components/sessions/core/serialized_navigation_entry.h" | 19 #include "components/sessions/core/serialized_navigation_entry.h" |
| 20 #include "components/sessions/core/session_id.h" | 20 #include "components/sessions/core/session_id.h" |
| 21 #include "components/sessions/core/tab_restore_service.h" | 21 #include "components/sessions/core/tab_restore_service.h" |
| 22 #include "components/sessions/ios/ios_live_tab.h" | 22 #include "components/sessions/ios/ios_live_tab.h" |
| 23 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" | 23 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" |
| 24 #include "ios/chrome/browser/chrome_url_constants.h" | 24 #include "ios/chrome/browser/chrome_url_constants.h" |
| 25 #import "ios/chrome/browser/chrome_url_util.h" | 25 #import "ios/chrome/browser/chrome_url_util.h" |
| 26 #import "ios/chrome/browser/metrics/tab_usage_recorder.h" | 26 #import "ios/chrome/browser/metrics/tab_usage_recorder.h" |
| 27 #import "ios/chrome/browser/metrics/tab_usage_recorder_web_state_list_observer.h
" |
| 27 #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h" | 28 #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h" |
| 28 #import "ios/chrome/browser/sessions/session_service.h" | 29 #import "ios/chrome/browser/sessions/session_service.h" |
| 29 #import "ios/chrome/browser/sessions/session_window.h" | 30 #import "ios/chrome/browser/sessions/session_window.h" |
| 30 #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" |
| 31 #include "ios/chrome/browser/tab_parenting_global_observer.h" | 33 #include "ios/chrome/browser/tab_parenting_global_observer.h" |
| 32 #import "ios/chrome/browser/tabs/legacy_tab_helper.h" | 34 #import "ios/chrome/browser/tabs/legacy_tab_helper.h" |
| 33 #import "ios/chrome/browser/tabs/tab.h" | 35 #import "ios/chrome/browser/tabs/tab.h" |
| 34 #import "ios/chrome/browser/tabs/tab_model_list.h" | 36 #import "ios/chrome/browser/tabs/tab_model_list.h" |
| 35 #import "ios/chrome/browser/tabs/tab_model_observers.h" | 37 #import "ios/chrome/browser/tabs/tab_model_observers.h" |
| 36 #import "ios/chrome/browser/tabs/tab_model_observers_bridge.h" | 38 #import "ios/chrome/browser/tabs/tab_model_observers_bridge.h" |
| 37 #import "ios/chrome/browser/tabs/tab_model_order_controller.h" | 39 #import "ios/chrome/browser/tabs/tab_model_selected_tab_observer.h" |
| 38 #import "ios/chrome/browser/tabs/tab_model_synced_window_delegate.h" | 40 #import "ios/chrome/browser/tabs/tab_model_synced_window_delegate.h" |
| 39 #import "ios/chrome/browser/tabs/tab_parenting_observer.h" | 41 #import "ios/chrome/browser/tabs/tab_parenting_observer.h" |
| 40 #import "ios/chrome/browser/xcallback_parameters.h" | 42 #import "ios/chrome/browser/xcallback_parameters.h" |
| 41 #import "ios/shared/chrome/browser/tabs/web_state_list.h" | 43 #import "ios/shared/chrome/browser/tabs/web_state_list.h" |
| 42 #import "ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper.h
" | 44 #import "ios/shared/chrome/browser/tabs/web_state_list_fast_enumeration_helper.h
" |
| 43 #import "ios/shared/chrome/browser/tabs/web_state_list_metrics_observer.h" | 45 #import "ios/shared/chrome/browser/tabs/web_state_list_metrics_observer.h" |
| 44 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h" | 46 #import "ios/shared/chrome/browser/tabs/web_state_list_observer.h" |
| 45 #import "ios/web/navigation/crw_session_certificate_policy_manager.h" | 47 #import "ios/web/navigation/crw_session_certificate_policy_manager.h" |
| 46 #import "ios/web/navigation/crw_session_controller.h" | 48 #import "ios/web/navigation/crw_session_controller.h" |
| 47 #include "ios/web/public/browser_state.h" | 49 #include "ios/web/public/browser_state.h" |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 | 159 |
| 158 // Used to keep the Tabs alive while the corresponding WebStates are stored | 160 // Used to keep the Tabs alive while the corresponding WebStates are stored |
| 159 // in the WebStateList (as Tabs currently own their WebState). Remove once | 161 // in the WebStateList (as Tabs currently own their WebState). Remove once |
| 160 // WebState owns the associated Tab. | 162 // WebState owns the associated Tab. |
| 161 base::scoped_nsobject<NSMutableSet<Tab*>> _tabRetainer; | 163 base::scoped_nsobject<NSMutableSet<Tab*>> _tabRetainer; |
| 162 | 164 |
| 163 // WebStateListObserver bridges to react to modifications of the model (may | 165 // WebStateListObserver bridges to react to modifications of the model (may |
| 164 // send notification, translate and forward events, update metrics, ...). | 166 // send notification, translate and forward events, update metrics, ...). |
| 165 std::vector<std::unique_ptr<WebStateListObserver>> _observerBridges; | 167 std::vector<std::unique_ptr<WebStateListObserver>> _observerBridges; |
| 166 | 168 |
| 167 // Maintains policy for where new tabs go and the selection when a tab | |
| 168 // is removed. | |
| 169 base::scoped_nsobject<TabModelOrderController> _orderController; | |
| 170 // The delegate for sync. | 169 // The delegate for sync. |
| 171 std::unique_ptr<TabModelSyncedWindowDelegate> _syncedWindowDelegate; | 170 std::unique_ptr<TabModelSyncedWindowDelegate> _syncedWindowDelegate; |
| 172 // Currently selected tab. May be nil. | |
| 173 base::WeakNSObject<Tab> _currentTab; | |
| 174 | 171 |
| 175 // Counters for metrics. | 172 // Counters for metrics. |
| 176 int _openedTabCount; | 173 WebStateListMetricsObserver* _webStateListMetricsObserver; |
| 177 int _closedTabCount; | |
| 178 int _newTabCount; | |
| 179 | 174 |
| 180 // Backs up property with the same name. | 175 // Backs up property with the same name. |
| 181 std::unique_ptr<TabUsageRecorder> _tabUsageRecorder; | 176 std::unique_ptr<TabUsageRecorder> _tabUsageRecorder; |
| 182 // Backs up property with the same name. | 177 // Backs up property with the same name. |
| 183 const SessionID _sessionID; | 178 const SessionID _sessionID; |
| 184 // Saves session's state. | 179 // Saves session's state. |
| 185 base::scoped_nsobject<SessionServiceIOS> _sessionService; | 180 base::scoped_nsobject<SessionServiceIOS> _sessionService; |
| 186 // List of TabModelObservers. | 181 // List of TabModelObservers. |
| 187 base::scoped_nsobject<TabModelObservers> _observers; | 182 base::scoped_nsobject<TabModelObservers> _observers; |
| 188 | 183 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 205 // TabModelConstants::kTabPositionAutomatically if the caller doesn't have a | 200 // TabModelConstants::kTabPositionAutomatically if the caller doesn't have a |
| 206 // preference for the position of the tab. | 201 // preference for the position of the tab. |
| 207 - (Tab*)insertTabWithLoadParams: | 202 - (Tab*)insertTabWithLoadParams: |
| 208 (const web::NavigationManager::WebLoadParams&)params | 203 (const web::NavigationManager::WebLoadParams&)params |
| 209 windowName:(NSString*)windowName | 204 windowName:(NSString*)windowName |
| 210 opener:(Tab*)parentTab | 205 opener:(Tab*)parentTab |
| 211 openedByDOM:(BOOL)openedByDOM | 206 openedByDOM:(BOOL)openedByDOM |
| 212 atIndex:(NSUInteger)index | 207 atIndex:(NSUInteger)index |
| 213 inBackground:(BOOL)inBackground; | 208 inBackground:(BOOL)inBackground; |
| 214 | 209 |
| 215 // Call to switch the selected tab. Broadcasts about the change in selection. | |
| 216 // It's ok for |newTab| to be nil in case the last tab is going away. In that | |
| 217 // case, the "tab deselected" notification gets sent, but no corresponding | |
| 218 // "tab selected" notification is sent. |persist| indicates whether or not | |
| 219 // the tab's state should be persisted in history upon switching. | |
| 220 - (void)changeSelectedTabFrom:(Tab*)oldTab | |
| 221 to:(Tab*)newTab | |
| 222 persistState:(BOOL)persist; | |
| 223 | |
| 224 // Tells the snapshot cache the adjacent tab session ids. | |
| 225 - (void)updateSnapshotCache:(Tab*)tab; | |
| 226 | |
| 227 // Helper method that posts a notification with the given name with |tab| | 210 // Helper method that posts a notification with the given name with |tab| |
| 228 // in the userInfo dictionary under the kTabModelTabKey. | 211 // in the userInfo dictionary under the kTabModelTabKey. |
| 229 - (void)postNotificationName:(NSString*)notificationName withTab:(Tab*)tab; | 212 - (void)postNotificationName:(NSString*)notificationName withTab:(Tab*)tab; |
| 230 | 213 |
| 231 // Helper method to restore a saved session and control if the state should | 214 // Helper method to restore a saved session and control if the state should |
| 232 // be persisted or not. Used to implement the public -restoreSessionWindow: | 215 // be persisted or not. Used to implement the public -restoreSessionWindow: |
| 233 // method and restoring session in the initialiser. | 216 // method and restoring session in the initialiser. |
| 234 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window | 217 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window |
| 235 persistState:(BOOL)persistState; | 218 persistState:(BOOL)persistState; |
| 236 | 219 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 259 | 242 |
| 260 #pragma mark - Overriden | 243 #pragma mark - Overriden |
| 261 | 244 |
| 262 - (void)dealloc { | 245 - (void)dealloc { |
| 263 DCHECK([_observers empty]); | 246 DCHECK([_observers empty]); |
| 264 // browserStateDestroyed should always have been called before destruction. | 247 // browserStateDestroyed should always have been called before destruction. |
| 265 DCHECK(!_browserState); | 248 DCHECK(!_browserState); |
| 266 | 249 |
| 267 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 250 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 268 | 251 |
| 252 // Clear weak pointer to WebStateListMetricsObserver before destroying it. |
| 253 _webStateListMetricsObserver = nullptr; |
| 254 |
| 269 // Unregister all listeners before closing all the tabs. | 255 // Unregister all listeners before closing all the tabs. |
| 270 for (const auto& observerBridge : _observerBridges) | 256 for (const auto& observerBridge : _observerBridges) |
| 271 _webStateList.RemoveObserver(observerBridge.get()); | 257 _webStateList.RemoveObserver(observerBridge.get()); |
| 272 _observerBridges.clear(); | 258 _observerBridges.clear(); |
| 273 | 259 |
| 274 // Make sure the tabs do clean after themselves. It is important for | 260 // Make sure the tabs do clean after themselves. It is important for |
| 275 // removeObserver: to be called first otherwise a lot of unecessary work will | 261 // removeObserver: to be called first otherwise a lot of unecessary work will |
| 276 // happen on -closeAllTabs. | 262 // happen on -closeAllTabs. |
| 277 [self closeAllTabs]; | 263 [self closeAllTabs]; |
| 278 | 264 |
| 279 _clearPoliciesTaskTracker.TryCancelAll(); | 265 _clearPoliciesTaskTracker.TryCancelAll(); |
| 280 | 266 |
| 281 [super dealloc]; | 267 [super dealloc]; |
| 282 } | 268 } |
| 283 | 269 |
| 284 #pragma mark - Public methods | 270 #pragma mark - Public methods |
| 285 | 271 |
| 286 - (Tab*)currentTab { | 272 - (Tab*)currentTab { |
| 287 return _currentTab.get(); | 273 web::WebState* webState = _webStateList.GetActiveWebState(); |
| 274 return webState ? LegacyTabHelper::GetTabForWebState(webState) : nil; |
| 288 } | 275 } |
| 289 | 276 |
| 290 - (void)setCurrentTab:(Tab*)newTab { | 277 - (void)setCurrentTab:(Tab*)newTab { |
| 291 DCHECK_NE([self indexOfTab:newTab], static_cast<NSUInteger>(NSNotFound)); | 278 int indexOfTab = _webStateList.GetIndexOfWebState(newTab.webState); |
| 292 if (_currentTab != newTab) { | 279 DCHECK_NE(indexOfTab, WebStateList::kInvalidIndex); |
| 293 base::RecordAction(base::UserMetricsAction("MobileTabSwitched")); | 280 _webStateList.ActivateWebStateAt(indexOfTab); |
| 294 [self updateSnapshotCache:newTab]; | |
| 295 } | |
| 296 if (_tabUsageRecorder) { | |
| 297 _tabUsageRecorder->RecordTabSwitched(_currentTab, newTab); | |
| 298 } | |
| 299 [self changeSelectedTabFrom:_currentTab to:newTab persistState:YES]; | |
| 300 } | 281 } |
| 301 | 282 |
| 302 - (TabModelSyncedWindowDelegate*)syncedWindowDelegate { | 283 - (TabModelSyncedWindowDelegate*)syncedWindowDelegate { |
| 303 return _syncedWindowDelegate.get(); | 284 return _syncedWindowDelegate.get(); |
| 304 } | 285 } |
| 305 | 286 |
| 306 - (TabUsageRecorder*)tabUsageRecorder { | 287 - (TabUsageRecorder*)tabUsageRecorder { |
| 307 return _tabUsageRecorder.get(); | 288 return _tabUsageRecorder.get(); |
| 308 } | 289 } |
| 309 | 290 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 // Set up the usage recorder before tabs are created. | 322 // Set up the usage recorder before tabs are created. |
| 342 _tabUsageRecorder = base::MakeUnique<TabUsageRecorder>(self); | 323 _tabUsageRecorder = base::MakeUnique<TabUsageRecorder>(self); |
| 343 } | 324 } |
| 344 _syncedWindowDelegate = | 325 _syncedWindowDelegate = |
| 345 base::MakeUnique<TabModelSyncedWindowDelegate>(self); | 326 base::MakeUnique<TabModelSyncedWindowDelegate>(self); |
| 346 | 327 |
| 347 // There must be a valid session service defined to consume session windows. | 328 // There must be a valid session service defined to consume session windows. |
| 348 DCHECK(service); | 329 DCHECK(service); |
| 349 _sessionService.reset([service retain]); | 330 _sessionService.reset([service retain]); |
| 350 | 331 |
| 332 _observerBridges.push_back( |
| 333 base::MakeUnique<SnapshotCacheWebStateListObserver>( |
| 334 [SnapshotCache sharedInstance])); |
| 335 if (_tabUsageRecorder) { |
| 336 _observerBridges.push_back( |
| 337 base::MakeUnique<TabUsageRecorderWebStateListObserver>( |
| 338 _tabUsageRecorder.get())); |
| 339 } |
| 351 _observerBridges.push_back(base::MakeUnique<TabParentingObserver>()); | 340 _observerBridges.push_back(base::MakeUnique<TabParentingObserver>()); |
| 352 _observerBridges.push_back(base::MakeUnique<WebStateListObserverBridge>( | 341 _observerBridges.push_back(base::MakeUnique<WebStateListObserverBridge>( |
| 342 [[TabModelSelectedTabObserver alloc] initWithTabModel:self])); |
| 343 _observerBridges.push_back(base::MakeUnique<WebStateListObserverBridge>( |
| 353 [[TabModelObserversBridge alloc] initWithTabModel:self | 344 [[TabModelObserversBridge alloc] initWithTabModel:self |
| 354 tabModelObservers:_observers.get()])); | 345 tabModelObservers:_observers.get()])); |
| 355 _observerBridges.push_back(base::MakeUnique<WebStateListMetricsObserver>()); | 346 |
| 347 auto webStateListMetricsObserver = |
| 348 base::MakeUnique<WebStateListMetricsObserver>(); |
| 349 _webStateListMetricsObserver = webStateListMetricsObserver.get(); |
| 350 _observerBridges.push_back(std::move(webStateListMetricsObserver)); |
| 356 | 351 |
| 357 for (const auto& observerBridge : _observerBridges) | 352 for (const auto& observerBridge : _observerBridges) |
| 358 _webStateList.AddObserver(observerBridge.get()); | 353 _webStateList.AddObserver(observerBridge.get()); |
| 359 | 354 |
| 360 if (window) { | 355 if (window) { |
| 361 DCHECK([_observers empty]); | 356 DCHECK([_observers empty]); |
| 362 // Restore the session and reset the session metrics (as the event have | 357 // Restore the session and reset the session metrics (as the event have |
| 363 // not been generated by the user but by a cold start cycle). | 358 // not been generated by the user but by a cold start cycle). |
| 364 [self restoreSessionWindow:window persistState:NO]; | 359 [self restoreSessionWindow:window persistState:NO]; |
| 365 [self resetSessionMetrics]; | 360 [self resetSessionMetrics]; |
| 366 } | 361 } |
| 367 | 362 |
| 368 _orderController.reset( | |
| 369 [[TabModelOrderController alloc] initWithTabModel:self]); | |
| 370 | |
| 371 // Register for resign active notification. | 363 // Register for resign active notification. |
| 372 [[NSNotificationCenter defaultCenter] | 364 [[NSNotificationCenter defaultCenter] |
| 373 addObserver:self | 365 addObserver:self |
| 374 selector:@selector(willResignActive:) | 366 selector:@selector(willResignActive:) |
| 375 name:UIApplicationWillResignActiveNotification | 367 name:UIApplicationWillResignActiveNotification |
| 376 object:nil]; | 368 object:nil]; |
| 377 // Register for background notification. | 369 // Register for background notification. |
| 378 [[NSNotificationCenter defaultCenter] | 370 [[NSNotificationCenter defaultCenter] |
| 379 addObserver:self | 371 addObserver:self |
| 380 selector:@selector(applicationDidEnterBackground:) | 372 selector:@selector(applicationDidEnterBackground:) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 398 return nil; | 390 return nil; |
| 399 } | 391 } |
| 400 | 392 |
| 401 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window { | 393 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window { |
| 402 return [self restoreSessionWindow:window persistState:YES]; | 394 return [self restoreSessionWindow:window persistState:YES]; |
| 403 } | 395 } |
| 404 | 396 |
| 405 - (void)saveSessionImmediately:(BOOL)immediately { | 397 - (void)saveSessionImmediately:(BOOL)immediately { |
| 406 // Do nothing if there are tabs in the model but no selected tab. This is | 398 // Do nothing if there are tabs in the model but no selected tab. This is |
| 407 // a transitional state. | 399 // a transitional state. |
| 408 if ((!_currentTab && _webStateList.count()) || !_browserState) | 400 if ((!self.currentTab && _webStateList.count()) || !_browserState) |
| 409 return; | 401 return; |
| 410 [_sessionService saveWindow:self.windowForSavingSession | 402 [_sessionService saveWindow:self.windowForSavingSession |
| 411 forBrowserState:_browserState | 403 forBrowserState:_browserState |
| 412 immediately:immediately]; | 404 immediately:immediately]; |
| 413 } | 405 } |
| 414 | 406 |
| 415 - (Tab*)tabAtIndex:(NSUInteger)index { | 407 - (Tab*)tabAtIndex:(NSUInteger)index { |
| 416 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); | 408 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); |
| 417 return LegacyTabHelper::GetTabForWebState( | 409 return LegacyTabHelper::GetTabForWebState( |
| 418 _webStateList.GetWebStateAt(static_cast<int>(index))); | 410 _webStateList.GetWebStateAt(static_cast<int>(index))); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 const int insertion_index = static_cast<int>(index); | 569 const int insertion_index = static_cast<int>(index); |
| 578 _webStateList.InsertWebState(insertion_index, tab.webState, | 570 _webStateList.InsertWebState(insertion_index, tab.webState, |
| 579 parentTab.webState); | 571 parentTab.webState); |
| 580 } | 572 } |
| 581 | 573 |
| 582 // Persist the session due to a new tab being inserted. If this is a | 574 // Persist the session due to a new tab being inserted. If this is a |
| 583 // background tab (will not become active), saving now will capture the | 575 // background tab (will not become active), saving now will capture the |
| 584 // state properly. If it does eventually become active, another save will | 576 // state properly. If it does eventually become active, another save will |
| 585 // be triggered to properly capture the end result. | 577 // be triggered to properly capture the end result. |
| 586 [self saveSessionImmediately:NO]; | 578 [self saveSessionImmediately:NO]; |
| 587 | |
| 588 ++_newTabCount; | |
| 589 } | 579 } |
| 590 | 580 |
| 591 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index opener:(Tab*)parentTab { | 581 - (void)insertTab:(Tab*)tab atIndex:(NSUInteger)index opener:(Tab*)parentTab { |
| 592 DCHECK(tab); | 582 DCHECK(tab); |
| 593 DCHECK(![_tabRetainer containsObject:tab]); | 583 DCHECK(![_tabRetainer containsObject:tab]); |
| 594 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); | 584 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); |
| 595 | 585 |
| 596 [self insertTab:tab | 586 [self insertTab:tab |
| 597 atIndex:index | 587 atIndex:index |
| 598 opener:parentTab | 588 opener:parentTab |
| (...skipping 24 matching lines...) Expand all Loading... |
| 623 DCHECK_GE(index, 0); | 613 DCHECK_GE(index, 0); |
| 624 | 614 |
| 625 base::scoped_nsobject<Tab> tabSaver([oldTab retain]); | 615 base::scoped_nsobject<Tab> tabSaver([oldTab retain]); |
| 626 [_tabRetainer removeObject:oldTab]; | 616 [_tabRetainer removeObject:oldTab]; |
| 627 [_tabRetainer addObject:newTab]; | 617 [_tabRetainer addObject:newTab]; |
| 628 [newTab setParentTabModel:self]; | 618 [newTab setParentTabModel:self]; |
| 629 | 619 |
| 630 _webStateList.ReplaceWebStateAt(index, newTab.webState, | 620 _webStateList.ReplaceWebStateAt(index, newTab.webState, |
| 631 GetOpenerForTab(self, newTab).webState); | 621 GetOpenerForTab(self, newTab).webState); |
| 632 | 622 |
| 633 if (self.currentTab == oldTab) | |
| 634 [self changeSelectedTabFrom:nil to:newTab persistState:NO]; | |
| 635 | |
| 636 [oldTab setParentTabModel:nil]; | 623 [oldTab setParentTabModel:nil]; |
| 637 [oldTab close]; | 624 [oldTab close]; |
| 638 } | 625 } |
| 639 | 626 |
| 640 - (void)closeTabAtIndex:(NSUInteger)index { | 627 - (void)closeTabAtIndex:(NSUInteger)index { |
| 641 DCHECK(index < self.count); | 628 DCHECK(index < self.count); |
| 642 [self closeTab:[self tabAtIndex:index]]; | 629 [self closeTab:[self tabAtIndex:index]]; |
| 643 } | 630 } |
| 644 | 631 |
| 645 - (void)closeTab:(Tab*)tab { | 632 - (void)closeTab:(Tab*)tab { |
| 646 // Ensure the tab stays alive long enough for us to send out the | 633 // Ensure the tab stays alive long enough for us to send out the |
| 647 // notice of its destruction to the delegate. | 634 // notice of its destruction to the delegate. |
| 648 [_observers tabModel:self willRemoveTab:tab]; | 635 [_observers tabModel:self willRemoveTab:tab]; |
| 649 [tab close]; // Note it is not safe to access the tab after 'close'. | 636 [tab close]; // Note it is not safe to access the tab after 'close'. |
| 650 } | 637 } |
| 651 | 638 |
| 652 - (void)closeAllTabs { | 639 - (void)closeAllTabs { |
| 653 // If this changes, _closedTabCount metrics need to be adjusted. | |
| 654 for (NSInteger i = self.count - 1; i >= 0; --i) | 640 for (NSInteger i = self.count - 1; i >= 0; --i) |
| 655 [self closeTabAtIndex:i]; | 641 [self closeTabAtIndex:i]; |
| 656 [[NSNotificationCenter defaultCenter] | 642 [[NSNotificationCenter defaultCenter] |
| 657 postNotificationName:kTabModelAllTabsDidCloseNotification | 643 postNotificationName:kTabModelAllTabsDidCloseNotification |
| 658 object:self]; | 644 object:self]; |
| 659 } | 645 } |
| 660 | 646 |
| 661 - (void)haltAllTabs { | 647 - (void)haltAllTabs { |
| 662 for (Tab* tab in self) { | 648 for (Tab* tab in self) { |
| 663 [tab terminateNetworkActivity]; | 649 [tab terminateNetworkActivity]; |
| 664 } | 650 } |
| 665 } | 651 } |
| 666 | 652 |
| 667 - (void)notifyTabChanged:(Tab*)tab { | 653 - (void)notifyTabChanged:(Tab*)tab { |
| 668 [_observers tabModel:self didChangeTab:tab]; | 654 [_observers tabModel:self didChangeTab:tab]; |
| 669 } | 655 } |
| 670 | 656 |
| 671 - (void)addObserver:(id<TabModelObserver>)observer { | 657 - (void)addObserver:(id<TabModelObserver>)observer { |
| 672 [_observers addObserver:observer]; | 658 [_observers addObserver:observer]; |
| 673 } | 659 } |
| 674 | 660 |
| 675 - (void)removeObserver:(id<TabModelObserver>)observer { | 661 - (void)removeObserver:(id<TabModelObserver>)observer { |
| 676 [_observers removeObserver:observer]; | 662 [_observers removeObserver:observer]; |
| 677 } | 663 } |
| 678 | 664 |
| 679 - (void)resetSessionMetrics { | 665 - (void)resetSessionMetrics { |
| 680 _closedTabCount = 0; | 666 if (_webStateListMetricsObserver) |
| 681 _openedTabCount = 0; | 667 _webStateListMetricsObserver->ResetSessionMetrics(); |
| 682 _newTabCount = 0; | |
| 683 } | 668 } |
| 684 | 669 |
| 685 - (void)recordSessionMetrics { | 670 - (void)recordSessionMetrics { |
| 686 UMA_HISTOGRAM_CUSTOM_COUNTS("Session.ClosedTabCounts", _closedTabCount, 1, | 671 if (_webStateListMetricsObserver) |
| 687 200, 50); | 672 _webStateListMetricsObserver->RecordSessionMetrics(); |
| 688 UMA_HISTOGRAM_CUSTOM_COUNTS("Session.OpenedTabCounts", _openedTabCount, 1, | |
| 689 200, 50); | |
| 690 UMA_HISTOGRAM_CUSTOM_COUNTS("Session.NewTabCounts", _newTabCount, 1, 200, 50); | |
| 691 } | 673 } |
| 692 | 674 |
| 693 - (void)notifyTabSnapshotChanged:(Tab*)tab withImage:(UIImage*)image { | 675 - (void)notifyTabSnapshotChanged:(Tab*)tab withImage:(UIImage*)image { |
| 694 DCHECK([NSThread isMainThread]); | 676 DCHECK([NSThread isMainThread]); |
| 695 [_observers tabModel:self didChangeTabSnapshot:tab withImage:image]; | 677 [_observers tabModel:self didChangeTabSnapshot:tab withImage:image]; |
| 696 } | 678 } |
| 697 | 679 |
| 698 - (void)resetAllWebViews { | 680 - (void)resetAllWebViews { |
| 699 for (Tab* tab in self) { | 681 for (Tab* tab in self) { |
| 700 [tab.webController reinitializeWebViewAndReload:(tab == _currentTab)]; | 682 [tab.webController reinitializeWebViewAndReload:(tab == self.currentTab)]; |
| 701 } | 683 } |
| 702 } | 684 } |
| 703 | 685 |
| 704 - (void)setWebUsageEnabled:(BOOL)webUsageEnabled { | 686 - (void)setWebUsageEnabled:(BOOL)webUsageEnabled { |
| 705 if (webUsageEnabled_ == webUsageEnabled) | 687 if (webUsageEnabled_ == webUsageEnabled) |
| 706 return; | 688 return; |
| 707 webUsageEnabled_ = webUsageEnabled; | 689 webUsageEnabled_ = webUsageEnabled; |
| 708 for (Tab* tab in self) { | 690 for (Tab* tab in self) { |
| 709 tab.webUsageEnabled = webUsageEnabled; | 691 tab.webUsageEnabled = webUsageEnabled; |
| 710 } | 692 } |
| 711 } | 693 } |
| 712 | 694 |
| 713 - (void)setPrimary:(BOOL)primary { | 695 - (void)setPrimary:(BOOL)primary { |
| 714 if (_tabUsageRecorder) | 696 if (_tabUsageRecorder) |
| 715 _tabUsageRecorder->RecordPrimaryTabModelChange(primary, _currentTab); | 697 _tabUsageRecorder->RecordPrimaryTabModelChange(primary, self.currentTab); |
| 716 } | 698 } |
| 717 | 699 |
| 718 - (NSSet*)currentlyReferencedExternalFiles { | 700 - (NSSet*)currentlyReferencedExternalFiles { |
| 719 NSMutableSet* referencedFiles = [NSMutableSet set]; | 701 NSMutableSet* referencedFiles = [NSMutableSet set]; |
| 720 if (!_browserState) | 702 if (!_browserState) |
| 721 return referencedFiles; | 703 return referencedFiles; |
| 722 // Check the currently open tabs for external files. | 704 // Check the currently open tabs for external files. |
| 723 for (Tab* tab in self) { | 705 for (Tab* tab in self) { |
| 724 if (UrlIsExternalFileReference(tab.url)) { | 706 if (UrlIsExternalFileReference(tab.url)) { |
| 725 NSString* fileName = base::SysUTF8ToNSString(tab.url.ExtractFileName()); | 707 NSString* fileName = base::SysUTF8ToNSString(tab.url.ExtractFileName()); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 ? IOSChromeTabRestoreServiceFactory::GetForBrowserState(_browserState) | 751 ? IOSChromeTabRestoreServiceFactory::GetForBrowserState(_browserState) |
| 770 : nullptr; | 752 : nullptr; |
| 771 web::NavigationManagerImpl* navigationManager = [closedTab navigationManager]; | 753 web::NavigationManagerImpl* navigationManager = [closedTab navigationManager]; |
| 772 DCHECK(navigationManager); | 754 DCHECK(navigationManager); |
| 773 int itemCount = navigationManager->GetItemCount(); | 755 int itemCount = navigationManager->GetItemCount(); |
| 774 if (restoreService && (![self isNTPTab:closedTab] || itemCount > 1)) { | 756 if (restoreService && (![self isNTPTab:closedTab] || itemCount > 1)) { |
| 775 restoreService->CreateHistoricalTab( | 757 restoreService->CreateHistoricalTab( |
| 776 sessions::IOSLiveTab::GetForWebState(closedTab.webState), | 758 sessions::IOSLiveTab::GetForWebState(closedTab.webState), |
| 777 closedTabIndex); | 759 closedTabIndex); |
| 778 } | 760 } |
| 779 // This needs to be called before the tab is removed from the list. | |
| 780 Tab* newSelection = | |
| 781 [_orderController determineNewSelectedTabFromRemovedTab:closedTab]; | |
| 782 | 761 |
| 783 base::scoped_nsobject<Tab> kungFuDeathGrip([closedTab retain]); | 762 base::scoped_nsobject<Tab> kungFuDeathGrip([closedTab retain]); |
| 784 | 763 |
| 785 // If closing the current tab, clear |_currentTab| before sending any | 764 // If a non-current Tab is closed, save the session (it will be saved by |
| 786 // notification. This avoids various parts of the code getting confused | 765 // TabModelObserversBridge if the currentTab has been closed). |
| 787 // when the current tab isn't in the tab model. | 766 BOOL needToSaveSession = (closedTab != self.currentTab); |
| 788 Tab* savedCurrentTab = _currentTab; | |
| 789 if (closedTab == _currentTab) | |
| 790 _currentTab.reset(nil); | |
| 791 | 767 |
| 792 DCHECK([_tabRetainer containsObject:closedTab]); | 768 DCHECK([_tabRetainer containsObject:closedTab]); |
| 793 [_tabRetainer removeObject:closedTab]; | 769 [_tabRetainer removeObject:closedTab]; |
| 794 | 770 |
| 795 _webStateList.DetachWebStateAt(closedTabIndex); | 771 _webStateList.DetachWebStateAt(closedTabIndex); |
| 796 | 772 |
| 797 // Current tab has closed, update the selected tab and swap in its | 773 if (needToSaveSession) |
| 798 // contents. There is nothing to do if a non-selected tab is closed as | |
| 799 // the selection isn't index-based, therefore it hasn't changed. | |
| 800 // -changeSelectedTabFrom: will persist the state change, so only do it | |
| 801 // if the selection isn't changing. | |
| 802 if (closedTab == savedCurrentTab) { | |
| 803 [self changeSelectedTabFrom:closedTab to:newSelection persistState:NO]; | |
| 804 } else { | |
| 805 [self saveSessionImmediately:NO]; | 774 [self saveSessionImmediately:NO]; |
| 806 } | |
| 807 ++_closedTabCount; | |
| 808 } | 775 } |
| 809 | 776 |
| 810 - (void)navigationCommittedInTab:(Tab*)tab { | 777 - (void)navigationCommittedInTab:(Tab*)tab { |
| 811 if (self.offTheRecord) | 778 if (self.offTheRecord) |
| 812 return; | 779 return; |
| 813 if (![tab navigationManager]) | 780 if (![tab navigationManager]) |
| 814 return; | 781 return; |
| 815 | 782 |
| 816 // 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. |
| 817 web::NavigationItem* previousItem = | 784 web::NavigationItem* previousItem = |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 count++; | 818 count++; |
| 852 } | 819 } |
| 853 return count; | 820 return count; |
| 854 } | 821 } |
| 855 | 822 |
| 856 #pragma mark - Private methods | 823 #pragma mark - Private methods |
| 857 | 824 |
| 858 - (SessionWindowIOS*)windowForSavingSession { | 825 - (SessionWindowIOS*)windowForSavingSession { |
| 859 // Background tabs will already have their state preserved, but not the | 826 // Background tabs will already have their state preserved, but not the |
| 860 // fg tab. Do it now. | 827 // fg tab. Do it now. |
| 861 [_currentTab recordStateInHistory]; | 828 [self.currentTab recordStateInHistory]; |
| 862 | 829 |
| 863 // Build the array of sessions. Copy the session objects as the saving will | 830 // Build the array of sessions. Copy the session objects as the saving will |
| 864 // be done on a separate thread. | 831 // be done on a separate thread. |
| 865 // TODO(crbug.com/661986): This could get expensive especially since this | 832 // TODO(crbug.com/661986): This could get expensive especially since this |
| 866 // window may never be saved (if another call comes in before the delay). | 833 // window may never be saved (if another call comes in before the delay). |
| 867 SessionWindowIOS* window = [[[SessionWindowIOS alloc] init] autorelease]; | 834 SessionWindowIOS* window = [[[SessionWindowIOS alloc] init] autorelease]; |
| 868 for (Tab* tab in self) { | 835 for (Tab* tab in self) { |
| 869 web::WebState* webState = tab.webState; | 836 web::WebState* webState = tab.webState; |
| 870 DCHECK(webState); | 837 DCHECK(webState); |
| 871 [window addSerializedSessionStorage:webState->BuildSessionStorage()]; | 838 [window addSerializedSessionStorage:webState->BuildSessionStorage()]; |
| 872 } | 839 } |
| 873 window.selectedIndex = [self indexOfTab:_currentTab]; | 840 window.selectedIndex = [self indexOfTab:self.currentTab]; |
| 874 return window; | 841 return window; |
| 875 } | 842 } |
| 876 | 843 |
| 877 - (BOOL)isNTPTab:(Tab*)tab { | 844 - (BOOL)isNTPTab:(Tab*)tab { |
| 878 std::string host = tab.url.host(); | 845 std::string host = tab.url.host(); |
| 879 return host == kChromeUINewTabHost || host == kChromeUIBookmarksHost; | 846 return host == kChromeUINewTabHost || host == kChromeUIBookmarksHost; |
| 880 } | 847 } |
| 881 | 848 |
| 882 - (Tab*)insertTabWithLoadParams: | 849 - (Tab*)insertTabWithLoadParams: |
| 883 (const web::NavigationManager::WebLoadParams&)params | 850 (const web::NavigationManager::WebLoadParams&)params |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 915 postNotificationName:kTabModelNewTabWillOpenNotification | 882 postNotificationName:kTabModelNewTabWillOpenNotification |
| 916 object:self | 883 object:self |
| 917 userInfo:userInfo]; | 884 userInfo:userInfo]; |
| 918 | 885 |
| 919 if (!inBackground) | 886 if (!inBackground) |
| 920 [self setCurrentTab:tab]; | 887 [self setCurrentTab:tab]; |
| 921 | 888 |
| 922 return tab; | 889 return tab; |
| 923 } | 890 } |
| 924 | 891 |
| 925 - (void)changeSelectedTabFrom:(Tab*)oldTab | |
| 926 to:(Tab*)newTab | |
| 927 persistState:(BOOL)persist { | |
| 928 if (oldTab) { | |
| 929 // Save state, such as scroll position, before switching tabs. | |
| 930 if (oldTab != newTab && persist) | |
| 931 [oldTab recordStateInHistory]; | |
| 932 [self postNotificationName:kTabModelTabDeselectedNotification | |
| 933 withTab:oldTab]; | |
| 934 } | |
| 935 | |
| 936 // No Tab to select (e.g. the last Tab has been closed). | |
| 937 if ([self indexOfTab:newTab] == NSNotFound) | |
| 938 return; | |
| 939 | |
| 940 _currentTab.reset(newTab); | |
| 941 if (newTab) { | |
| 942 [_observers tabModel:self | |
| 943 didChangeActiveTab:newTab | |
| 944 previousTab:oldTab | |
| 945 atIndex:[self indexOfTab:newTab]]; | |
| 946 [newTab updateLastVisitedTimestamp]; | |
| 947 ++_openedTabCount; | |
| 948 } | |
| 949 BOOL loadingFinished = [newTab.webController loadPhase] == web::PAGE_LOADED; | |
| 950 if (loadingFinished) { | |
| 951 // Persist the session state. | |
| 952 [self saveSessionImmediately:NO]; | |
| 953 } | |
| 954 } | |
| 955 | |
| 956 - (void)updateSnapshotCache:(Tab*)tab { | |
| 957 NSMutableSet* set = [NSMutableSet set]; | |
| 958 NSUInteger index = [self indexOfTab:tab]; | |
| 959 if (index > 0) { | |
| 960 Tab* previousTab = [self tabAtIndex:(index - 1)]; | |
| 961 [set addObject:previousTab.tabId]; | |
| 962 } | |
| 963 if (index < self.count - 1) { | |
| 964 Tab* nextTab = [self tabAtIndex:(index + 1)]; | |
| 965 [set addObject:nextTab.tabId]; | |
| 966 } | |
| 967 [SnapshotCache sharedInstance].pinnedIDs = set; | |
| 968 } | |
| 969 | |
| 970 - (void)postNotificationName:(NSString*)notificationName withTab:(Tab*)tab { | 892 - (void)postNotificationName:(NSString*)notificationName withTab:(Tab*)tab { |
| 971 // A scoped_nsobject is used rather than an NSDictionary with static | 893 // A scoped_nsobject is used rather than an NSDictionary with static |
| 972 // initializer dictionaryWithObject, because that approach adds the dictionary | 894 // initializer dictionaryWithObject, because that approach adds the dictionary |
| 973 // to the autorelease pool, which in turn holds Tab alive longer than | 895 // to the autorelease pool, which in turn holds Tab alive longer than |
| 974 // necessary. | 896 // necessary. |
| 975 base::scoped_nsobject<NSDictionary> userInfo( | 897 base::scoped_nsobject<NSDictionary> userInfo( |
| 976 [[NSDictionary alloc] initWithObjectsAndKeys:tab, kTabModelTabKey, nil]); | 898 [[NSDictionary alloc] initWithObjectsAndKeys:tab, kTabModelTabKey, nil]); |
| 977 [[NSNotificationCenter defaultCenter] postNotificationName:notificationName | 899 [[NSNotificationCenter defaultCenter] postNotificationName:notificationName |
| 978 object:self | 900 object:self |
| 979 userInfo:userInfo]; | 901 userInfo:userInfo]; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1028 DCHECK(opener.webState); | 950 DCHECK(opener.webState); |
| 1029 _webStateList.SetOpenerOfWebStateAt(index, opener.webState); | 951 _webStateList.SetOpenerOfWebStateAt(index, opener.webState); |
| 1030 } | 952 } |
| 1031 } | 953 } |
| 1032 | 954 |
| 1033 // Update the selected tab if there was a selected Tab in the saved session. | 955 // Update the selected tab if there was a selected Tab in the saved session. |
| 1034 if (window.selectedIndex != NSNotFound) { | 956 if (window.selectedIndex != NSNotFound) { |
| 1035 NSUInteger selectedIndex = window.selectedIndex + oldCount; | 957 NSUInteger selectedIndex = window.selectedIndex + oldCount; |
| 1036 DCHECK_LT(selectedIndex, self.count); | 958 DCHECK_LT(selectedIndex, self.count); |
| 1037 DCHECK([self tabAtIndex:selectedIndex]); | 959 DCHECK([self tabAtIndex:selectedIndex]); |
| 1038 [self changeSelectedTabFrom:_currentTab | 960 |
| 1039 to:[self tabAtIndex:selectedIndex] | 961 if (persistState && self.currentTab) |
| 1040 persistState:persistState]; | 962 [self.currentTab recordStateInHistory]; |
| 963 _webStateList.ActivateWebStateAt(static_cast<int>(selectedIndex)); |
| 1041 } | 964 } |
| 1042 | 965 |
| 1043 // If there was only one tab and it was the new tab page, clobber it. | 966 // If there was only one tab and it was the new tab page, clobber it. |
| 1044 BOOL closedNTPTab = NO; | 967 BOOL closedNTPTab = NO; |
| 1045 if (oldCount == 1) { | 968 if (oldCount == 1) { |
| 1046 Tab* tab = [self tabAtIndex:0]; | 969 Tab* tab = [self tabAtIndex:0]; |
| 1047 if (tab.url == GURL(kChromeUINewTabURL)) { | 970 if (tab.url == GURL(kChromeUINewTabURL)) { |
| 1048 [self closeTab:tab]; | 971 [self closeTab:tab]; |
| 1049 closedNTPTab = YES; | 972 closedNTPTab = YES; |
| 1050 oldCount = 0; | 973 oldCount = 0; |
| 1051 } | 974 } |
| 1052 } | 975 } |
| 1053 if (_tabUsageRecorder) { | 976 if (_tabUsageRecorder) { |
| 1054 NSMutableArray<Tab*>* restoredTabs = | 977 NSMutableArray<Tab*>* restoredTabs = |
| 1055 [NSMutableArray arrayWithCapacity:_webStateList.count() - oldCount]; | 978 [NSMutableArray arrayWithCapacity:_webStateList.count() - oldCount]; |
| 1056 for (int index = oldCount; index < _webStateList.count(); ++index) { | 979 for (int index = oldCount; index < _webStateList.count(); ++index) { |
| 1057 web::WebState* webState = _webStateList.GetWebStateAt(index); | 980 web::WebState* webState = _webStateList.GetWebStateAt(index); |
| 1058 [restoredTabs addObject:LegacyTabHelper::GetTabForWebState(webState)]; | 981 [restoredTabs addObject:LegacyTabHelper::GetTabForWebState(webState)]; |
| 1059 } | 982 } |
| 1060 _tabUsageRecorder->InitialRestoredTabs(_currentTab, restoredTabs); | 983 _tabUsageRecorder->InitialRestoredTabs(self.currentTab, restoredTabs); |
| 1061 } | 984 } |
| 1062 return closedNTPTab; | 985 return closedNTPTab; |
| 1063 } | 986 } |
| 1064 | 987 |
| 1065 #pragma mark - Notification Handlers | 988 #pragma mark - Notification Handlers |
| 1066 | 989 |
| 1067 // Called when UIApplicationWillResignActiveNotification is received. | 990 // Called when UIApplicationWillResignActiveNotification is received. |
| 1068 - (void)willResignActive:(NSNotification*)notify { | 991 - (void)willResignActive:(NSNotification*)notify { |
| 1069 if (webUsageEnabled_ && _currentTab) { | 992 if (webUsageEnabled_ && self.currentTab) { |
| 1070 [[SnapshotCache sharedInstance] | 993 [[SnapshotCache sharedInstance] |
| 1071 willBeSavedGreyWhenBackgrounding:_currentTab.get().tabId]; | 994 willBeSavedGreyWhenBackgrounding:self.currentTab.tabId]; |
| 1072 } | 995 } |
| 1073 } | 996 } |
| 1074 | 997 |
| 1075 // Called when UIApplicationDidEnterBackgroundNotification is received. | 998 // Called when UIApplicationDidEnterBackgroundNotification is received. |
| 1076 - (void)applicationDidEnterBackground:(NSNotification*)notify { | 999 - (void)applicationDidEnterBackground:(NSNotification*)notify { |
| 1077 if (!_browserState) | 1000 if (!_browserState) |
| 1078 return; | 1001 return; |
| 1079 | 1002 |
| 1080 // Evict all the certificate policies except for the current entries of the | 1003 // Evict all the certificate policies except for the current entries of the |
| 1081 // active sessions. | 1004 // active sessions. |
| 1082 CleanCertificatePolicyCache( | 1005 CleanCertificatePolicyCache( |
| 1083 &_clearPoliciesTaskTracker, | 1006 &_clearPoliciesTaskTracker, |
| 1084 web::WebThread::GetTaskRunnerForThread(web::WebThread::IO), | 1007 web::WebThread::GetTaskRunnerForThread(web::WebThread::IO), |
| 1085 web::BrowserState::GetCertificatePolicyCache(_browserState), | 1008 web::BrowserState::GetCertificatePolicyCache(_browserState), |
| 1086 &_webStateList); | 1009 &_webStateList); |
| 1087 | 1010 |
| 1088 if (_tabUsageRecorder) | 1011 if (_tabUsageRecorder) |
| 1089 _tabUsageRecorder->AppDidEnterBackground(); | 1012 _tabUsageRecorder->AppDidEnterBackground(); |
| 1090 | 1013 |
| 1091 // Normally, the session is saved after some timer expires but since the app | 1014 // Normally, the session is saved after some timer expires but since the app |
| 1092 // is about to enter the background send YES to save the session immediately. | 1015 // is about to enter the background send YES to save the session immediately. |
| 1093 [self saveSessionImmediately:YES]; | 1016 [self saveSessionImmediately:YES]; |
| 1094 | 1017 |
| 1095 // Write out a grey version of the current website to disk. | 1018 // Write out a grey version of the current website to disk. |
| 1096 if (webUsageEnabled_ && _currentTab) { | 1019 if (webUsageEnabled_ && self.currentTab) { |
| 1097 [[SnapshotCache sharedInstance] | 1020 [[SnapshotCache sharedInstance] |
| 1098 saveGreyInBackgroundForSessionID:_currentTab.get().tabId]; | 1021 saveGreyInBackgroundForSessionID:self.currentTab.tabId]; |
| 1099 } | 1022 } |
| 1100 } | 1023 } |
| 1101 | 1024 |
| 1102 // Called when UIApplicationWillEnterForegroundNotification is received. | 1025 // Called when UIApplicationWillEnterForegroundNotification is received. |
| 1103 - (void)applicationWillEnterForeground:(NSNotification*)notify { | 1026 - (void)applicationWillEnterForeground:(NSNotification*)notify { |
| 1104 if (_tabUsageRecorder) { | 1027 if (_tabUsageRecorder) { |
| 1105 _tabUsageRecorder->AppWillEnterForeground(); | 1028 _tabUsageRecorder->AppWillEnterForeground(); |
| 1106 } | 1029 } |
| 1107 } | 1030 } |
| 1108 | 1031 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1135 web::NavigationManager::WebLoadParams params(URL); | 1058 web::NavigationManager::WebLoadParams params(URL); |
| 1136 params.referrer = referrer; | 1059 params.referrer = referrer; |
| 1137 params.transition_type = ui::PAGE_TRANSITION_TYPED; | 1060 params.transition_type = ui::PAGE_TRANSITION_TYPED; |
| 1138 [[tab webController] loadWithParams:params]; | 1061 [[tab webController] loadWithParams:params]; |
| 1139 [tab webController].webUsageEnabled = webUsageEnabled_; | 1062 [tab webController].webUsageEnabled = webUsageEnabled_; |
| 1140 [self insertTab:tab atIndex:index opener:parentTab]; | 1063 [self insertTab:tab atIndex:index opener:parentTab]; |
| 1141 return tab; | 1064 return tab; |
| 1142 } | 1065 } |
| 1143 | 1066 |
| 1144 @end | 1067 @end |
| OLD | NEW |