blob: 8411ce1c004d7f3b89b1730480083bcc453119f7 [file] [log] [blame]
// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/sessions/session_window.h"
#include <list>
#include <memory>
#include "base/format_macros.h"
#include "base/location.h"
#include "base/logging.h"
#import "base/mac/scoped_nsobject.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#import "ios/chrome/browser/sessions/NSCoder+Compatibility.h"
#import "ios/chrome/browser/sessions/session_service.h"
#import "ios/web/public/web_thread.h"
// Serialization keys.
NSString* const kSessionsKey = @"sessions";
NSString* const kSelectedIndexKey = @"selectedIndex";
@interface SessionWindowIOS () {
// Backing objects for properties of the same name.
base::scoped_nsobject<NSMutableArray> _sessions;
NSUInteger _selectedIndex;
}
// Returns whether |index| is valid for a session window with |sessionCount|
// entries.
- (BOOL)isIndex:(NSUInteger)index validForSessionCount:(NSUInteger)sessionCount;
@end
@implementation SessionWindowIOS
@synthesize selectedIndex = _selectedIndex;
- (id)init {
if ((self = [super init])) {
_sessions.reset([[NSMutableArray alloc] init]);
_selectedIndex = NSNotFound;
}
return self;
}
#pragma mark - Accessors
- (NSArray*)sessions {
return [NSArray arrayWithArray:_sessions];
}
- (void)setSelectedIndex:(NSUInteger)selectedIndex {
DCHECK([self isIndex:selectedIndex validForSessionCount:[_sessions count]]);
_selectedIndex = selectedIndex;
}
#pragma mark - Public
- (void)addSerializedSessionStorage:(CRWSessionStorage*)session {
[_sessions addObject:session];
// Set the selected index to 0 (this session) if this is the first session
// added.
if (_selectedIndex == NSNotFound)
_selectedIndex = 0;
}
- (void)clearSessions {
[_sessions removeAllObjects];
_selectedIndex = NSNotFound;
}
#pragma mark - NSCoding
- (id)initWithCoder:(NSCoder*)aDecoder {
self = [super init];
if (self) {
DCHECK([aDecoder isKindOfClass:[SessionWindowUnarchiver class]]);
_selectedIndex = [aDecoder cr_decodeIndexForKey:kSelectedIndexKey];
_sessions.reset([[aDecoder decodeObjectForKey:kSessionsKey] retain]);
DCHECK(
[self isIndex:_selectedIndex validForSessionCount:[_sessions count]]);
// If index is somehow corrupted, reset it to zero.
// (note that if |_selectedIndex| == |_sessions.size()|, that's
// incorrect because the maximum index of a vector of size |n| is |n-1|).
// Empty sessions should have |_selectedIndex| values of NSNotFound.
if (![_sessions count]) {
_selectedIndex = NSNotFound;
} else if (_selectedIndex >= [_sessions count]) {
_selectedIndex = 0;
}
}
return self;
}
- (void)encodeWithCoder:(NSCoder*)aCoder {
[aCoder cr_encodeIndex:_selectedIndex forKey:kSelectedIndexKey];
[aCoder encodeObject:_sessions forKey:kSessionsKey];
}
#pragma mark -
- (BOOL)isIndex:(NSUInteger)index
validForSessionCount:(NSUInteger)sessionCount {
return (sessionCount && index < sessionCount) ||
(!sessionCount && index == NSNotFound);
}
- (NSString*)description {
return [NSString stringWithFormat:@"selected index: %" PRIuNS
"\nsessions:\n%@\n",
_selectedIndex, _sessions.get()];
}
@end