diff --git a/Riot/Modules/Analytics/Analytics.swift b/Riot/Modules/Analytics/Analytics.swift index 535ca7b2a..c1e162417 100644 --- a/Riot/Modules/Analytics/Analytics.swift +++ b/Riot/Modules/Analytics/Analytics.swift @@ -83,7 +83,7 @@ import AnalyticsEvents // Catch and log crashes MXLogger.logCrashes(true) - MXLogger.setBuildVersion(AppDelegate.theDelegate().build) + MXLogger.setBuildVersion(AppInfo.current.buildInfo.readableBuildVersion) } /// Use the analytics settings from the supplied session to configure analytics. @@ -200,6 +200,16 @@ extension Analytics { } } + /// Track when a user becomes unauthenticated without pressing the `sign out` button. + /// - Parameters: + /// - reason: The error that occurred. + /// - count: The number of times that error occurred. + func trackAuthUnauthenticatedError(softLogout: Bool, refreshTokenAuth: Bool, errorCode: String, errorReason: String) { + let errorCode = AnalyticsEvent.UnauthenticatedError.ErrorCode(rawValue: errorCode) ?? .M_UNKNOWN + let event = AnalyticsEvent.UnauthenticatedError(errorCode: errorCode, errorReason: errorReason, refreshTokenAuth: refreshTokenAuth, softLogout: softLogout) + client.capture(event) + } + /// Track whether the user accepted or declined the terms to an identity server. /// **Note** This method isn't currently implemented. /// - Parameter accepted: Whether the terms were accepted. diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h index b9eea90a4..e2c56d63d 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h @@ -362,5 +362,5 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer /** Handle unauthenticated errors from the server triggering hard/soft logouts as appropriate. */ -- (void)handleUnauthenticated:(MXError *)error andCompletion:(void (^)(void))completion; +- (void)handleUnauthenticatedWithError:(MXError *)error isSoftLogout:(BOOL)isSoftLogout isRefreshTokenAuth:(BOOL)isRefreshTokenAuth andCompletion:(void (^)(void))completion; @end diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m index 69db12322..0cb776bb2 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m @@ -36,6 +36,8 @@ #import "MXKSwiftHeader.h" +#import "GeneratedInterface-Swift.h" + NSString *const kMXKAccountUserInfoDidChangeNotification = @"kMXKAccountUserInfoDidChangeNotification"; NSString *const kMXKAccountAPNSActivityDidChangeNotification = @"kMXKAccountAPNSActivityDidChangeNotification"; NSString *const kMXKAccountPushKitActivityDidChangeNotification = @"kMXKAccountPushKitActivityDidChangeNotification"; @@ -1700,17 +1702,18 @@ static NSArray *initialSyncSilentErrorsHTTPStatusCodes; } andPersistentTokenDataHandler:^(void (^handler)(NSArray *credentials, void (^completion)(BOOL didUpdateCredentials))) { [MXKAccountManager.sharedManager readAndWriteCredentials:handler]; - } andUnauthenticatedHandler:^(MXError *error, void (^completion)(void)) { + } andUnauthenticatedHandler:^(MXError *error, BOOL isSoftLogout, BOOL isRefreshTokenAuth, void (^completion)(void)) { MXStrongifyAndReturnIfNil(self); - [self handleUnauthenticated:error andCompletion:completion]; + [self handleUnauthenticatedWithError:error isSoftLogout:isSoftLogout isRefreshTokenAuth:isRefreshTokenAuth andCompletion:completion]; }]; } - -- (void)handleUnauthenticated:(MXError *)error andCompletion:(void (^)(void))completion +- (void)handleUnauthenticatedWithError:(MXError *)error isSoftLogout:(BOOL)isSoftLogout isRefreshTokenAuth:(BOOL)isRefreshTokenAuth andCompletion:(void (^)(void))completion { - if (error.httpResponse.statusCode == 401 - && [error.userInfo[kMXErrorSoftLogoutKey] isEqual:@(YES)]) + + [Analytics.shared trackAuthUnauthenticatedErrorWithSoftLogout:isSoftLogout refreshTokenAuth:isRefreshTokenAuth errorCode:error.errcode errorReason:error.error]; + MXLogDebug(@"[MXKAccountManager] handleUnauthenticated: trackAuthUnauthenticatedErrorWithSoftLogout sent"); + if (isSoftLogout) { MXLogDebug(@"[MXKAccountManager] handleUnauthenticated: soft logout."); [[MXKAccountManager sharedManager] softLogout:self]; diff --git a/RiotNSE/NotificationService.swift b/RiotNSE/NotificationService.swift index b6a921b77..543536206 100644 --- a/RiotNSE/NotificationService.swift +++ b/RiotNSE/NotificationService.swift @@ -58,8 +58,8 @@ class NotificationService: UNNotificationServiceExtension { } let restClient = MXRestClient(credentials: userAccount.mxCredentials, unrecognizedCertificateHandler: nil, persistentTokenDataHandler: { persistTokenDataHandler in MXKAccountManager.shared().readAndWriteCredentials(persistTokenDataHandler) - }, unauthenticatedHandler: { error, completion in - userAccount.handleUnauthenticated(error, andCompletion: completion) + }, unauthenticatedHandler: { error, softLogout, refreshTokenAuth, completion in + userAccount.handleUnauthenticatedWithError(error, isSoftLogout: softLogout, isRefreshTokenAuth: refreshTokenAuth, andCompletion: completion) }) return restClient }() @@ -97,6 +97,8 @@ class NotificationService: UNNotificationServiceExtension { // log memory at the beginning of the process logMemory() + setupAnalytics() + UNUserNotificationCenter.current().removeUnwantedNotifications() // check if this is a Matrix notification @@ -170,6 +172,13 @@ class NotificationService: UNNotificationServiceExtension { } } + private func setupAnalytics(){ + // Configure our analytics. It will start if the option is enabled + let analytics = Analytics.shared + MXSDKOptions.sharedInstance().analyticsDelegate = analytics + analytics.startIfEnabled() + } + private func setup(withRoomId roomId: String, eventId: String, completion: @escaping () -> Void) { MXKAccountManager.sharedManager(withReload: true) self.userAccount = MXKAccountManager.shared()?.activeAccounts.first @@ -180,8 +189,8 @@ class NotificationService: UNNotificationServiceExtension { self.logMemory() NotificationService.backgroundSyncService = MXBackgroundSyncService(withCredentials: userAccount.mxCredentials, persistTokenDataHandler: { persistTokenDataHandler in MXKAccountManager.shared().readAndWriteCredentials(persistTokenDataHandler) - }, unauthenticatedHandler: { error, completion in - userAccount.handleUnauthenticated(error, andCompletion: completion) + }, unauthenticatedHandler: { error, softLogout, refreshTokenAuth, completion in + userAccount.handleUnauthenticatedWithError(error, isSoftLogout: softLogout, isRefreshTokenAuth: refreshTokenAuth, andCompletion: completion) }) MXLog.debug("[NotificationService] setup: MXBackgroundSyncService init: AFTER") self.logMemory() diff --git a/RiotNSE/SupportingFiles/RiotNSE-Bridging-Header.h b/RiotNSE/SupportingFiles/RiotNSE-Bridging-Header.h index 41b0ba485..6409af92f 100644 --- a/RiotNSE/SupportingFiles/RiotNSE-Bridging-Header.h +++ b/RiotNSE/SupportingFiles/RiotNSE-Bridging-Header.h @@ -21,4 +21,6 @@ #import "MatrixKit-Bridging-Header.h" +#import "BuildInfo.h" + #endif /* RiotNSE_Bridging_Header_h */ diff --git a/RiotNSE/target.yml b/RiotNSE/target.yml index f01b619a3..669fceeb6 100644 --- a/RiotNSE/target.yml +++ b/RiotNSE/target.yml @@ -62,6 +62,8 @@ targets: - path: ../Riot/Managers/Widgets/WidgetConstants.m - path: ../Riot/PropertyWrappers/UserDefaultsBackedPropertyWrapper.swift - path: ../Riot/Modules/MatrixKit + - path: ../Riot/Modules/Analytics + - path: ../Riot/Managers/AppInfo/ excludes: - "**/*.md" # excludes all files with the .md extension - path: ../Riot/Generated/MatrixKitStrings.swift diff --git a/RiotShareExtension/Shared/ShareManager.m b/RiotShareExtension/Shared/ShareManager.m index bfb58e8bc..d24289188 100644 --- a/RiotShareExtension/Shared/ShareManager.m +++ b/RiotShareExtension/Shared/ShareManager.m @@ -81,9 +81,9 @@ MXWeakify(self); MXRestClient *restClient = [[MXRestClient alloc] initWithCredentials:self.userAccount.mxCredentials andOnUnrecognizedCertificateBlock:nil andPersistentTokenDataHandler:^(void (^handler)(NSArray *credentials, void (^completion)(BOOL didUpdateCredentials))) { [[MXKAccountManager sharedManager] readAndWriteCredentials:handler]; - } andUnauthenticatedHandler:^(MXError *error, void (^completion)(void)) { + } andUnauthenticatedHandler:^(MXError *error, BOOL isSoftLogout, BOOL isRefreshTokenAuth, void (^completion)(void)) { MXStrongifyAndReturnIfNil(self); - [self.userAccount handleUnauthenticated:error andCompletion:completion]; + [self.userAccount handleUnauthenticatedWithError:error isSoftLogout:isSoftLogout isRefreshTokenAuth:isRefreshTokenAuth andCompletion:completion]; }]; MXSession *session = [[MXSession alloc] initWithMatrixRestClient:restClient]; [MXFileStore setPreloadOptions:0]; diff --git a/RiotShareExtension/Sources/ShareExtensionRootViewController.m b/RiotShareExtension/Sources/ShareExtensionRootViewController.m index 90b5006e8..c43eef81e 100644 --- a/RiotShareExtension/Sources/ShareExtensionRootViewController.m +++ b/RiotShareExtension/Sources/ShareExtensionRootViewController.m @@ -52,6 +52,10 @@ [MXLog configure:configuration]; + // Configure our analytics. It will start if the option is enabled + Analytics *analytics = Analytics.shared; + [MXSDKOptions sharedInstance].analyticsDelegate = analytics; + [analytics startIfEnabled]; [ThemeService.shared setThemeId:RiotSettings.shared.userInterfaceTheme]; diff --git a/RiotShareExtension/target.yml b/RiotShareExtension/target.yml index 7f32196f4..1144c2e37 100644 --- a/RiotShareExtension/target.yml +++ b/RiotShareExtension/target.yml @@ -69,6 +69,7 @@ targets: - path: ../Riot/Assets/SharedImages.xcassets buildPhase: resources - path: ../Riot/Modules/MatrixKit + - path: ../Riot/Modules/Analytics excludes: - "**/*.md" # excludes all files with the .md extension - path: ../Riot/Generated/MatrixKitStrings.swift diff --git a/SiriIntents/IntentHandler.m b/SiriIntents/IntentHandler.m index e73af8312..737db0839 100644 --- a/SiriIntents/IntentHandler.m +++ b/SiriIntents/IntentHandler.m @@ -53,6 +53,11 @@ } [MXLog configure:configuration]; + + // Configure our analytics. It will start if the option is enabled + Analytics *analytics = Analytics.shared; + [MXSDKOptions sharedInstance].analyticsDelegate = analytics; + [analytics startIfEnabled]; } return self; } diff --git a/SiriIntents/SupportingFiles/SiriIntents-Bridging-Header.h b/SiriIntents/SupportingFiles/SiriIntents-Bridging-Header.h index 306e2e582..ca6d81962 100644 --- a/SiriIntents/SupportingFiles/SiriIntents-Bridging-Header.h +++ b/SiriIntents/SupportingFiles/SiriIntents-Bridging-Header.h @@ -15,3 +15,4 @@ // #import "MatrixKit-Bridging-Header.h" +#import "BuildInfo.h" diff --git a/SiriIntents/target.yml b/SiriIntents/target.yml index 05aea0ea9..e41030c71 100644 --- a/SiriIntents/target.yml +++ b/SiriIntents/target.yml @@ -51,6 +51,10 @@ targets: - path: ../Riot/Managers/Locale/LocaleProviderType.swift - path: ../Riot/Managers/Locale/LocaleProvider.swift - path: ../Riot/Modules/MatrixKit + - path: ../Riot/Modules/Analytics + - path: ../Riot/Managers/AppInfo/ + - path: ../Riot/Managers/Locale/LocaleProviderType.swift + - path: ../Riot/Generated/Strings.swift excludes: - "**/*.md" # excludes all files with the .md extension - path: ../Riot/Generated/MatrixKitStrings.swift