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

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

Issue 1360993002: Moved NavigationManagerImpl serialization out of CRWSessionController. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: compilation fix after rebase Created 3 years, 10 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"
13 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" 14 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
14 #import "ios/chrome/browser/sessions/NSCoder+Compatibility.h" 15 #import "ios/chrome/browser/sessions/NSCoder+Compatibility.h"
15 #import "ios/chrome/browser/sessions/session_service.h" 16 #import "ios/chrome/browser/sessions/session_service.h"
16 #import "ios/web/navigation/crw_session_controller.h" 17 #import "ios/web/navigation/crw_session_controller.h"
17 #import "ios/web/public/web_thread.h" 18 #import "ios/web/public/web_thread.h"
18 #import "ios/web/web_state/web_state_impl.h" 19 #import "ios/web/web_state/web_state_impl.h"
19 20
20 using web::WebStateImpl; 21 using web::WebStateImpl;
21 22
23 // Serialization keys.
24 NSString* const kSessionsKey = @"sessions";
25 NSString* const kSelectedIndexKey = @"selectedIndex";
26
22 @interface SessionWindowIOS () { 27 @interface SessionWindowIOS () {
23 @private 28 // Backing objects for properties of the same name.
24 NSUInteger _selectedIndex; // Currently selected session. 29 base::scoped_nsobject<NSMutableArray> _sessions;
25 // For SessionWindows created via -initWithSessions:currentIndex:, the 30 NSUInteger _selectedIndex;
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;
30 } 31 }
31 32
32 // For testing only. Empties _sessions. 33 // Returns whether |index| is valid for a session window with |sessionCount|
33 - (void)clearSessions; 34 // entries.
35 - (BOOL)isIndex:(NSUInteger)index validForSessionCount:(NSUInteger)sessionCount;
34 36
35 @end 37 @end
36 38
37 @implementation SessionWindowIOS 39 @implementation SessionWindowIOS
38 40
39 @synthesize selectedIndex = _selectedIndex; 41 @synthesize selectedIndex = _selectedIndex;
40 42
41 - (id)init { 43 - (id)init {
42 if ((self = [super init])) { 44 if ((self = [super init])) {
45 _sessions.reset([[NSMutableArray alloc] init]);
43 _selectedIndex = NSNotFound; 46 _selectedIndex = NSNotFound;
44 } 47 }
45 return self; 48 return self;
46 } 49 }
47 50
51 #pragma mark - Accessors
52
53 - (NSArray*)sessions {
54 return [NSArray arrayWithArray:_sessions];
55 }
56
57 - (void)setSelectedIndex:(NSUInteger)selectedIndex {
58 DCHECK([self isIndex:selectedIndex validForSessionCount:[_sessions count]]);
59 _selectedIndex = selectedIndex;
60 }
61
62 #pragma mark - Public
63
64 - (void)addSerializedSession:(CRWNavigationManagerStorage*)session {
65 [_sessions addObject:session];
66 // Set the selected index to 0 (this session) if this is the first session
67 // added.
68 if (_selectedIndex == NSNotFound)
69 _selectedIndex = 0;
70 }
71
72 - (void)clearSessions {
73 [_sessions removeAllObjects];
74 _selectedIndex = NSNotFound;
75 }
76
77 #pragma mark - NSCoding
78
48 - (id)initWithCoder:(NSCoder*)aDecoder { 79 - (id)initWithCoder:(NSCoder*)aDecoder {
49 self = [super init]; 80 self = [super init];
50 if (self) { 81 if (self) {
51 DCHECK([aDecoder isKindOfClass:[SessionWindowUnarchiver class]]); 82 DCHECK([aDecoder isKindOfClass:[SessionWindowUnarchiver class]]);
52 ios::ChromeBrowserState* browserState = 83 _selectedIndex = [aDecoder cr_decodeIndexForKey:kSelectedIndexKey];
53 static_cast<SessionWindowUnarchiver*>(aDecoder).browserState; 84 _sessions.reset([[aDecoder decodeObjectForKey:kSessionsKey] retain]);
54 DCHECK(browserState); 85 DCHECK(
55 _selectedIndex = [aDecoder cr_decodeIndexForKey:@"selectedIndex"]; 86 [self isIndex:_selectedIndex validForSessionCount:[_sessions count]]);
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. 87 // If index is somehow corrupted, reset it to zero.
66 // (note that if |_selectedIndex| == |_sessions.size()|, that's 88 // (note that if |_selectedIndex| == |_sessions.size()|, that's
67 // incorrect because the maximum index of a vector of size |n| is |n-1|). 89 // incorrect because the maximum index of a vector of size |n| is |n-1|).
68 // Empty sessions should have |_selectedIndex| values of NSNotFound. 90 // Empty sessions should have |_selectedIndex| values of NSNotFound.
69 if (_sessions.empty()) { 91 if (![_sessions count]) {
70 _selectedIndex = NSNotFound; 92 _selectedIndex = NSNotFound;
71 } else if (_selectedIndex >= _sessions.size()) { 93 } else if (_selectedIndex >= [_sessions count]) {
72 _selectedIndex = 0; 94 _selectedIndex = 0;
73 } 95 }
74 } 96 }
75 return self; 97 return self;
76 } 98 }
77 99
78 - (void)dealloc {
79 DCHECK(_sessions.empty());
80 [super dealloc];
81 }
82
83 - (void)clearSessions {
84 while (self.unclaimedSessions) {
85 std::unique_ptr<WebStateImpl> webState = [self nextSession];
86 webState.reset();
87 }
88 }
89
90 - (void)encodeWithCoder:(NSCoder*)aCoder { 100 - (void)encodeWithCoder:(NSCoder*)aCoder {
91 // Destructively pull all of the WebStateImpls out of |_sessions| and hand 101 [aCoder cr_encodeIndex:_selectedIndex forKey:kSelectedIndexKey];
92 // off their sessionControllers for archiving. When encoding is complete, 102 [aCoder encodeObject:_sessions forKey:kSessionsKey];
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());
115 // Set the selected index to 0 (this session) if this is the first session
116 // added.
117 if (_selectedIndex == NSNotFound)
118 _selectedIndex = 0;
119 }
120
121 - (void)setSelectedIndex:(NSUInteger)selectedIndex {
122 DCHECK((_sessions.size() && selectedIndex < _sessions.size()) ||
123 (_sessions.empty() && selectedIndex == NSNotFound));
124 _selectedIndex = selectedIndex;
125 }
126
127 - (std::unique_ptr<web::WebStateImpl>)nextSession {
128 std::unique_ptr<web::WebStateImpl> session(_sessions.front());
129 _sessions.pop_front();
130 return session;
131 }
132
133 - (NSUInteger)unclaimedSessions {
134 return _sessions.size();
135 } 103 }
136 104
137 #pragma mark - 105 #pragma mark -
138 #pragma mark Debugging conveniences. 106
107 - (BOOL)isIndex:(NSUInteger)index
108 validForSessionCount:(NSUInteger)sessionCount {
109 return (sessionCount && index < sessionCount) ||
110 (!sessionCount && index == NSNotFound);
111 }
139 112
140 - (NSString*)description { 113 - (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
149 return [NSString stringWithFormat:@"selected index: %" PRIuNS 114 return [NSString stringWithFormat:@"selected index: %" PRIuNS
150 "\nsessions:\n%@\n", 115 "\nsessions:\n%@\n",
151 _selectedIndex, sessionControllers]; 116 _selectedIndex, _sessions.get()];
152 } 117 }
153 118
154 @end 119 @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