diff --git a/src/Storage/AxolotlStore/TSStorageManager+SessionStore.h b/src/Storage/AxolotlStore/TSStorageManager+SessionStore.h index aa7c6f009..b33f33119 100644 --- a/src/Storage/AxolotlStore/TSStorageManager+SessionStore.h +++ b/src/Storage/AxolotlStore/TSStorageManager+SessionStore.h @@ -1,9 +1,5 @@ // -// TSStorageManager+SessionStore.h -// TextSecureKit -// -// Created by Frederic Jacobs on 06/11/14. -// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // #import @@ -11,4 +7,8 @@ @interface TSStorageManager (SessionStore) +#pragma mark - debug + +- (void)printAllSessions; + @end diff --git a/src/Storage/AxolotlStore/TSStorageManager+SessionStore.m b/src/Storage/AxolotlStore/TSStorageManager+SessionStore.m index 3993f7eed..4fbb680fa 100644 --- a/src/Storage/AxolotlStore/TSStorageManager+SessionStore.m +++ b/src/Storage/AxolotlStore/TSStorageManager+SessionStore.m @@ -1,9 +1,5 @@ // -// TSStorageManager+SessionStore.m -// TextSecureKit -// -// Created by Frederic Jacobs on 06/11/14. -// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // #import "TSStorageManager+SessionStore.h" @@ -12,6 +8,9 @@ @implementation TSStorageManager (SessionStore) + +#pragma mark - SessionStore + - (SessionRecord *)loadSession:(NSString *)contactIdentifier deviceId:(int)deviceId { NSDictionary *dictionary = [self dictionaryForKey:contactIdentifier inCollection:TSStorageManagerSessionStoreCollection]; @@ -47,6 +46,13 @@ } - (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]; @@ -80,9 +86,56 @@ [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 *previousStates = + [sessionRecord previousSessionStates]; + DDLogDebug(@"%@ Device: %@ SessionRecord: %@ activeSessionState: " + @"%@ previousSessionStates: %@", + tag, + key, + sessionRecord, + activeState, + previousStates); + }]; + }]; + }]; +} + @end