Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App: UISI AutoReporting #5743

Merged
merged 10 commits into from
Mar 24, 2022
4 changes: 4 additions & 0 deletions Config/BuildSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ final class BuildSettings: NSObject {
static let bugReportEndpointUrlString = "https://riot.im/bugreports"
// Use the name allocated by the bug report server
static let bugReportApplicationId = "riot-ios"
static let bugReportUISIId = "element-auto-uisi"


// MARK: - Integrations
Expand Down Expand Up @@ -377,6 +378,9 @@ final class BuildSettings: NSObject {
// MARK: - Secrets Recovery
static let secretsRecoveryAllowReset = true

// MARK: - UISI Autoreporting
static let cryptoUISIAutoReportingEnabled = false

// MARK: - Polls

static var pollsEnabled: Bool {
Expand Down
44 changes: 22 additions & 22 deletions Riot/Assets/en.lproj/Vector.strings
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,7 @@ Tap the + to start adding people.";
"settings_labs_enable_ringing_for_group_calls" = "Ring for group calls";
"settings_labs_enabled_polls" = "Polls";
"settings_labs_enable_threads" = "Threaded messaging";
"settings_labs_enable_auto_report_decryption_errors" = "Auto Report Decryption Errors";
"settings_labs_use_only_latest_user_avatar_and_name" = "Show latest avatar and name for users in message history";

"settings_version" = "Version %@";
Expand Down Expand Up @@ -2424,7 +2425,7 @@ Tap the + to start adding people.";
"language_picker_title" = "Choose a language";
"language_picker_default_language" = "Default (%@)";

/* -*-
/* -*-
Automatic localization for en

The following key/value pairs were extracted from the android i18n file:
Expand Down Expand Up @@ -2507,35 +2508,35 @@ Tap the + to start adding people.";
"notice_room_history_visible_to_members_from_joined_point_by_you" = "You made future room history visible to all room members, from the point they joined.";
"notice_room_history_visible_to_members_from_joined_point_by_you_for_dm" = "You made future messages visible to everyone, from when they joined.";

// Room Screen
// Room Screen

// general errors
// general errors

// Home Screen
// Home Screen

// Last seen time
// Last seen time

// call events
// call events

/* -*-
/* -*-
Automatic localization for en

The following key/value pairs were extracted from the android i18n file:
/console/src/main/res/values/strings.xml.
*/


// titles
// titles

// button names
// button names
"send" = "Send";
"copy_button_name" = "Copy";
"resend" = "Resend";
"redact" = "Remove";
"share" = "Share";
"delete" = "Delete";

// actions
// actions
"action_logout" = "Logout";
"create_room" = "Create Room";
"login" = "Login";
Expand All @@ -2550,32 +2551,32 @@ Tap the + to start adding people.";
"unban" = "Un-ban";
"message_unsaved_changes" = "There are unsaved changes. Leaving will discard them.";

// Login Screen
// Login Screen
"login_error_already_logged_in" = "Already logged in";
"login_error_must_start_http" = "URL must start with http[s]://";

// members list Screen
// members list Screen

// accounts list Screen
// accounts list Screen

// image size selection
// image size selection

// invitation members list Screen
// invitation members list Screen

// room creation dialog Screen
// room creation dialog Screen

// room info dialog Screen

// room details dialog screen

// contacts list screen
// contacts list screen
"invitation_message" = "I\'d like to chat with you with matrix. Please, visit the website http://matrix.org to have more information.";

// Settings screen
// Settings screen
"settings_title_config" = "Configuration";
"settings_title_notifications" = "Notifications";

// Notification settings screen
// Notification settings screen
"notification_settings_disable_all" = "Disable all notifications";
"notification_settings_enable_notifications" = "Enable notifications";
"notification_settings_enable_notifications_warning" = "All notifications are currently disabled for all devices.";
Expand All @@ -2602,10 +2603,10 @@ Tap the + to start adding people.";
"notification_settings_by_default" = "By default...";
"notification_settings_notify_all_other" = "Notify for all other messages/rooms";

// gcm section
// gcm section
"settings_config_identity_server" = "Identity server: %@";

// Settings keys
// Settings keys

// call string
"call_connecting" = "Connecting…";
Expand Down Expand Up @@ -2638,4 +2639,3 @@ Tap the + to start adding people.";
"ssl_unexpected_existing_expl" = "The certificate has changed from one that was trusted by your phone. This is HIGHLY UNUSUAL. It is recommended that you DO NOT ACCEPT this new certificate.";
"ssl_expected_existing_expl" = "The certificate has changed from a previously trusted one to one that is not trusted. The server may have renewed its certificate. Contact the server administrator for the expected fingerprint.";
"ssl_only_accept" = "ONLY accept the certificate if the server administrator has published a fingerprint that matches the one above.";

26 changes: 26 additions & 0 deletions Riot/Categories/Codable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Copyright 2021 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

extension Encodable {
/// Convenience method to get the json string of an Encodable
var jsonString: String? {
let encoder = JSONEncoder()
guard let jsonData = try? encoder.encode(self) else { return nil }
return String(data: jsonData, encoding: .utf8)
}
}
114 changes: 114 additions & 0 deletions Riot/Categories/MXBugReportRestClient+Riot.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
//
// Copyright 2021 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
import MatrixSDK
import GBDeviceInfo

extension MXBugReportRestClient {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pixlwave I extracted the common common code for sending reports from the app in case it's useful for your needs.


@objc static func vc_bugReportRestClient(appName: String) -> MXBugReportRestClient {
let client = MXBugReportRestClient(bugReportEndpoint: BuildSettings.bugReportEndpointUrlString)
// App info
client.appName = appName
client.version = AppDelegate.theDelegate().appVersion
client.build = AppDelegate.theDelegate().build

client.deviceModel = GBDeviceInfo.deviceInfo().modelString
client.deviceOS = "\(UIDevice.current.systemName) \(UIDevice.current.systemVersion)"
return client
}

@objc func vc_sendBugReport(
description: String,
sendLogs: Bool,
sendCrashLog: Bool,
sendFiles: [URL]? = nil,
additionalLabels: [String]? = nil,
customFields: [String: String]? = nil,
progress: ((MXBugReportState, Progress?) -> Void)? = nil,
success: ((String?) -> Void)? = nil,
failure: ((Error?) -> Void)? = nil
) {
// User info (TODO: handle multi-account and find a way to expose them in rageshake API)
var userInfo = [String: String]()
let mainAccount = MXKAccountManager.shared().accounts.first
if let userId = mainAccount?.mxSession.myUser.userId {
userInfo["user_id"] = userId
}
if let deviceId = mainAccount?.mxSession.matrixRestClient.credentials.deviceId {
userInfo["device_id"] = deviceId
}

userInfo["locale"] = NSLocale.preferredLanguages[0]
userInfo["default_app_language"] = Bundle.main.preferredLocalizations[0] // The language chosen by the OS
userInfo["app_language"] = Bundle.mxk_language() ?? userInfo["default_app_language"] // The language chosen by the user

// Application settings
userInfo["lazy_loading"] = MXKAppSettings.standard().syncWithLazyLoadOfRoomMembers ? "ON" : "OFF"

let currentDate = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
userInfo["local_time"] = dateFormatter.string(from: currentDate)

dateFormatter.timeZone = TimeZone(identifier: "UTC")
userInfo["utc_time"] = dateFormatter.string(from: currentDate)

if let customFields = customFields {
// combine userInfo with custom fields overriding with custom where there is a conflict
userInfo.merge(customFields) { (_, new) in new }
}
others = userInfo

var labels: [String] = additionalLabels ?? [String]()
// Add a Github label giving information about the version
if var versionLabel = version, let buildLabel = build {

// If this is not the app store version, be more accurate on the build origin
if buildLabel == VectorL10n.settingsConfigNoBuildInfo {
// This is a debug session from Xcode
versionLabel += "-debug"
} else if !buildLabel.contains("master") {
// This is a Jenkins build. Add the branch and the build number
let buildString = buildLabel.replacingOccurrences(of: " ", with: "-")
versionLabel += "-\(buildString)"
}
labels += [versionLabel]
}
if sendCrashLog {
labels += ["crash"]
}

var sendDescription = description
if sendCrashLog,
let crashLogFile = MXLogger.crashLog(),
let crashLog = try? String(contentsOfFile: crashLogFile, encoding: .utf8) {
// Append the crash dump to the user description in order to ease triaging of GH issues
sendDescription += "\n\n\n--------------------------------------------------------------------------------\n\n\(crashLog)"
}

sendBugReport(sendDescription,
sendLogs: sendLogs,
sendCrashLog: sendCrashLog,
sendFiles: sendFiles,
attachGitHubLabels: labels,
progress: progress,
success: success,
failure: failure)
}

}
37 changes: 37 additions & 0 deletions Riot/Categories/Publisher+Riot.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// Copyright 2021 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 Combine

@available(iOS 14.0, *)
extension Publisher {

///
/// Buffer upstream items and guarantee a time interval spacing out the published items.
/// - Parameters:
/// - spacingDelay: A delay in seconds to guarantee between emissions
/// - scheduler: The `DispatchQueue` on which to schedule emissions.
/// - Returns: The new wrapped publisher
func bufferAndSpace(spacingDelay: Int, scheduler: DispatchQueue = DispatchQueue.main) -> Publishers.FlatMap<
Publishers.SetFailureType<Publishers.Delay<Just<Publishers.Buffer<Self>.Output>, DispatchQueue>, Publishers.Buffer<Self>.Failure>,
Publishers.Buffer<Self>
> {
return buffer(size: .max, prefetch: .byRequest, whenFull: .dropNewest)
.flatMap(maxPublishers: .max(1)) {
Just($0).delay(for: .seconds(spacingDelay), scheduler: scheduler)
}
}
}
4 changes: 4 additions & 0 deletions Riot/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6667,6 +6667,10 @@ public class VectorL10n: NSObject {
public static var settingsLabsE2eEncryptionPromptMessage: String {
return VectorL10n.tr("Vector", "settings_labs_e2e_encryption_prompt_message")
}
/// Auto Report Decryption Errors
public static var settingsLabsEnableAutoReportDecryptionErrors: String {
return VectorL10n.tr("Vector", "settings_labs_enable_auto_report_decryption_errors")
}
/// Ring for group calls
public static var settingsLabsEnableRingingForGroupCalls: String {
return VectorL10n.tr("Vector", "settings_labs_enable_ringing_for_group_calls")
Expand Down
29 changes: 29 additions & 0 deletions Riot/Managers/Settings/RiotSettings+Publisher.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Copyright 2021 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
import Combine

extension RiotSettings {

@available(iOS 13.0, *)
func publisher(for key: String) -> AnyPublisher<Notification, Never> {
return NotificationCenter.default.publisher(for: .userDefaultValueUpdated)
.filter({ $0.object as? String == key })
.eraseToAnyPublisher()
}

}
5 changes: 5 additions & 0 deletions Riot/Managers/Settings/RiotSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ final class RiotSettings: NSObject {
static let pinRoomsWithMissedNotificationsOnHome = "pinRoomsWithMissedNotif"
static let pinRoomsWithUnreadMessagesOnHome = "pinRoomsWithUnread"
static let showAllRoomsInHomeSpace = "showAllRoomsInHomeSpace"
static let enableUISIAutoReporting = "enableUISIAutoReporting"
}

static let shared = RiotSettings()
Expand Down Expand Up @@ -146,6 +147,10 @@ final class RiotSettings: NSObject {
@UserDefault(key: "enableThreads", defaultValue: false, storage: defaults)
var enableThreads

/// Indicates if auto reporting of decryption errors is enabled
@UserDefault(key: UserDefaultsKeys.enableUISIAutoReporting, defaultValue: BuildSettings.cryptoUISIAutoReportingEnabled, storage: defaults)
var enableUISIAutoReporting

// MARK: Calls

/// Indicate if `allowStunServerFallback` settings has been set once.
Expand Down
Loading