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

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

Issue 2811593004: [ios] Allow having multiple session windows in a session. (Closed)
Patch Set: Rebase on origin/master. Created 3 years, 8 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/foundation_util.h"
14 #import "base/mac/scoped_nsobject.h" 14 #import "base/mac/scoped_nsobject.h"
15 #include "base/metrics/histogram_macros.h" 15 #include "base/metrics/histogram_macros.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 #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" 28 #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h"
29 #import "ios/chrome/browser/sessions/session_ios.h"
29 #import "ios/chrome/browser/sessions/session_service_ios.h" 30 #import "ios/chrome/browser/sessions/session_service_ios.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"
36 #import "ios/chrome/browser/tabs/tab_model_closing_web_state_observer.h" 37 #import "ios/chrome/browser/tabs/tab_model_closing_web_state_observer.h"
37 #import "ios/chrome/browser/tabs/tab_model_list.h" 38 #import "ios/chrome/browser/tabs/tab_model_list.h"
38 #import "ios/chrome/browser/tabs/tab_model_observers.h" 39 #import "ios/chrome/browser/tabs/tab_model_observers.h"
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 // Saves session's state. 164 // Saves session's state.
164 base::scoped_nsobject<SessionServiceIOS> _sessionService; 165 base::scoped_nsobject<SessionServiceIOS> _sessionService;
165 // List of TabModelObservers. 166 // List of TabModelObservers.
166 base::scoped_nsobject<TabModelObservers> _observers; 167 base::scoped_nsobject<TabModelObservers> _observers;
167 168
168 // Used to ensure thread-safety of the certificate policy management code. 169 // Used to ensure thread-safety of the certificate policy management code.
169 base::CancelableTaskTracker _clearPoliciesTaskTracker; 170 base::CancelableTaskTracker _clearPoliciesTaskTracker;
170 } 171 }
171 172
172 // Session window for the contents of the tab model. 173 // Session window for the contents of the tab model.
173 @property(nonatomic, readonly) SessionWindowIOS* windowForSavingSession; 174 @property(nonatomic, readonly) SessionIOS* sessionForSaving;
174 175
175 // Helper method that posts a notification with the given name with |tab| 176 // Helper method that posts a notification with the given name with |tab|
176 // in the userInfo dictionary under the kTabModelTabKey. 177 // in the userInfo dictionary under the kTabModelTabKey.
177 - (void)postNotificationName:(NSString*)notificationName withTab:(Tab*)tab; 178 - (void)postNotificationName:(NSString*)notificationName withTab:(Tab*)tab;
178 179
179 // Helper method to restore a saved session and control if the state should 180 // Helper method to restore a saved session and control if the state should
180 // be persisted or not. Used to implement the public -restoreSessionWindow: 181 // be persisted or not. Used to implement the public -restoreSessionWindow:
181 // method and restoring session in the initialiser. 182 // method and restoring session in the initialiser.
182 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window 183 - (BOOL)restoreSessionWindow:(SessionWindowIOS*)window
183 persistState:(BOOL)persistState; 184 persistState:(BOOL)persistState;
(...skipping 20 matching lines...) Expand all
204 [[NSNotificationCenter defaultCenter] removeObserver:self]; 205 [[NSNotificationCenter defaultCenter] removeObserver:self];
205 206
206 // Clear weak pointer to WebStateListMetricsObserver before destroying it. 207 // Clear weak pointer to WebStateListMetricsObserver before destroying it.
207 _webStateListMetricsObserver = nullptr; 208 _webStateListMetricsObserver = nullptr;
208 209
209 // Close all tabs. Do this in an @autoreleasepool as WebStateList observers 210 // Close all tabs. Do this in an @autoreleasepool as WebStateList observers
210 // will be notified (they are unregistered later). As some of them may be 211 // will be notified (they are unregistered later). As some of them may be
211 // implemented in Objective-C and unregister themselves in their -dealloc 212 // implemented in Objective-C and unregister themselves in their -dealloc
212 // method, ensure they -autorelease introduced by ARC are processed before 213 // method, ensure they -autorelease introduced by ARC are processed before
213 // the WebStateList destructor is called. 214 // the WebStateList destructor is called.
214 @autoreleasepool { 215 @autoreleasepool {
marq (ping after 24h) 2017/04/18 15:16:55 This file isn't ARC yet. Should this be a ScopedAu
sdefresne 2017/04/19 14:54:41 @autoreleasepool is not related to ARC and can be
215 [self closeAllTabs]; 216 [self closeAllTabs];
216 } 217 }
217 218
218 // Unregister all observers after closing all the tabs as some of them are 219 // Unregister all observers after closing all the tabs as some of them are
219 // required to properly clean up the Tabs. 220 // required to properly clean up the Tabs.
220 for (const auto& webStateListObserver : _webStateListObservers) 221 for (const auto& webStateListObserver : _webStateListObservers)
221 _webStateList->RemoveObserver(webStateListObserver.get()); 222 _webStateList->RemoveObserver(webStateListObserver.get());
222 _webStateListObservers.clear(); 223 _webStateListObservers.clear();
223 _retainedWebStateListObservers.reset(); 224 _retainedWebStateListObservers.reset();
224 225
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 return [self restoreSessionWindow:window persistState:YES]; 387 return [self restoreSessionWindow:window persistState:YES];
387 } 388 }
388 389
389 - (void)saveSessionImmediately:(BOOL)immediately { 390 - (void)saveSessionImmediately:(BOOL)immediately {
390 // Do nothing if there are tabs in the model but no selected tab. This is 391 // Do nothing if there are tabs in the model but no selected tab. This is
391 // a transitional state. 392 // a transitional state.
392 if ((!self.currentTab && _webStateList->count()) || !_browserState) 393 if ((!self.currentTab && _webStateList->count()) || !_browserState)
393 return; 394 return;
394 NSString* statePath = 395 NSString* statePath =
395 base::SysUTF8ToNSString(_browserState->GetStatePath().AsUTF8Unsafe()); 396 base::SysUTF8ToNSString(_browserState->GetStatePath().AsUTF8Unsafe());
396 [_sessionService saveSessionWindow:self.windowForSavingSession 397 [_sessionService saveSession:self.sessionForSaving
397 directory:statePath 398 directory:statePath
398 immediately:immediately]; 399 immediately:immediately];
399 } 400 }
400 401
401 - (Tab*)tabAtIndex:(NSUInteger)index { 402 - (Tab*)tabAtIndex:(NSUInteger)index {
402 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX)); 403 DCHECK_LE(index, static_cast<NSUInteger>(INT_MAX));
403 return LegacyTabHelper::GetTabForWebState( 404 return LegacyTabHelper::GetTabForWebState(
404 _webStateList->GetWebStateAt(static_cast<int>(index))); 405 _webStateList->GetWebStateAt(static_cast<int>(index)));
405 } 406 }
406 407
407 - (NSUInteger)indexOfTab:(Tab*)tab { 408 - (NSUInteger)indexOfTab:(Tab*)tab {
408 int index = _webStateList->GetIndexOfWebState(tab.webState); 409 int index = _webStateList->GetIndexOfWebState(tab.webState);
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 NSUInteger count = 0; 684 NSUInteger count = 0;
684 for (Tab* tab in self) { 685 for (Tab* tab in self) {
685 if ([tab.webController isViewAlive]) 686 if ([tab.webController isViewAlive])
686 count++; 687 count++;
687 } 688 }
688 return count; 689 return count;
689 } 690 }
690 691
691 #pragma mark - Private methods 692 #pragma mark - Private methods
692 693
693 - (SessionWindowIOS*)windowForSavingSession { 694 - (SessionIOS*)sessionForSaving {
694 // Background tabs will already have their state preserved, but not the 695 // Background tabs will already have their state preserved, but not the
695 // fg tab. Do it now. 696 // fg tab. Do it now.
696 [self.currentTab recordStateInHistory]; 697 [self.currentTab recordStateInHistory];
697 698
698 // Build the array of sessions. Copy the session objects as the saving will 699 // Build the array of sessions. Copy the session objects as the saving will
699 // be done on a separate thread. 700 // be done on a separate thread.
700 // TODO(crbug.com/661986): This could get expensive especially since this 701 // TODO(crbug.com/661986): This could get expensive especially since this
701 // window may never be saved (if another call comes in before the delay). 702 // window may never be saved (if another call comes in before the delay).
702 return [[[SessionWindowIOS alloc] 703 SessionWindowIOS* sessionWindow = [[[SessionWindowIOS alloc]
703 initWithSessions:SerializeWebStateList(_webStateList.get()) 704 initWithSessions:SerializeWebStateList(_webStateList.get())
704 selectedIndex:[self indexOfTab:self.currentTab]] autorelease]; 705 selectedIndex:[self indexOfTab:self.currentTab]] autorelease];
706 return [[SessionIOS alloc] initWithWindows:@[ sessionWindow ]];
705 } 707 }
706 708
707 - (void)postNotificationName:(NSString*)notificationName withTab:(Tab*)tab { 709 - (void)postNotificationName:(NSString*)notificationName withTab:(Tab*)tab {
708 // A scoped_nsobject is used rather than an NSDictionary with static 710 // A scoped_nsobject is used rather than an NSDictionary with static
709 // initializer dictionaryWithObject, because that approach adds the dictionary 711 // initializer dictionaryWithObject, because that approach adds the dictionary
710 // to the autorelease pool, which in turn holds Tab alive longer than 712 // to the autorelease pool, which in turn holds Tab alive longer than
711 // necessary. 713 // necessary.
712 base::scoped_nsobject<NSDictionary> userInfo( 714 base::scoped_nsobject<NSDictionary> userInfo(
713 [[NSDictionary alloc] initWithObjectsAndKeys:tab, kTabModelTabKey, nil]); 715 [[NSDictionary alloc] initWithObjectsAndKeys:tab, kTabModelTabKey, nil]);
714 [[NSNotificationCenter defaultCenter] postNotificationName:notificationName 716 [[NSNotificationCenter defaultCenter] postNotificationName:notificationName
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 } 823 }
822 824
823 // Called when UIApplicationWillEnterForegroundNotification is received. 825 // Called when UIApplicationWillEnterForegroundNotification is received.
824 - (void)applicationWillEnterForeground:(NSNotification*)notify { 826 - (void)applicationWillEnterForeground:(NSNotification*)notify {
825 if (_tabUsageRecorder) { 827 if (_tabUsageRecorder) {
826 _tabUsageRecorder->AppWillEnterForeground(); 828 _tabUsageRecorder->AppWillEnterForeground();
827 } 829 }
828 } 830 }
829 831
830 @end 832 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698