Clean up Internal Settings

This commit is contained in:
Sasha Weiss 2026-05-22 15:46:13 -07:00 committed by GitHub
parent 665fda1f2a
commit 0ca83a1b50
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 90 additions and 520 deletions

View File

@ -534,7 +534,6 @@
45A1684D2A1C308800C2432D /* AudioPresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A1684C2A1C308800C2432D /* AudioPresentation.swift */; };
45A2F005204473A3002E978A /* NewMessage.aifc in Resources */ = {isa = PBXBuildFile; fileRef = 45A2F004204473A3002E978A /* NewMessage.aifc */; };
45A3579827DAAC6A0051CE8B /* UserProfileTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A3579727DAAC6A0051CE8B /* UserProfileTest.swift */; };
45B27B862037FFB400A539DF /* InternalFileBrowserViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B27B852037FFB400A539DF /* InternalFileBrowserViewController.swift */; };
45B3680B2A1D75DF0067D05A /* AudioAllMediaPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B3680A2A1D75DF0067D05A /* AudioAllMediaPresenter.swift */; };
45B74A742044AAB600CD42F8 /* aurora-quiet.aifc in Resources */ = {isa = PBXBuildFile; fileRef = 45B74A5B2044AAB300CD42F8 /* aurora-quiet.aifc */; };
45B74A752044AAB600CD42F8 /* synth-quiet.aifc in Resources */ = {isa = PBXBuildFile; fileRef = 45B74A5C2044AAB300CD42F8 /* synth-quiet.aifc */; };
@ -601,7 +600,6 @@
4CA485BB2232339F004B9E7D /* PhotoCaptureViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CA485BA2232339F004B9E7D /* PhotoCaptureViewController.swift */; };
4CB5F26720F6E1E2004D1B42 /* MessageActionsToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CFF4C0920F55BBA005DA313 /* MessageActionsToolbar.swift */; };
4CB5F26920F7D060004D1B42 /* MessageActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB5F26820F7D060004D1B42 /* MessageActions.swift */; };
4CBBFE4A2306F5D300B37450 /* LogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CBBFE492306F5D300B37450 /* LogViewController.swift */; };
4CC1ECF9211A47CE00CC13BE /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CC1ECF8211A47CD00CC13BE /* StoreKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
4CD675BE22E7BE35008010D2 /* MediaDismissAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CD675BD22E7BE35008010D2 /* MediaDismissAnimationController.swift */; };
4CD675C522E7CF22008010D2 /* ConversationViewController+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CD675C422E7CF22008010D2 /* ConversationViewController+OWS.swift */; };
@ -1287,6 +1285,7 @@
66D31DAD2BC48E0100EAF735 /* OWSContactAddress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D31DAC2BC48E0100EAF735 /* OWSContactAddress.swift */; };
66D31DAF2BC48E3A00EAF735 /* OWSContactName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D31DAE2BC48E3A00EAF735 /* OWSContactName.swift */; };
66D31F972E5E685300A1C82D /* InternalListMediaViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D31F962E5E684E00A1C82D /* InternalListMediaViewController.swift */; };
66D31FA02E5E685300A1C82D /* InternalBackupSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D31FA12E5E684E00A1C82D /* InternalBackupSettingsViewController.swift */; };
66D709E928E3999400B5013A /* StoryContextAssociatedData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D709E828E3999400B5013A /* StoryContextAssociatedData.swift */; };
66D7B8FF2B9287F00005C98B /* AttachmentManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D7B8FE2B9287F00005C98B /* AttachmentManager.swift */; };
66D7B9012B92889E0005C98B /* AttachmentManagerImpl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D7B9002B92889E0005C98B /* AttachmentManagerImpl.swift */; };
@ -4754,7 +4753,6 @@
45A3579727DAAC6A0051CE8B /* UserProfileTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileTest.swift; sourceTree = "<group>"; };
45A663C41F92EC760027B59E /* GroupTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupTableViewCell.swift; sourceTree = "<group>"; };
45A6DAD51EBBF85500893231 /* ReminderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReminderView.swift; sourceTree = "<group>"; };
45B27B852037FFB400A539DF /* InternalFileBrowserViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InternalFileBrowserViewController.swift; sourceTree = "<group>"; };
45B3680A2A1D75DF0067D05A /* AudioAllMediaPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioAllMediaPresenter.swift; sourceTree = "<group>"; };
45B74A5B2044AAB300CD42F8 /* aurora-quiet.aifc */ = {isa = PBXFileReference; lastKnownFileType = file; path = "aurora-quiet.aifc"; sourceTree = "<group>"; };
45B74A5C2044AAB300CD42F8 /* synth-quiet.aifc */ = {isa = PBXFileReference; lastKnownFileType = file; path = "synth-quiet.aifc"; sourceTree = "<group>"; };
@ -4837,7 +4835,6 @@
4CA485BA2232339F004B9E7D /* PhotoCaptureViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoCaptureViewController.swift; sourceTree = "<group>"; };
4CB5F26820F7D060004D1B42 /* MessageActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageActions.swift; sourceTree = "<group>"; };
4CB93DC12180FF07004B9764 /* ProximityMonitoringManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProximityMonitoringManager.swift; sourceTree = "<group>"; };
4CBBFE492306F5D300B37450 /* LogViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewController.swift; sourceTree = "<group>"; };
4CC1ECF8211A47CD00CC13BE /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
4CD675BD22E7BE35008010D2 /* MediaDismissAnimationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaDismissAnimationController.swift; sourceTree = "<group>"; };
4CD675C422E7CF22008010D2 /* ConversationViewController+OWS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ConversationViewController+OWS.swift"; sourceTree = "<group>"; };
@ -5567,6 +5564,7 @@
66D31DAC2BC48E0100EAF735 /* OWSContactAddress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OWSContactAddress.swift; sourceTree = "<group>"; };
66D31DAE2BC48E3A00EAF735 /* OWSContactName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OWSContactName.swift; sourceTree = "<group>"; };
66D31F962E5E684E00A1C82D /* InternalListMediaViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InternalListMediaViewController.swift; sourceTree = "<group>"; };
66D31FA12E5E684E00A1C82D /* InternalBackupSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InternalBackupSettingsViewController.swift; sourceTree = "<group>"; };
66D709E828E3999400B5013A /* StoryContextAssociatedData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoryContextAssociatedData.swift; sourceTree = "<group>"; };
66D7B8FE2B9287F00005C98B /* AttachmentManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentManager.swift; sourceTree = "<group>"; };
66D7B9002B92889E0005C98B /* AttachmentManagerImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentManagerImpl.swift; sourceTree = "<group>"; };
@ -11441,12 +11439,11 @@
isa = PBXGroup;
children = (
344A761024B366F4009D69A5 /* FlagsViewController.swift */,
66D31FA12E5E684E00A1C82D /* InternalBackupSettingsViewController.swift */,
665229882E218D53002C14A0 /* InternalDiskUsageViewController.swift */,
45B27B852037FFB400A539DF /* InternalFileBrowserViewController.swift */,
66D31F962E5E684E00A1C82D /* InternalListMediaViewController.swift */,
8862A55825F090C5005D65DB /* InternalSettingsViewController.swift */,
663883562D4C034F008EA898 /* InternalSQLClientViewController.swift */,
4CBBFE492306F5D300B37450 /* LogViewController.swift */,
344A761224B36C8C009D69A5 /* TestingViewController.swift */,
);
path = Internal;
@ -18508,8 +18505,8 @@
D9E43C072CC194140001536E /* IndividualCallViewController.swift in Sources */,
D97046062E81D4240034C05D /* InfoMessageGroupUpdateMigrator.swift in Sources */,
88BCCC8123837B7D00CE5FE6 /* InteractionReactionState.swift in Sources */,
66D31FA02E5E685300A1C82D /* InternalBackupSettingsViewController.swift in Sources */,
665229892E218D5F002C14A0 /* InternalDiskUsageViewController.swift in Sources */,
45B27B862037FFB400A539DF /* InternalFileBrowserViewController.swift in Sources */,
66D31F972E5E685300A1C82D /* InternalListMediaViewController.swift in Sources */,
8862A55925F090C5005D65DB /* InternalSettingsViewController.swift in Sources */,
663883572D4C0360008EA898 /* InternalSQLClientViewController.swift in Sources */,
@ -18533,7 +18530,6 @@
4C25768A23AD510800E0398D /* LoadMoreMessagesView.swift in Sources */,
D9E43C082CC194140001536E /* LocalVideoView.swift in Sources */,
88A9729422FB4D02004B4FBF /* LocationPicker.swift in Sources */,
4CBBFE4A2306F5D300B37450 /* LogViewController.swift in Sources */,
3496744F2076ACD000080B5F /* LongTextViewController.swift in Sources */,
88A941992409A391000E9700 /* LottieToggleButton.swift in Sources */,
5033D46929D7951F007FEADA /* MainAppContext.swift in Sources */,

