mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-05-14 11:49:59 +02:00
Merge pull request #1917 from vector-im/e2e_telemetry_
Crypto: Add telemetry for events unable to decrypt (UTDs)
This commit is contained in:
@@ -6,6 +6,7 @@ Improvements:
|
||||
* RoomVC: Add a re-request keys button on message unable to decrypt (#1879).
|
||||
* Analytics: Move code from AppDelegate to a dedicated class: Analytics.
|
||||
* Analytics: Track Matrix SDK stats (time to startup the app).
|
||||
* Crypto: Add telemetry for events unable to decrypt (UTDs).
|
||||
* Added the i18n localisation strings to the accessibility labels (#1842), thanks to @einMarco (PR#1906).
|
||||
* Added titles to sound files ID3 tags.
|
||||
|
||||
|
||||
@@ -64,6 +64,8 @@
|
||||
3267EFB820E379FE00FF1CAA /* Podfile in Resources */ = {isa = PBXBuildFile; fileRef = 3267EFB420E379FD00FF1CAA /* Podfile */; };
|
||||
3267EFB920E379FE00FF1CAA /* AUTHORS.rst in Resources */ = {isa = PBXBuildFile; fileRef = 3267EFB520E379FD00FF1CAA /* AUTHORS.rst */; };
|
||||
3267EFBA20E379FE00FF1CAA /* README.rst in Resources */ = {isa = PBXBuildFile; fileRef = 3267EFB620E379FD00FF1CAA /* README.rst */; };
|
||||
3267EFC020E4A3DD00FF1CAA /* DecryptionFailureTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 3267EFBE20E4A3DD00FF1CAA /* DecryptionFailureTracker.m */; };
|
||||
3267EFC320E5055800FF1CAA /* DecryptionFailure.m in Sources */ = {isa = PBXBuildFile; fileRef = 3267EFC220E5055800FF1CAA /* DecryptionFailure.m */; };
|
||||
327382B51F276AD200356143 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 327382A81F276AD200356143 /* InfoPlist.strings */; };
|
||||
327382B61F276AD200356143 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 327382AA1F276AD200356143 /* Localizable.strings */; };
|
||||
327382B71F276AD200356143 /* Vector.strings in Resources */ = {isa = PBXBuildFile; fileRef = 327382AC1F276AD200356143 /* Vector.strings */; };
|
||||
@@ -736,6 +738,10 @@
|
||||
3267EFB420E379FD00FF1CAA /* Podfile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Podfile; sourceTree = "<group>"; };
|
||||
3267EFB520E379FD00FF1CAA /* AUTHORS.rst */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AUTHORS.rst; sourceTree = "<group>"; };
|
||||
3267EFB620E379FD00FF1CAA /* README.rst */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.rst; sourceTree = "<group>"; };
|
||||
3267EFBE20E4A3DD00FF1CAA /* DecryptionFailureTracker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DecryptionFailureTracker.m; path = Riot/Analytics/DecryptionFailureTracker.m; sourceTree = SOURCE_ROOT; };
|
||||
3267EFBF20E4A3DD00FF1CAA /* DecryptionFailureTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DecryptionFailureTracker.h; path = Riot/Analytics/DecryptionFailureTracker.h; sourceTree = SOURCE_ROOT; };
|
||||
3267EFC120E5055800FF1CAA /* DecryptionFailure.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DecryptionFailure.h; path = Riot/Analytics/DecryptionFailure.h; sourceTree = SOURCE_ROOT; };
|
||||
3267EFC220E5055800FF1CAA /* DecryptionFailure.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = DecryptionFailure.m; path = Riot/Analytics/DecryptionFailure.m; sourceTree = SOURCE_ROOT; };
|
||||
327382A91F276AD200356143 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = InfoPlist.strings; sourceTree = "<group>"; };
|
||||
327382AB1F276AD200356143 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = Localizable.strings; sourceTree = "<group>"; };
|
||||
327382AD1F276AD200356143 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = Vector.strings; sourceTree = "<group>"; };
|
||||
@@ -1613,6 +1619,10 @@
|
||||
children = (
|
||||
3267EFB020E2A04100FF1CAA /* Analytics.h */,
|
||||
3267EFB120E2A04100FF1CAA /* Analytics.m */,
|
||||
3267EFBF20E4A3DD00FF1CAA /* DecryptionFailureTracker.h */,
|
||||
3267EFBE20E4A3DD00FF1CAA /* DecryptionFailureTracker.m */,
|
||||
3267EFC120E5055800FF1CAA /* DecryptionFailure.h */,
|
||||
3267EFC220E5055800FF1CAA /* DecryptionFailure.m */,
|
||||
);
|
||||
name = Analytics;
|
||||
path = "New Group";
|
||||
@@ -3622,6 +3632,7 @@
|
||||
F083BE2D1E7009ED00A9B29C /* ForgotPasswordInputsView.m in Sources */,
|
||||
F083BE7E1E7009ED00A9B29C /* InviteRecentTableViewCell.m in Sources */,
|
||||
F083BE3C1E7009ED00A9B29C /* RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.m in Sources */,
|
||||
3267EFC320E5055800FF1CAA /* DecryptionFailure.m in Sources */,
|
||||
F083BE211E7009ED00A9B29C /* RoomSearchViewController.m in Sources */,
|
||||
32185B311F20FA2B00752141 /* LanguagePickerViewController.m in Sources */,
|
||||
F083BE3E1E7009ED00A9B29C /* RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.m in Sources */,
|
||||
@@ -3686,6 +3697,7 @@
|
||||
F083BE101E7009ED00A9B29C /* CountryPickerViewController.m in Sources */,
|
||||
F083BE581E7009ED00A9B29C /* RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m in Sources */,
|
||||
F083BDF61E7009ED00A9B29C /* Contact.m in Sources */,
|
||||
3267EFC020E4A3DD00FF1CAA /* DecryptionFailureTracker.m in Sources */,
|
||||
F083BE961E7009ED00A9B29C /* MessagesSearchResultAttachmentBubbleCell.m in Sources */,
|
||||
F083BE391E7009ED00A9B29C /* RoomEncryptedDataBubbleCell.m in Sources */,
|
||||
F083BDF01E7009ED00A9B29C /* UIViewController+RiotSearch.m in Sources */,
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <MatrixSDK/MatrixSDK.h>
|
||||
#import "DecryptionFailureTracker.h"
|
||||
|
||||
/**
|
||||
`Analytics` sends analytics to an analytics tool.
|
||||
*/
|
||||
@interface Analytics : NSObject <MXAnalyticsDelegate>
|
||||
@interface Analytics : NSObject <MXAnalyticsDelegate, MXDecryptionFailureDelegate>
|
||||
|
||||
/**
|
||||
Returns the shared Analytics manager.
|
||||
|
||||
+29
-12
@@ -22,8 +22,14 @@
|
||||
// Then, there are 2 Piwik actions: "iOS.startup" and "iOS.stats" (these actions
|
||||
// are namespaced by plaform to have a nice rendering on the Piwik website).
|
||||
// Then, we use constants defined by the Matrix SDK as Piwik Names (ex:"mountData")
|
||||
NSString *const kAnalyticsPiwikMetricsCategory = @"Metrics";
|
||||
NSString *const kAnalyticsPiwikMetricsActionPattern = @"iOS.%@";
|
||||
NSString *const kAnalyticsMetricsCategory = @"Metrics";
|
||||
NSString *const kAnalyticsMetricsActionPattern = @"iOS.%@";
|
||||
|
||||
// E2E telemetry is stored under a Piwik category called "E2E".
|
||||
NSString *const kAnalyticsE2eCategory = @"E2E";
|
||||
NSString *const kAnalyticsE2eDecryptionFailureAction = @"Decryption failure";
|
||||
NSString *const kAnalyticsE2eDecryptionFailureReasonNoReason = @"no_reason";
|
||||
|
||||
|
||||
@import PiwikTracker;
|
||||
|
||||
@@ -111,9 +117,9 @@ NSString *const kAnalyticsPiwikMetricsActionPattern = @"iOS.%@";
|
||||
|
||||
- (void)trackLaunchScreenDisplayDuration:(NSTimeInterval)seconds
|
||||
{
|
||||
NSString *action = [NSString stringWithFormat:kAnalyticsPiwikMetricsActionPattern, kMXAnalyticsStartupCategory];
|
||||
NSString *action = [NSString stringWithFormat:kAnalyticsMetricsActionPattern, kMXAnalyticsStartupCategory];
|
||||
|
||||
[[PiwikTracker shared] trackWithEventWithCategory:kAnalyticsPiwikMetricsCategory
|
||||
[[PiwikTracker shared] trackWithEventWithCategory:kAnalyticsMetricsCategory
|
||||
action:action
|
||||
name:kMXAnalyticsStartupLaunchScreen
|
||||
number:@(seconds * 1000)
|
||||
@@ -124,9 +130,9 @@ NSString *const kAnalyticsPiwikMetricsActionPattern = @"iOS.%@";
|
||||
|
||||
- (void)trackStartupStorePreloadDuration: (NSTimeInterval)seconds
|
||||
{
|
||||
NSString *action = [NSString stringWithFormat:kAnalyticsPiwikMetricsActionPattern, kMXAnalyticsStartupCategory];
|
||||
NSString *action = [NSString stringWithFormat:kAnalyticsMetricsActionPattern, kMXAnalyticsStartupCategory];
|
||||
|
||||
[[PiwikTracker shared] trackWithEventWithCategory:kAnalyticsPiwikMetricsCategory
|
||||
[[PiwikTracker shared] trackWithEventWithCategory:kAnalyticsMetricsCategory
|
||||
action:action
|
||||
name:kMXAnalyticsStartupStorePreload
|
||||
number:@(seconds * 1000)
|
||||
@@ -135,9 +141,9 @@ NSString *const kAnalyticsPiwikMetricsActionPattern = @"iOS.%@";
|
||||
|
||||
- (void)trackStartupMountDataDuration: (NSTimeInterval)seconds
|
||||
{
|
||||
NSString *action = [NSString stringWithFormat:kAnalyticsPiwikMetricsActionPattern, kMXAnalyticsStartupCategory];
|
||||
NSString *action = [NSString stringWithFormat:kAnalyticsMetricsActionPattern, kMXAnalyticsStartupCategory];
|
||||
|
||||
[[PiwikTracker shared] trackWithEventWithCategory:kAnalyticsPiwikMetricsCategory
|
||||
[[PiwikTracker shared] trackWithEventWithCategory:kAnalyticsMetricsCategory
|
||||
action:action
|
||||
name:kMXAnalyticsStartupMountData
|
||||
number:@(seconds * 1000)
|
||||
@@ -146,9 +152,9 @@ NSString *const kAnalyticsPiwikMetricsActionPattern = @"iOS.%@";
|
||||
|
||||
- (void)trackStartupSyncDuration: (NSTimeInterval)seconds isInitial: (BOOL)isInitial
|
||||
{
|
||||
NSString *action = [NSString stringWithFormat:kAnalyticsPiwikMetricsActionPattern, kMXAnalyticsStartupCategory];
|
||||
NSString *action = [NSString stringWithFormat:kAnalyticsMetricsActionPattern, kMXAnalyticsStartupCategory];
|
||||
|
||||
[[PiwikTracker shared] trackWithEventWithCategory:kAnalyticsPiwikMetricsCategory
|
||||
[[PiwikTracker shared] trackWithEventWithCategory:kAnalyticsMetricsCategory
|
||||
action:action
|
||||
name:isInitial ? kMXAnalyticsStartupInititialSync : kMXAnalyticsStartupIncrementalSync
|
||||
number:@(seconds * 1000)
|
||||
@@ -157,13 +163,24 @@ NSString *const kAnalyticsPiwikMetricsActionPattern = @"iOS.%@";
|
||||
|
||||
- (void)trackRoomCount: (NSUInteger)roomCount
|
||||
{
|
||||
NSString *action = [NSString stringWithFormat:kAnalyticsPiwikMetricsActionPattern, kMXAnalyticsStatsCategory];
|
||||
NSString *action = [NSString stringWithFormat:kAnalyticsMetricsActionPattern, kMXAnalyticsStatsCategory];
|
||||
|
||||
[[PiwikTracker shared] trackWithEventWithCategory:kAnalyticsPiwikMetricsCategory
|
||||
[[PiwikTracker shared] trackWithEventWithCategory:kAnalyticsMetricsCategory
|
||||
action:action
|
||||
name:kMXAnalyticsStatsRooms
|
||||
number:@(roomCount)
|
||||
url:nil];
|
||||
}
|
||||
|
||||
#pragma mark - MXDecryptionFailureDelegate
|
||||
|
||||
- (void)trackFailures:(NSUInteger)failuresCount
|
||||
{
|
||||
[[PiwikTracker shared] trackWithEventWithCategory:kAnalyticsE2eCategory
|
||||
action:kAnalyticsE2eDecryptionFailureAction
|
||||
name:kAnalyticsE2eDecryptionFailureReasonNoReason
|
||||
number:@(failuresCount)
|
||||
url:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/**
|
||||
`DecryptionFailure` represents a decryption failure.
|
||||
*/
|
||||
@interface DecryptionFailure : NSObject
|
||||
|
||||
/**
|
||||
The id of the event that was unabled to decrypt.
|
||||
*/
|
||||
@property (nonatomic) NSString *failedEventId;
|
||||
|
||||
/**
|
||||
The time the failure has been reported.
|
||||
*/
|
||||
@property (nonatomic, readonly) NSTimeInterval ts;
|
||||
|
||||
/**
|
||||
Decryption failure reason.
|
||||
*/
|
||||
@property (nonatomic) NSString *reason;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "DecryptionFailure.h"
|
||||
|
||||
@implementation DecryptionFailure
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
_ts = [NSDate date].timeIntervalSince1970;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@import MatrixSDK;
|
||||
|
||||
@protocol MXDecryptionFailureDelegate;
|
||||
|
||||
@interface DecryptionFailureTracker : NSObject
|
||||
|
||||
/**
|
||||
Returns the shared tracker.
|
||||
|
||||
@return the shared tracker.
|
||||
*/
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
/**
|
||||
The delegate object to receive analytics events.
|
||||
*/
|
||||
@property (nonatomic) id<MXDecryptionFailureDelegate> delegate;
|
||||
|
||||
/**
|
||||
Report an event unable to decrypt.
|
||||
|
||||
This error can be momentary. The DecryptionFailureTracker will check if it gets
|
||||
fixed. Else, it will generate a failure (@see `trackFailures`).
|
||||
|
||||
@param event the event.
|
||||
@param roomState the room state when the event was received.
|
||||
@param userId my user id.
|
||||
*/
|
||||
- (void)reportUnableToDecryptErrorForEvent:(MXEvent*)event withRoomState:(MXRoomState*)roomState myUser:(NSString*)userId;
|
||||
|
||||
/**
|
||||
Flush current data.
|
||||
*/
|
||||
- (void)dispatch;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
The `MXDecryptionFailureDelegate` protocol receives some stats computed by
|
||||
`DecryptionFailureTracker`.
|
||||
*/
|
||||
@protocol MXDecryptionFailureDelegate <NSObject>
|
||||
|
||||
/**
|
||||
Stats for decryption failures.
|
||||
|
||||
@param failuresCount the number of decryption failures.
|
||||
*/
|
||||
- (void)trackFailures:(NSUInteger)failuresCount;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "DecryptionFailureTracker.h"
|
||||
|
||||
#import "DecryptionFailure.h"
|
||||
|
||||
|
||||
// Call `checkFailures` every `CHECK_INTERVAL`
|
||||
#define CHECK_INTERVAL 5
|
||||
|
||||
// Give events a chance to be decrypted by waiting `GRACE_PERIOD` before counting
|
||||
// and reporting them as failures
|
||||
#define GRACE_PERIOD 60
|
||||
|
||||
|
||||
@interface DecryptionFailureTracker()
|
||||
{
|
||||
// Reported failures
|
||||
// Every `CHECK_INTERVAL`, this list is checked for failures that happened
|
||||
// more than`GRACE_PERIOD` ago. Those that did are reported to the delegate.
|
||||
NSMutableDictionary<NSString* /* eventId */, DecryptionFailure*> *reportedFailures;
|
||||
|
||||
// Event ids of failures that were tracked previously
|
||||
NSMutableSet<NSString*> *trackedEvents;
|
||||
|
||||
// Timer for periodic check
|
||||
NSTimer *checkFailuresTimer;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation DecryptionFailureTracker
|
||||
|
||||
+ (instancetype)sharedInstance
|
||||
{
|
||||
static DecryptionFailureTracker *sharedInstance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [[DecryptionFailureTracker alloc] init];
|
||||
});
|
||||
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
reportedFailures = [NSMutableDictionary dictionary];
|
||||
trackedEvents = [NSMutableSet set];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(eventDidDecrypt:) name:kMXEventDidDecryptNotification object:nil];
|
||||
|
||||
checkFailuresTimer = [NSTimer scheduledTimerWithTimeInterval:CHECK_INTERVAL
|
||||
target:self
|
||||
selector:@selector(checkFailures)
|
||||
userInfo:nil
|
||||
repeats:YES];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)reportUnableToDecryptErrorForEvent:(MXEvent *)event withRoomState:(MXRoomState *)roomState myUser:(NSString *)userId
|
||||
{
|
||||
if (reportedFailures[event.eventId] || [trackedEvents containsObject:event.eventId])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Filter out "expected" UTDs
|
||||
// We cannot decrypt messages sent before the user joined the room
|
||||
MXRoomMember *myUser = [roomState memberWithUserId:userId];
|
||||
if (!myUser || myUser.membership != MXMembershipJoin)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DecryptionFailure *decryptionFailure = [[DecryptionFailure alloc] init];
|
||||
decryptionFailure.failedEventId = event.eventId;
|
||||
|
||||
// TODO: Need to sync with all platforms
|
||||
// decryptionFailure.reason =;
|
||||
|
||||
reportedFailures[event.eventId] = decryptionFailure;
|
||||
}
|
||||
|
||||
- (void)dispatch
|
||||
{
|
||||
[self checkFailures];
|
||||
}
|
||||
|
||||
#pragma mark - Private methods
|
||||
|
||||
/**
|
||||
Mark reported failures that occured before tsNow - GRACE_PERIOD as failures that should be
|
||||
tracked.
|
||||
*/
|
||||
- (void)checkFailures
|
||||
{
|
||||
NSTimeInterval tsNow = [NSDate date].timeIntervalSince1970;
|
||||
|
||||
NSMutableArray *failuresToTrack = [NSMutableArray array];
|
||||
|
||||
for (DecryptionFailure *reportedFailure in reportedFailures.allValues)
|
||||
{
|
||||
if (reportedFailure.ts < tsNow - GRACE_PERIOD)
|
||||
{
|
||||
[failuresToTrack addObject:reportedFailure];
|
||||
[reportedFailures removeObjectForKey:reportedFailure.failedEventId];
|
||||
[trackedEvents addObject:reportedFailure.failedEventId];
|
||||
}
|
||||
}
|
||||
|
||||
if (_delegate && failuresToTrack.count)
|
||||
{
|
||||
NSLog(@"[DecryptionFailureTracker] trackFailures: %@", @(failuresToTrack.count));
|
||||
[_delegate trackFailures:failuresToTrack.count];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)eventDidDecrypt:(NSNotification *)notif
|
||||
{
|
||||
// Could be an event in the reportedFailures, remove it
|
||||
MXEvent *event = notif.object;
|
||||
[reportedFailures removeObjectForKey:event.eventId];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -464,6 +464,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
||||
|
||||
// Configure our analytics. It will indeed start if the option is enabled
|
||||
[MXSDKOptions sharedInstance].analyticsDelegate = [Analytics sharedInstance];
|
||||
[DecryptionFailureTracker sharedInstance].delegate = [Analytics sharedInstance];
|
||||
[[Analytics sharedInstance] start];
|
||||
|
||||
// Prepare Pushkit handling
|
||||
@@ -558,6 +559,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN
|
||||
_isAppForeground = NO;
|
||||
|
||||
// Analytics: Force to send the pending actions
|
||||
[[DecryptionFailureTracker sharedInstance] dispatch];
|
||||
[[Analytics sharedInstance] dispatch];
|
||||
}
|
||||
|
||||
|
||||
+31
-23
@@ -22,6 +22,7 @@
|
||||
#import "WidgetManager.h"
|
||||
|
||||
#import "MXDecryptionResult.h"
|
||||
#import "DecryptionFailureTracker.h"
|
||||
|
||||
#pragma mark - Constants definitions
|
||||
|
||||
@@ -117,34 +118,41 @@ NSString *const kEventFormatterOnReRequestKeysLinkActionSeparator = @"/";
|
||||
NSAttributedString *attributedString = [super attributedStringFromEvent:event withRoomState:roomState error:error];
|
||||
|
||||
if (event.sentState == MXEventSentStateSent
|
||||
&& [event.decryptionError.domain isEqualToString:MXDecryptingErrorDomain]
|
||||
&& event.decryptionError.code == MXDecryptingErrorUnknownInboundSessionIdCode)
|
||||
&& [event.decryptionError.domain isEqualToString:MXDecryptingErrorDomain])
|
||||
{
|
||||
// Append to the displayed error an attibuted string with a tappable link
|
||||
// so that the user can try to fix the UTC
|
||||
NSMutableAttributedString *attributedStringWithRerequestMessage = [attributedString mutableCopy];
|
||||
[attributedStringWithRerequestMessage appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n"]];
|
||||
// Track e2e failures
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[DecryptionFailureTracker sharedInstance] reportUnableToDecryptErrorForEvent:event withRoomState:roomState myUser:mxSession.myUser.userId];
|
||||
});
|
||||
|
||||
NSString *linkActionString = [NSString stringWithFormat:@"%@%@%@", kEventFormatterOnReRequestKeysLinkAction,
|
||||
kEventFormatterOnReRequestKeysLinkActionSeparator,
|
||||
event.eventId];
|
||||
if (event.decryptionError.code == MXDecryptingErrorUnknownInboundSessionIdCode)
|
||||
{
|
||||
// Append to the displayed error an attibuted string with a tappable link
|
||||
// so that the user can try to fix the UTD
|
||||
NSMutableAttributedString *attributedStringWithRerequestMessage = [attributedString mutableCopy];
|
||||
[attributedStringWithRerequestMessage appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n"]];
|
||||
|
||||
[attributedStringWithRerequestMessage appendAttributedString:
|
||||
[[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"event_formatter_rerequest_keys_part1_link", @"Vector", nil)
|
||||
attributes:@{
|
||||
NSLinkAttributeName: linkActionString,
|
||||
NSForegroundColorAttributeName: self.sendingTextColor,
|
||||
NSFontAttributeName: self.encryptedMessagesTextFont
|
||||
}]];
|
||||
NSString *linkActionString = [NSString stringWithFormat:@"%@%@%@", kEventFormatterOnReRequestKeysLinkAction,
|
||||
kEventFormatterOnReRequestKeysLinkActionSeparator,
|
||||
event.eventId];
|
||||
|
||||
[attributedStringWithRerequestMessage appendAttributedString:
|
||||
[[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"event_formatter_rerequest_keys_part2", @"Vector", nil)
|
||||
attributes:@{
|
||||
NSForegroundColorAttributeName: self.sendingTextColor,
|
||||
NSFontAttributeName: self.encryptedMessagesTextFont
|
||||
}]];
|
||||
[attributedStringWithRerequestMessage appendAttributedString:
|
||||
[[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"event_formatter_rerequest_keys_part1_link", @"Vector", nil)
|
||||
attributes:@{
|
||||
NSLinkAttributeName: linkActionString,
|
||||
NSForegroundColorAttributeName: self.sendingTextColor,
|
||||
NSFontAttributeName: self.encryptedMessagesTextFont
|
||||
}]];
|
||||
|
||||
attributedString = attributedStringWithRerequestMessage;
|
||||
[attributedStringWithRerequestMessage appendAttributedString:
|
||||
[[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"event_formatter_rerequest_keys_part2", @"Vector", nil)
|
||||
attributes:@{
|
||||
NSForegroundColorAttributeName: self.sendingTextColor,
|
||||
NSFontAttributeName: self.encryptedMessagesTextFont
|
||||
}]];
|
||||
|
||||
attributedString = attributedStringWithRerequestMessage;
|
||||
}
|
||||
}
|
||||
|
||||
return attributedString;
|
||||
|
||||
Reference in New Issue
Block a user