Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

No Bug: Add sandbox inspector to settings debug section #4295

Merged
merged 1 commit into from Oct 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions Client.xcodeproj/project.pbxproj
Expand Up @@ -226,6 +226,7 @@
2726636924944BFA0056CFE1 /* BraveNewsOptInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2726636824944BFA0056CFE1 /* BraveNewsOptInView.swift */; };
2726637324981B600056CFE1 /* FeedSectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2726637224981B5F0056CFE1 /* FeedSectionHeaderView.swift */; };
2727369B24A65F650096DCB9 /* UIActionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2727369A24A65F650096DCB9 /* UIActionExtensions.swift */; };
272B862B270BD96F005ED304 /* SandboxInspectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 272B862A270BD96F005ED304 /* SandboxInspectorView.swift */; };
27384CAE254360120086922F /* OnboardingRewardsAgreementView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E1D8C6C232BF9C200BDE662 /* OnboardingRewardsAgreementView.swift */; };
273EB3A72422AB24002A8AAF /* PaymentRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9616E6A240EE43F00667C2D /* PaymentRequest.swift */; };
273FCB9A25A7BC5500F279B5 /* BraveNewsDebugSettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 273FCB9925A7BC5500F279B5 /* BraveNewsDebugSettingsController.swift */; };
Expand Down Expand Up @@ -1680,6 +1681,7 @@
2726636824944BFA0056CFE1 /* BraveNewsOptInView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BraveNewsOptInView.swift; sourceTree = "<group>"; };
2726637224981B5F0056CFE1 /* FeedSectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedSectionHeaderView.swift; sourceTree = "<group>"; };
2727369A24A65F650096DCB9 /* UIActionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIActionExtensions.swift; sourceTree = "<group>"; };
272B862A270BD96F005ED304 /* SandboxInspectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SandboxInspectorView.swift; sourceTree = "<group>"; };
273FCB9925A7BC5500F279B5 /* BraveNewsDebugSettingsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BraveNewsDebugSettingsController.swift; sourceTree = "<group>"; };
274398E124E4827800E79605 /* FeedCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedCard.swift; sourceTree = "<group>"; };
274398E424E4829900E79605 /* FeedFillStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedFillStrategy.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4156,6 +4158,7 @@
0A42BC42260CEDA3007EBBF3 /* VPNLogs.swift */,
2F51767325E4024B00429692 /* PlaylistSettingsViewController.swift */,
2F12A175260A3B17005A8C2B /* ShortcutSettingsViewController.swift */,
272B862A270BD96F005ED304 /* SandboxInspectorView.swift */,
);
path = Settings;
sourceTree = "<group>";
Expand Down Expand Up @@ -7257,6 +7260,7 @@
0AAAAC972249174A009A8763 /* SyncAlerts.swift in Sources */,
CA439A7625E8054A00FE9150 /* VideoPlayerControlsView.swift in Sources */,
0A6F957624044F070098217F /* NTPLearnMoreContentView.swift in Sources */,
272B862B270BD96F005ED304 /* SandboxInspectorView.swift in Sources */,
4422D4F221BFFB7600BF1855 /* builder.cc in Sources */,
0A1E84432190A57F0042F782 /* SyncWelcomeViewController.swift in Sources */,
D308E4E41A5306F500842685 /* SearchEngines.swift in Sources */,
Expand Down
127 changes: 127 additions & 0 deletions Client/Frontend/Settings/SandboxInspectorView.swift
@@ -0,0 +1,127 @@
// Copyright 2021 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

import SwiftUI

/// A small file browser that lets you inspect the contents of the apps sandbox.
///
/// Currently it only supports viewing the sizes and file names
struct SandboxInspectorView: View {
private struct Node: Identifiable {
var url: URL
var size: Int
var isDirectory: Bool
var children: [Node]?

var id: String {
url.path
}
}

@State private var nodes: [Node] = []
@State private var total: String = ""
@State private var isLoading: Bool = false

private let formatter = ByteCountFormatter().then {
$0.countStyle = .file
$0.allowsNonnumericFormatting = false
$0.allowedUnits = [.useKB, .useMB, .useGB, .useTB]
}

private func getNodes() {
let fm = FileManager.default
let base = URL(fileURLWithPath: NSHomeDirectory())
func nodes(from base: URL) -> [Node]? {
do {
return try fm.contentsOfDirectory(
at: base,
includingPropertiesForKeys: nil
).compactMap { url -> Node? in
var isDirectory: ObjCBool = false
guard fm.fileExists(atPath: url.path, isDirectory: &isDirectory) else {
return nil
}
let size: Int
var children: [Node]?
if isDirectory.boolValue {
// TODO: Optimize this better, enumerator(at:includingPropertiesForKeys:) already includes every subitem URL, we should construct the entire tree using it
if let subitems = fm.enumerator(
at: url,
includingPropertiesForKeys: nil
)?.allObjects as? [URL], !subitems.isEmpty {
size = try subitems.reduce(0, {
$0 + (try $1.resourceValues(forKeys: [.totalFileAllocatedSizeKey])
.totalFileAllocatedSize ?? 0)
})
children = nodes(from: url)
} else {
size = 0
}
} else {
size = try url.resourceValues(forKeys: [.totalFileAllocatedSizeKey])
.totalFileAllocatedSize ?? 0
}
return Node(
url: url,
size: size,
isDirectory: isDirectory.boolValue,
children: children?.sorted(by: { $0.size > $1.size })
)
}
} catch {
print("Error: \(error)")
return nil
}
}

self.isLoading = true
DispatchQueue.global(qos: .userInitiated).async {
let nodes = nodes(from: base) ?? []
DispatchQueue.main.async {
self.nodes = nodes.sorted(by: { $0.size > $1.size })
self.total = formatter.string(fromByteCount: Int64(self.nodes.reduce(0, { $0 + $1.size })))
self.isLoading = false
}
}
}

var body: some View {
List {
Section {
HStack {
Text("Total Size")
Spacer()
Text(total)
}
}
.listRowBackground(Color(.secondaryBraveGroupedBackground))
Section {
if isLoading {
ProgressView()
.progressViewStyle(CircularProgressViewStyle())
.frame(maxWidth: .infinity)
} else {
OutlineGroup(nodes, children: \.children) { row in
HStack {
Label {
Text(row.url.lastPathComponent)
} icon: {
Image(systemName: "folder")
.opacity(row.isDirectory ? 1 : 0)
}
Spacer()
Text(formatter.string(fromByteCount: Int64(row.size)))
}
.font(.callout)
}
}
}
.listRowBackground(Color(.secondaryBraveGroupedBackground))
}
.navigationTitle("Sandbox Inspector")
.navigationBarTitleDisplayMode(.inline)
.onAppear(perform: getNodes)
}
}
4 changes: 4 additions & 0 deletions Client/Frontend/Settings/SettingsViewController.swift
Expand Up @@ -507,6 +507,10 @@ class SettingsViewController: TableViewController {
return Static.Section(
rows: [
Row(text: "Region: \(Locale.current.regionCode ?? "--")"),
Row(text: "Sandbox Inspector", selection: { [unowned self] in
let vc = UIHostingController(rootView: SandboxInspectorView())
self.navigationController?.pushViewController(vc, animated: true)
}, accessory: .disclosureIndicator),
Row(text: "Adblock Debug", selection: { [unowned self] in
let vc = AdblockDebugMenuTableViewController(style: .grouped)
self.navigationController?.pushViewController(vc, animated: true)
Expand Down