View File

@ -148,9 +148,6 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
debugLogger.enableFileLogging(appContext: mainAppContext, canLaunchInBackground: true)
DebugLogger.configureSwiftLogging()
if DebugFlags.audibleErrorLogging {
debugLogger.enableErrorReporting()
}
Logger.warn("Launching…")
defer { Logger.info("Launched.") }

View File

@ -0,0 +1,82 @@
//
// Copyright 2026 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import SignalServiceKit
import SignalUI
class InternalBackupSettingsViewController: OWSTableViewController2 {
override func viewDidLoad() {
super.viewDidLoad()
title = "Backups"
updateTableContents()
}
func updateTableContents() {
let contents = OWSTableContents()
let section = OWSTableSection()
let backupSettingsStore = BackupSettingsStore()
let db = DependenciesBridge.shared.db
let lastBackupDetails = db.read { tx in
return backupSettingsStore.lastBackupDetails(tx: tx)
}
section.add(.copyableItem(
label: "Last Backup chats/messages file size",
value: lastBackupDetails.flatMap { ByteCountFormatter().string(for: $0.backupFileSizeBytes) },
))
section.add(.actionItem(withText: "Enable Backups onboarding flow") { [weak self] in
let backupSettingsStore = BackupSettingsStore()
let db = DependenciesBridge.shared.db
db.write { tx in
backupSettingsStore.setShouldOverrideShowBackupsOnboarding(true, tx: tx)
}
self?.presentToast(text: "Backups onboarding enabled!")
})
section.add(.actionItem(withText: #"Show "Backup Key Reminder" flow"#) { [weak self] in
guard let self else { return }
let accountKeyStore = DependenciesBridge.shared.accountKeyStore
let db = DependenciesBridge.shared.db
guard let aep = db.read(block: { accountKeyStore.getAccountEntropyPool(tx: $0) }) else {
presentToast(text: "Missing AEP?!")
return
}
BackupRecoveryKeyReminderCoordinator(
aep: aep,
fromViewController: self,
onSuccess: {
self.presentToast(text: "Success!")
},
).presentVerifyFlow()
})
section.add(.actionItem(withText: "Backup media integrity check") { [weak self] in
let vc = InternalListMediaViewController()
self?.navigationController?.pushViewController(vc, animated: true)
})
if RemoteConfig.current.isOptimizeStorageEnabled {
section.add(.switch(
withText: "Aggressive optimize media",
subtitle: "Don't keep recent attachments when optimize media is enabled",
isOn: { Attachment.offloadingThresholdOverride },
actionBlock: { _ in
Attachment.offloadingThresholdOverride = !Attachment.offloadingThresholdOverride
},
))
}
contents.add(section)
self.contents = contents
}
}

