Clean up Internal Settings
This commit is contained in:
parent
665fda1f2a
commit
0ca83a1b50
@ -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 */,
|
||||
|
||||
@ -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.") }
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
@ -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.";
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user