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

Side by Side Diff: ios/chrome/browser/sessions/session_window.mm

Issue 2655253002: Revert of Moved NavigationManagerImpl serialization out of CRWSessionController. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View 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/sessions/session_window.h" 5 #import "ios/chrome/browser/sessions/session_window.h"
6 6
7 #include <list> 7 #include <list>
8 #include <memory> 8 #include <memory>
9 9
10 #include "base/format_macros.h" 10 #include "base/format_macros.h"
11 #include "base/location.h" 11 #include "base/location.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #import "base/mac/scoped_nsobject.h"
14 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" 13 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
15 #import "ios/chrome/browser/sessions/NSCoder+Compatibility.h" 14 #import "ios/chrome/browser/sessions/NSCoder+Compatibility.h"
16 #import "ios/chrome/browser/sessions/session_service.h" 15 #import "ios/chrome/browser/sessions/session_service.h"
17 #import "ios/web/navigation/crw_session_controller.h" 16 #import "ios/web/navigation/crw_session_controller.h"
18 #import "ios/web/public/web_thread.h" 17 #import "ios/web/public/web_thread.h"
19 #import "ios/web/web_state/web_state_impl.h" 18 #import "ios/web/web_state/web_state_impl.h"
20 19
21 using web::WebStateImpl; 20 using web::WebStateImpl;
22 21
23 // Serialization keys.
24 NSString* const kSessionsKey = @"sessions";
25 NSString* const kSelectedIndexKey = @"selectedIndex";
26
27 @interface SessionWindowIOS () { 22 @interface SessionWindowIOS () {
28 // Backing objects for properties of the same name. 23 @private
29 base::scoped_nsobject<NSMutableArray> _sessions; 24 NSUInteger _selectedIndex; // Currently selected session.
30 NSUInteger _selectedIndex; 25 // For SessionWindows created via -initWithSessions:currentIndex:, the
26 // WebStateImpls in |_sessions| are owned by the calling code. When created
27 // via -initwithCoder:, the code which accepts the SessionWindow object
28 // should take or assign ownership of the contents of |_sessions|.
29 std::list<web::WebStateImpl*> _sessions;
31 } 30 }
32 31
33 // Returns whether |index| is valid for a session window with |sessionCount| 32 // For testing only. Empties _sessions.
34 // entries. 33 - (void)clearSessions;
35 - (BOOL)isIndex:(NSUInteger)index validForSessionCount:(NSUInteger)sessionCount;
36 34
37 @end 35 @end
38 36
39 @implementation SessionWindowIOS 37 @implementation SessionWindowIOS
40 38
41 @synthesize selectedIndex = _selectedIndex; 39 @synthesize selectedIndex = _selectedIndex;
42 40
43 - (id)init { 41 - (id)init {
44 if ((self = [super init])) { 42 if ((self = [super init])) {
45 _sessions.reset([[NSMutableArray alloc] init]);
46 _selectedIndex = NSNotFound; 43 _selectedIndex = NSNotFound;
47 } 44 }
48 return self; 45 return self;
49 } 46 }
50 47
51 #pragma mark - Accessors 48 - (id)initWithCoder:(NSCoder*)aDecoder {
52 49 self = [super init];
53 - (NSArray*)sessions { 50 if (self) {
54 return [NSArray arrayWithArray:_sessions]; 51 DCHECK([aDecoder isKindOfClass:[SessionWindowUnarchiver class]]);
52 ios::ChromeBrowserState* browserState =
53 static_cast<SessionWindowUnarchiver*>(aDecoder).browserState;
54 DCHECK(browserState);
55 _selectedIndex = [aDecoder cr_decodeIndexForKey:@"selectedIndex"];
56 base::scoped_nsobject<NSArray> decodedSessionControllers(
57 [[aDecoder decodeObjectForKey:@"sessions"] retain]);
58 for (CRWSessionController* sc in decodedSessionControllers.get()) {
59 WebStateImpl* webState = new WebStateImpl(browserState);
60 webState->GetNavigationManagerImpl().SetSessionController(sc);
61 _sessions.push_back(webState);
62 }
63 DCHECK((_sessions.size() && _selectedIndex < _sessions.size()) ||
64 (_sessions.empty() && _selectedIndex == NSNotFound));
65 // If index is somehow corrupted, reset it to zero.
66 // (note that if |_selectedIndex| == |_sessions.size()|, that's
67 // incorrect because the maximum index of a vector of size |n| is |n-1|).
68 // Empty sessions should have |_selectedIndex| values of NSNotFound.
69 if (_sessions.empty()) {
70 _selectedIndex = NSNotFound;
71 } else if (_selectedIndex >= _sessions.size()) {
72 _selectedIndex = 0;
73 }
74 }
75 return self;
55 } 76 }
56 77
57 - (void)setSelectedIndex:(NSUInteger)selectedIndex { 78 - (void)dealloc {
58 DCHECK([self isIndex:selectedIndex validForSessionCount:[_sessions count]]); 79 DCHECK(_sessions.empty());
59 _selectedIndex = selectedIndex; 80 [super dealloc];
60 } 81 }
61 82
62 #pragma mark - Public 83 - (void)clearSessions {
84 while (self.unclaimedSessions) {
85 std::unique_ptr<WebStateImpl> webState = [self nextSession];
86 webState.reset();
87 }
88 }
63 89
64 - (void)addSerializedSession:(CRWNavigationManagerStorage*)session { 90 - (void)encodeWithCoder:(NSCoder*)aCoder {
65 [_sessions addObject:session]; 91 // Destructively pull all of the WebStateImpls out of |_sessions| and hand
92 // off their sessionControllers for archiving. When encoding is complete,
93 // all of the objects in |_sessions| have been destroyed.
94 NSMutableArray* sessionControllers =
95 [NSMutableArray arrayWithCapacity:_sessions.size()];
96 while (self.unclaimedSessions) {
97 std::unique_ptr<WebStateImpl> webState = [self nextSession];
98 CRWSessionController* sessionController =
99 webState->GetNavigationManagerImpl().GetSessionController();
100 [sessionControllers addObject:sessionController];
101
102 // NOTE: WebStateImpl must be destroyed on the UI thread for safety
103 // reasons.
104 web::WebThread::DeleteSoon(web::WebThread::UI, FROM_HERE,
105 webState.release());
106 }
107
108 [aCoder cr_encodeIndex:_selectedIndex forKey:@"selectedIndex"];
109 [aCoder encodeObject:sessionControllers forKey:@"sessions"];
110 }
111
112 - (void)addSession:(std::unique_ptr<web::WebStateImpl>)session {
113 DCHECK(session->GetNavigationManagerImpl().GetSessionController());
114 _sessions.push_back(session.release());
66 // Set the selected index to 0 (this session) if this is the first session 115 // Set the selected index to 0 (this session) if this is the first session
67 // added. 116 // added.
68 if (_selectedIndex == NSNotFound) 117 if (_selectedIndex == NSNotFound)
69 _selectedIndex = 0; 118 _selectedIndex = 0;
70 } 119 }
71 120
72 - (void)clearSessions { 121 - (void)setSelectedIndex:(NSUInteger)selectedIndex {
73 [_sessions removeAllObjects]; 122 DCHECK((_sessions.size() && selectedIndex < _sessions.size()) ||
74 _selectedIndex = NSNotFound; 123 (_sessions.empty() && selectedIndex == NSNotFound));
124 _selectedIndex = selectedIndex;
75 } 125 }
76 126
77 #pragma mark - NSCoding 127 - (std::unique_ptr<web::WebStateImpl>)nextSession {
78 128 std::unique_ptr<web::WebStateImpl> session(_sessions.front());
79 - (id)initWithCoder:(NSCoder*)aDecoder { 129 _sessions.pop_front();
80 self = [super init]; 130 return session;
81 if (self) {
82 DCHECK([aDecoder isKindOfClass:[SessionWindowUnarchiver class]]);
83 _selectedIndex = [aDecoder cr_decodeIndexForKey:kSelectedIndexKey];
84 _sessions.reset([[aDecoder decodeObjectForKey:kSessionsKey] retain]);
85 DCHECK(
86 [self isIndex:_selectedIndex validForSessionCount:[_sessions count]]);
87 // If index is somehow corrupted, reset it to zero.
88 // (note that if |_selectedIndex| == |_sessions.size()|, that's
89 // incorrect because the maximum index of a vector of size |n| is |n-1|).
90 // Empty sessions should have |_selectedIndex| values of NSNotFound.
91 if (![_sessions count]) {
92 _selectedIndex = NSNotFound;
93 } else if (_selectedIndex >= [_sessions count]) {
94 _selectedIndex = 0;
95 }
96 }
97 return self;
98 } 131 }
99 132
100 - (void)encodeWithCoder:(NSCoder*)aCoder { 133 - (NSUInteger)unclaimedSessions {
101 [aCoder cr_encodeIndex:_selectedIndex forKey:kSelectedIndexKey]; 134 return _sessions.size();
102 [aCoder encodeObject:_sessions forKey:kSessionsKey];
103 } 135 }
104 136
105 #pragma mark - 137 #pragma mark -
106 138 #pragma mark Debugging conveniences.
107 - (BOOL)isIndex:(NSUInteger)index
108 validForSessionCount:(NSUInteger)sessionCount {
109 return (sessionCount && index < sessionCount) ||
110 (!sessionCount && index == NSNotFound);
111 }
112 139
113 - (NSString*)description { 140 - (NSString*)description {
141 NSMutableArray* sessionControllers =
142 [NSMutableArray arrayWithCapacity:_sessions.size()];
143 for (auto it = _sessions.begin(); it != _sessions.end(); ++it) {
144 CRWSessionController* sessionController =
145 (*it)->GetNavigationManagerImpl().GetSessionController();
146 [sessionControllers addObject:sessionController];
147 }
148
114 return [NSString stringWithFormat:@"selected index: %" PRIuNS 149 return [NSString stringWithFormat:@"selected index: %" PRIuNS
115 "\nsessions:\n%@\n", 150 "\nsessions:\n%@\n",
116 _selectedIndex, _sessions.get()]; 151 _selectedIndex, sessionControllers];
117 } 152 }
118 153
119 @end 154 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/sessions/session_window.h ('k') | ios/chrome/browser/sessions/session_window_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698