View File

@ -1,101 +0,0 @@
//
// Copyright 2018 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import SignalServiceKit
import SignalUI
class InternalFileBrowserViewController: OWSTableViewController2 {
private let fileManager: FileManager
private let fileURL: URL
init(fileURL: URL) {
self.fileManager = .default
self.fileURL = fileURL
super.init()
self.contents = buildContents()
}
private func buildContents() -> OWSTableContents {
var isDirectory: ObjCBool = false
guard fileManager.fileExists(atPath: fileURL.path, isDirectory: &isDirectory) else {
return OWSTableContents(title: "File not found: \(fileURL)")
}
var sections = [OWSTableSection]()
// Put the URL somewhere it'll wrap and is copyable.
sections.append(OWSTableSection(items: [
.copyableItem(
label: "Current File URL",
value: fileURL.absoluteString,
),
]))
if isDirectory.boolValue {
let directoryContents: [URL]
do {
directoryContents = try fileManager.contentsOfDirectory(
at: fileURL,
includingPropertiesForKeys: [.isDirectoryKey],
)
} catch {
owsFailDebug("Failed to get contents of \(fileURL)! \(error)")
directoryContents = []
}
let fileItems: [OWSTableItem] = directoryContents.map { contentsUrl in
let fileIsDirectory: Bool
do {
fileIsDirectory = try contentsUrl.resourceValues(forKeys: [.isDirectoryKey]).isDirectory!
} catch {
owsFailDebug("Failed to get isDirectory resource value! \(error)")
fileIsDirectory = false
}
let icon = fileIsDirectory ? "📁" : "📄"
return .disclosureItem(
withText: "\(icon): \(contentsUrl.lastPathComponent)",
actionBlock: { [weak self] in
guard let self else { return }
navigationController?.pushViewController(
InternalFileBrowserViewController(fileURL: contentsUrl),
animated: true,
)
},
)
}
sections.append(OWSTableSection(
title: "Contents",
items: fileItems,
))
}
do {
let attributes: [FileAttributeKey: Any] = try fileManager.attributesOfItem(atPath: fileURL.path)
let attributeItems: [OWSTableItem] = attributes
.sorted(by: { $0.key.rawValue < $1.key.rawValue })
.map { fileAttribute, value in
return .copyableItem(
label: fileAttribute.rawValue.replacingOccurrences(of: "NSFile", with: ""),
value: "\(value)",
)
}
sections.append(OWSTableSection(
title: "Attributes",
items: attributeItems,
))
} catch {
owsFailDebug("Failed to get attributes for \(fileURL)! \(error)")
}
return OWSTableContents(sections: sections)
}
}

