You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-ios/src/Storage/AxolotlStore/TSStorageManager+SessionSto...

142 lines
6.1 KiB
Objective-C

//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "TSStorageManager+SessionStore.h"
#define TSStorageManagerSessionStoreCollection @"TSStorageManagerSessionStoreCollection"
@implementation TSStorageManager (SessionStore)
#pragma mark - SessionStore
- (SessionRecord *)loadSession:(NSString *)contactIdentifier deviceId:(int)deviceId {
NSDictionary *dictionary =
[self dictionaryForKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection];
SessionRecord *record;
if (dictionary) {
record = [dictionary objectForKey:[self keyForInt:deviceId]];
}
if (!record) {
return [SessionRecord new];
}
return record;
}
- (NSArray *)subDevicesSessions:(NSString *)contactIdentifier {
NSDictionary *dictionary =
[self objectForKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection];
NSMutableArray *subDevicesSessions = [NSMutableArray array];
if (dictionary) {
for (NSString *key in [dictionary allKeys]) {
NSNumber *number = @([key doubleValue]);
[subDevicesSessions addObject:number];
}
}
return subDevicesSessions;
}
- (void)storeSession:(NSString *)contactIdentifier deviceId:(int)deviceId session:(SessionRecord *)session {
// We need to ensure subsequent usage of this SessionRecord does not consider this session as "fresh". Normally this
// is achieved by marking things as "not fresh" at the point of deserialization - when we fetch a SessionRecord from
// YapDB (initWithCoder:). However, because YapDB has an object cache, rather than fetching/deserializing, it's
// possible we'd get back *this* exact instance of the object (which, at this point, is still potentially "fresh"),
// thus we explicitly mark this instance as "unfresh", any time we save.
[session markAsUnFresh];
NSMutableDictionary *dictionary =
[[self dictionaryForKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection] mutableCopy];
if (!dictionary) {
dictionary = [NSMutableDictionary dictionary];
}
[dictionary setObject:session forKey:[self keyForInt:deviceId]];
[self setObject:dictionary forKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection];
}
- (BOOL)containsSession:(NSString *)contactIdentifier deviceId:(int)deviceId {
return [self loadSession:contactIdentifier deviceId:deviceId].sessionState.hasSenderChain;
}
- (void)deleteSessionForContact:(NSString *)contactIdentifier deviceId:(int)deviceId {
NSMutableDictionary *dictionary =
[[self dictionaryForKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection] mutableCopy];
if (!dictionary) {
dictionary = [NSMutableDictionary dictionary];
}
[dictionary removeObjectForKey:[self keyForInt:deviceId]];
[self setObject:dictionary forKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection];
}
- (void)deleteAllSessionsForContact:(NSString *)contactIdentifier {
[self removeObjectForKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection];
}
#pragma mark - util
- (NSNumber *)keyForInt:(int)number {
return [NSNumber numberWithInt:number];
}
#pragma mark - debug
- (void)printAllSessions
{
NSString *tag = @"[TSStorageManager (SessionStore)]";
[self.dbConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
DDLogDebug(@"%@ All Sessions:", tag);
[transaction
enumerateKeysAndObjectsInCollection:TSStorageManagerSessionStoreCollection
usingBlock:^(NSString *_Nonnull key,
id _Nonnull deviceSessionsObject,
BOOL *_Nonnull stop) {
if (![deviceSessionsObject isKindOfClass:[NSDictionary class]]) {
OWSAssert(NO);
DDLogError(
@"%@ Unexpected type: %@ in collection.", tag, deviceSessionsObject);
return;
}
NSDictionary *deviceSessions = (NSDictionary *)deviceSessionsObject;
DDLogDebug(@"%@ Sessions for recipient: %@", tag, key);
[deviceSessions enumerateKeysAndObjectsUsingBlock:^(
id _Nonnull key, id _Nonnull sessionRecordObject, BOOL *_Nonnull stop) {
if (![sessionRecordObject isKindOfClass:[SessionRecord class]]) {
OWSAssert(NO);
DDLogError(@"%@ Unexpected type: %@ in collection.",
tag,
sessionRecordObject);
return;
}
SessionRecord *sessionRecord = (SessionRecord *)sessionRecordObject;
SessionState *activeState = [sessionRecord sessionState];
NSArray<SessionState *> *previousStates =
[sessionRecord previousSessionStates];
DDLogDebug(@"%@ Device: %@ SessionRecord: %@ activeSessionState: "
@"%@ previousSessionStates: %@",
tag,
key,
sessionRecord,
activeState,
previousStates);
}];
}];
}];
}
@end