View File

@ -4,8 +4,6 @@
//
import AVFoundation
import GRDB
import LibSignalClient
import SignalServiceKit
import SignalUI
@ -51,17 +49,6 @@ class InternalSettingsViewController: OWSTableViewController2 {
))
#endif
if DebugFlags.audibleErrorLogging {
debugSection.add(.disclosureItem(
withText: OWSLocalizedString("SETTINGS_ADVANCED_VIEW_ERROR_LOG", comment: ""),
actionBlock: { [weak self] in
Logger.flush()
let vc = LogPickerViewController(logDirUrl: DebugLogger.errorLogsDir)
self?.navigationController?.pushViewController(vc, animated: true)
},
))
}
debugSection.add(.disclosureItem(
withText: "Remote Configs",
actionBlock: { [weak self] in
@ -92,42 +79,11 @@ class InternalSettingsViewController: OWSTableViewController2 {
self?.navigationController?.pushViewController(vc, animated: true)
},
))
debugSection.add(.actionItem(
withText: "Run Database Integrity Checks",
debugSection.add(.disclosureItem(
withText: "Backups",
actionBlock: { [weak self] in
guard let self else { return }
ModalActivityIndicatorViewController.present(
fromViewController: self,
) { modal in
let databaseStorage = SSKEnvironment.shared.databaseStorageRef
let integrityCheckResult = GRDBDatabaseStorageAdapter.checkIntegrity(
databaseStorage: databaseStorage,
)
modal.dismiss {
switch integrityCheckResult {
case .ok:
self.presentToast(text: "Integrity check: ok! More detail in logs.")
case .notOk:
self.presentToast(text: "Integrity check: not ok! More detail in logs.")
}
}
}
},
))
debugSection.add(.actionItem(
withText: "Clean Orphaned Data",
actionBlock: { [weak self] in
guard let self else { return }
ModalActivityIndicatorViewController.present(
fromViewController: self,
canCancel: false,
asyncBlock: { modalActivityIndicator in
try? await OWSOrphanDataCleaner.cleanUp(shouldRemoveOrphanedData: true)
modalActivityIndicator.dismiss()
},
)
let vc = InternalBackupSettingsViewController()
self?.navigationController?.pushViewController(vc, animated: true)
},
))
@ -139,98 +95,6 @@ class InternalSettingsViewController: OWSTableViewController2 {
contents.add(debugSection)
let backupsSection = OWSTableSection(title: "Backups")
let backupSettingsStore = BackupSettingsStore()
let db = DependenciesBridge.shared.db
let lastBackupDetails = db.read { tx in
return backupSettingsStore.lastBackupDetails(tx: tx)
}
backupsSection.add(.actionItem(withText: "Export + Validate Message Backup proto") { [self] in
Task {
await exportMessageBackupProto()
}
})
if SSKEnvironment.shared.remoteConfigManagerRef.currentConfig().isOptimizeStorageEnabled {
backupsSection.add(.switch(
withText: "Offload all attachments",
subtitle: "If on and \"Optimize Storage\" enabled, offload all attachments instead of only those >30d old",
isOn: { Attachment.offloadingThresholdOverride },
actionBlock: { _ in
Attachment.offloadingThresholdOverride = !Attachment.offloadingThresholdOverride
},
))
}
backupsSection.add(.actionItem(withText: "Enable Backups onboarding flow") { [weak self] in
let backupSettingsStore = BackupSettingsStore()
let db = DependenciesBridge.shared.db
db.write { tx in
backupSettingsStore.setShouldOverrideShowBackupsOnboarding(true, tx: tx)
}
self?.presentToast(text: "Backups onboarding enabled!")
})
backupsSection.add(.copyableItem(
label: "Last Backup chats/messages file size",
value: lastBackupDetails.flatMap { ByteCountFormatter().string(for: $0.backupFileSizeBytes) },
))
backupsSection.add(.actionItem(withText: #"Show "Backup Key Reminder" flow"#) { [weak self] in
guard let self else { return }
let accountKeyStore = DependenciesBridge.shared.accountKeyStore
let db = DependenciesBridge.shared.db
guard let aep = db.read(block: { accountKeyStore.getAccountEntropyPool(tx: $0) }) else {
presentToast(text: "Missing AEP?!")
return
}
BackupRecoveryKeyReminderCoordinator(
aep: aep,
fromViewController: self,
onSuccess: {
self.presentToast(text: "Success!")
},
).presentVerifyFlow()
})
backupsSection.add(.actionItem(withText: "Backup media integrity check") { [weak self] in
let vc = InternalListMediaViewController()
self?.navigationController?.pushViewController(vc, animated: true)
})
contents.add(backupsSection)
do {
func makeFileBrowsingActionItem(_ title: String, _ fileUrl: URL) -> OWSTableItem {
return .actionItem(
withText: title,
actionBlock: { [weak self] in
guard let self else { return }
navigationController?.pushViewController(
InternalFileBrowserViewController(fileURL: fileUrl),
animated: true,
)
},
)
}
let fileBrowsingSection = OWSTableSection(title: "Browse App Files")
fileBrowsingSection.add(makeFileBrowsingActionItem(
"App Container: Library",
URL(string: OWSFileSystem.appLibraryDirectoryPath())!.deletingLastPathComponent(),
))
fileBrowsingSection.add(makeFileBrowsingActionItem(
"App Container: Documents",
URL(string: OWSFileSystem.appDocumentDirectoryPath())!.deletingLastPathComponent(),
))
fileBrowsingSection.add(makeFileBrowsingActionItem(
"Shared App Container",
URL(string: OWSFileSystem.appSharedDataDirectoryPath())!.deletingLastPathComponent(),
))
contents.add(fileBrowsingSection)
}
let (
contactThreadCount,
groupThreadCount,
@ -412,66 +276,4 @@ private extension InternalSettingsViewController {
}
InMemorySettings.spinningCheckmarks = !wasSpinning
}
func exportMessageBackupProto() async {
let accountKeyStore = DependenciesBridge.shared.accountKeyStore
let backupArchiveManager = DependenciesBridge.shared.backupArchiveManager
let db = DependenciesBridge.shared.db
let tsAccountManager = DependenciesBridge.shared.tsAccountManager
let backupKey: MessageBackupKey
let exportMetadata: Upload.EncryptedBackupUploadMetadata
do {
(backupKey, exportMetadata) = try await ModalActivityIndicatorViewController.presentAndPropagateResult(
from: self,
title: "Exporting...",
) {
let (messageBackupKey, localIdentifiers) = try db.read { tx in
let localIdentifiers = try tsAccountManager.registeredState(tx: tx).localIdentifiers
return (
try accountKeyStore.getMessageRootBackupKey(aci: localIdentifiers.aci, tx: tx)!,
localIdentifiers,
)
}
let backupKey = try MessageBackupKey(
backupKey: messageBackupKey.backupKey,
backupId: messageBackupKey.backupId,
)
let exportMetadata = try await backupArchiveManager.exportEncryptedBackup(
localIdentifiers: localIdentifiers,
backupPurpose: .remoteExport(key: messageBackupKey, chatAuth: .implicit()),
progress: nil,
logger: PrefixedLogger(prefix: "[Backups]"),
)
return (backupKey, exportMetadata)
}
} catch {
let message = "Failed to export Backup proto! \(error)"
Logger.error(message)
presentToast(text: message)
return
}
let keyString = "AES key: \(backupKey.aesKey.base64EncodedString())"
+ "\nHMAC key: \(backupKey.hmacKey.base64EncodedString())"
let activityVC = UIActivityViewController(
activityItems: [exportMetadata.fileUrl],
applicationActivities: nil,
)
activityVC.popoverPresentationController?.sourceView = view
activityVC.completionWithItemsHandler = { [self] _, _, _, _ in
UIPasteboard.general.setItems(
[[UIPasteboard.typeAutomatic: keyString]],
options: [.expirationDate: Date().addingTimeInterval(120)],
)
presentToast(text: "Success! Encryption key copied.")
}
present(activityVC, animated: true)
}
}

View File

@ -1,168 +0,0 @@
//
// Copyright 2019 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import SignalServiceKit
public import SignalUI
public class LogPickerViewController: OWSTableViewController2 {
let logDirUrl: URL
public init(logDirUrl: URL) {
self.logDirUrl = logDirUrl
super.init()
}
override public func viewDidLoad() {
super.viewDidLoad()
updateTableContents()
}
public func updateTableContents() {
let contents = OWSTableContents()
contents.add(buildPreferenceSection())
contents.add(buildActionsSection())
contents.add(buildLogsSection())
self.contents = contents
}
private func buildPreferenceSection() -> OWSTableSection {
let chooChoo = OWSTableItem.switch(
withText: "🚂 Play Sound When Errors Occur",
isOn: { Preferences.isAudibleErrorLoggingEnabled },
target: self,
selector: #selector(didToggleAudiblePreference(_:)),
)
let failDebug = OWSTableItem.switch(
withText: "💥 Crash When owsFailDebugs Occur",
isOn: { Preferences.isFailDebugEnabled },
target: self,
selector: #selector(didToggleFailDebug(_:)),
)
return OWSTableSection(title: "Preferences", items: [chooChoo, failDebug])
}
private func buildActionsSection() -> OWSTableSection {
let exportItem = OWSTableItem(title: "Export Logs") {
Logger.flush()
DebugLogs.exportLogs()
}
return OWSTableSection(title: "Actions", items: [exportItem])
}
private func buildLogsSection() -> OWSTableSection {
guard let directoryEnumerator = FileManager.default.enumerator(at: logDirUrl, includingPropertiesForKeys: nil) else {
owsFailDebug("logUrls was unexpectedly nil")
return OWSTableSection(title: "No Log URLs", items: [])
}
let logUrls: [URL] = directoryEnumerator.compactMap { $0 as? URL }
let sortedUrls = logUrls.sorted { a, b -> Bool in
return a.lastPathComponent > b.lastPathComponent
}
let logItems: [OWSTableItem] = sortedUrls.map { logUrl in
return OWSTableItem(
customCellBlock: { () -> UITableViewCell in
let cell = OWSTableItem.newCell()
guard let textLabel = cell.textLabel else {
owsFailDebug("textLabel was unexpectedly nil")
return cell
}
textLabel.lineBreakMode = .byTruncatingHead
textLabel.text = logUrl.lastPathComponent
return cell
},
actionBlock: { [weak self] in
guard let self else { return }
let logVC = LogViewController(logUrl: logUrl)
guard let navigationController = self.navigationController else {
owsFailDebug("navigationController was unexpectedly nil")
return
}
navigationController.pushViewController(logVC, animated: true)
},
)
}
return OWSTableSection(title: "View Logs", items: logItems)
}
@objc
private func didToggleAudiblePreference(_ sender: UISwitch) {
Preferences.setIsAudibleErrorLoggingEnabled(sender.isOn)
if sender.isOn {
ErrorLogger.playAlertSound()
}
}
@objc
private func didToggleFailDebug(_ sender: UISwitch) {
Preferences.setIsFailDebugEnabled(sender.isOn)
}
}
public class LogViewController: UIViewController {
let logUrl: URL
public init(logUrl: URL) {
self.logUrl = logUrl
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let textView = UITextView()
override public func loadView() {
self.view = textView
loadLogText()
}
override public func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItems = [
UIBarButtonItem(image: Theme.iconImage(.buttonShare), style: .plain, target: self, action: #selector(didTapShare(_:))),
UIBarButtonItem(image: Theme.iconImage(.buttonDelete), style: .plain, target: self, action: #selector(didTapTrash(_:))),
]
}
func loadLogText() {
do {
// This is super crude, but:
// 1. generally we should haven't a ton of logged errors
// 2. this is a dev tool
let logData = try Data(contentsOf: logUrl)
// TODO most recent lines on top?
textView.text = String(data: logData, encoding: .utf8)
} catch {
textView.text = "Failed to load log data: \(error)"
}
}
@objc
private func didTapTrash(_ sender: UIBarButtonItem) {
// truncate logUrl
do {
try NSData().write(to: logUrl)
loadLogText()
} catch {
owsFailDebug("error: \(error)")
}
}
@objc
private func didTapShare(_ sender: UIBarButtonItem) {
let logText = textView.text ?? "Empty Log"
let vc = UIActivityViewController(activityItems: [logText], applicationActivities: [])
present(vc, animated: true)
}
}

View File

@ -8308,9 +8308,6 @@
/* No comment provided by engineer. */
"SETTINGS_ADVANCED_SUBMIT_DEBUGLOG" = "Submit Debug Log";
/* No comment provided by engineer. */
"SETTINGS_ADVANCED_VIEW_ERROR_LOG" = "Error Logs";
/* Information on sheet about changing the app icon - first line */
"SETTINGS_APP_ICON_EDUCATION_APP_NAME" = "The app name “Signal” will be visible on the Home Screen, in notifications and in the App Library.";

View File

@ -3,7 +3,6 @@
// SPDX-License-Identifier: AGPL-3.0-only
//
import AudioToolbox
import CocoaLumberjack
import LibSignalClient
import SignalRingRTC
@ -59,19 +58,6 @@ private final class DebugLogFileManager: DDLogFileManagerDefault {
}
}
public final class ErrorLogger: DDFileLogger {
public static func playAlertSound() {
AudioServicesPlayAlertSound(SystemSoundID(1023))
}
override public func log(message logMessage: DDLogMessage) {
super.log(message: logMessage)
if Preferences.isAudibleErrorLoggingEnabled {
Self.playAlertSound()
}
}
}
public final class DebugLogger {
private init() {}
@ -105,8 +91,6 @@ public final class DebugLogger {
DebugLogger.nseDebugLogsDirPath,
]
public static let errorLogsDir = URL(fileURLWithPath: OWSFileSystem.cachesDirectoryPath().appendingPathComponent("ErrorLogs"))
public var fileLogger: DDFileLogger?
public var allLogFilePaths: Set<String> {
let fileManager = FileManager.default
@ -129,12 +113,6 @@ public final class DebugLogger {
return logPathSet
}
public func enableErrorReporting() {
let errorLogger = ErrorLogger(logFileManager: DDLogFileManagerDefault(logsDirectory: Self.errorLogsDir.path))
errorLogger.logFormatter = ScrubbingLogFormatter()
DDLog.add(errorLogger, with: .error)
}
// MARK: Enable/Disable
public func enableFileLogging(appContext: AppContext, canLaunchInBackground: Bool) {

View File

@ -25,8 +25,6 @@ private let build = FeatureBuild.current
/// it's easier to review which feature flags are in play.
public enum BuildFlags {
public static let choochoo = build <= .internal
public static let failDebug = build <= .internal
public static let linkedPhones = build <= .internal
@ -151,8 +149,6 @@ public enum DebugFlags {
public static let testPopulationErrorAlerts = build <= .beta
public static let audibleErrorLogging = build <= .internal
public static let internalSettings = build <= .internal
public static let internalMegaphoneEligible = build <= .internal

View File

@ -49,7 +49,6 @@ public class Preferences {
private enum UserDefaultsKeys {
static let deviceScale = "OWSPreferencesKeyDeviceScale"
static let isAudibleErrorLoggingEnabled = "IsAudibleErrorLoggingEnabled"
static let isFailDebugEnabled = "IsFailDebugEnabled"
}
@ -147,14 +146,6 @@ public class Preferences {
CurrentAppContext().appUserDefaults().set(value, forKey: UserDefaultsKeys.isFailDebugEnabled)
}
public static var isAudibleErrorLoggingEnabled: Bool {
CurrentAppContext().appUserDefaults().bool(forKey: UserDefaultsKeys.isAudibleErrorLoggingEnabled) && BuildFlags.choochoo
}
public static func setIsAudibleErrorLoggingEnabled(_ value: Bool) {
CurrentAppContext().appUserDefaults().set(value, forKey: UserDefaultsKeys.isAudibleErrorLoggingEnabled)
}
// MARK: Specific Preferences
public var isScreenSecurityEnabled: Bool {