feat: implement disable, uninstall and revert
This commit is contained in:
40
Cargo.lock
generated
40
Cargo.lock
generated
@@ -394,9 +394,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-lock"
|
||||
version = "3.4.1"
|
||||
version = "3.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc"
|
||||
checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
"event-listener-strategy",
|
||||
@@ -744,9 +744,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.49"
|
||||
version = "1.2.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215"
|
||||
checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"jobserver",
|
||||
@@ -801,9 +801,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.56"
|
||||
version = "0.1.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b042e5d8a74ae91bb0961acd039822472ec99f8ab0948cbf6d1369588f8be586"
|
||||
checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
@@ -1907,9 +1907,9 @@ checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010"
|
||||
|
||||
[[package]]
|
||||
name = "jiff"
|
||||
@@ -2917,9 +2917,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.11.1"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
|
||||
checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd"
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic-util"
|
||||
@@ -3777,18 +3777,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.7.3"
|
||||
version = "0.7.5+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533"
|
||||
checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.23.9"
|
||||
version = "0.23.10+spec-1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832"
|
||||
checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"toml_datetime",
|
||||
@@ -3798,18 +3798,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_parser"
|
||||
version = "1.0.4"
|
||||
version = "1.0.6+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e"
|
||||
checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44"
|
||||
dependencies = [
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.43"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647"
|
||||
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
||||
dependencies = [
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
@@ -3830,9 +3830,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.35"
|
||||
version = "0.1.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c"
|
||||
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
368
src/main.rs
368
src/main.rs
@@ -2,9 +2,9 @@
|
||||
|
||||
use std::{
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
io::{BufReader, Write},
|
||||
sync::mpsc::{Receiver, channel},
|
||||
thread::sleep,
|
||||
io::BufReader,
|
||||
sync::mpsc::{Receiver, Sender, channel},
|
||||
thread::{sleep, spawn},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
@@ -17,6 +17,60 @@ use egui::{
|
||||
use egui_alignments::{center_horizontal, column};
|
||||
|
||||
const WORKER_THREAD_POLL: Duration = Duration::from_secs(5);
|
||||
const LABEL_EXTRACTOR: &[u8; 2124] = include_bytes!("./extractor.dex");
|
||||
|
||||
type FrontendPayload = PackageDiff;
|
||||
|
||||
struct App {
|
||||
search_query: String,
|
||||
uninstallable: bool,
|
||||
reinstallable: bool,
|
||||
entries: BTreeMap<String, Entry>,
|
||||
package_diff_rx: Receiver<FrontendPayload>,
|
||||
device_lost_rx: Receiver<()>,
|
||||
action_tx: Sender<Action>,
|
||||
disable_mode: bool,
|
||||
|
||||
have_device: bool,
|
||||
}
|
||||
|
||||
type PackageIdentifier = String;
|
||||
type PackagePath = String;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Package {
|
||||
id: PackageIdentifier,
|
||||
path: PackagePath,
|
||||
label: String,
|
||||
}
|
||||
|
||||
struct Entry {
|
||||
package: Package,
|
||||
expand_triggered: bool,
|
||||
enabled: bool,
|
||||
selected: bool,
|
||||
}
|
||||
|
||||
struct PackageDiff {
|
||||
added: Vec<Package>,
|
||||
removed: Vec<PackageIdentifier>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ShellRunError {
|
||||
Timeout,
|
||||
ParseError,
|
||||
Unrecoverable,
|
||||
UnsuccessfulOperation(PackageIdentifier),
|
||||
BackupNotPossible(PackageIdentifier),
|
||||
RevertFailed(PackageIdentifier),
|
||||
}
|
||||
|
||||
pub enum Action {
|
||||
Uninstall(Package),
|
||||
Revert(PackageIdentifier),
|
||||
Disable(PackageIdentifier),
|
||||
}
|
||||
|
||||
fn main() -> eframe::Result {
|
||||
env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`).
|
||||
@@ -25,58 +79,18 @@ fn main() -> eframe::Result {
|
||||
..Default::default()
|
||||
};
|
||||
eframe::run_native(
|
||||
"My egui App",
|
||||
"Zilch",
|
||||
options,
|
||||
Box::new(|cc| {
|
||||
let (package_diff_tx, package_diff_rx) = channel();
|
||||
let (device_lost_tx, device_lost_rx) = channel();
|
||||
let (action_tx, action_rx) = channel();
|
||||
|
||||
let ctx = cc.egui_ctx.clone();
|
||||
std::thread::spawn(move || {
|
||||
let mut device: Option<ADBUSBDevice> = None;
|
||||
let mut pkg_set: BTreeSet<String> = Default::default();
|
||||
|
||||
loop {
|
||||
while device.is_none() {
|
||||
device = ADBUSBDevice::autodetect().ok();
|
||||
|
||||
sleep(WORKER_THREAD_POLL);
|
||||
}
|
||||
|
||||
if let Some(device_mut) = device.as_mut() {
|
||||
let mut label_extractor_dex_stream = BufReader::new(&LABEL_EXTRACTOR[..]);
|
||||
let remote_path = "/data/local/tmp/extractor.dex";
|
||||
device_mut
|
||||
.push(&mut label_extractor_dex_stream, &remote_path)
|
||||
.expect("failed to upload extractor to the device");
|
||||
}
|
||||
|
||||
while let Some(device_mut) = device.as_mut() {
|
||||
match fetch_packages(device_mut, &pkg_set) {
|
||||
Ok((diff, new_pkg_set)) => {
|
||||
if diff.added.is_empty() && diff.removed.is_empty() {
|
||||
sleep(WORKER_THREAD_POLL);
|
||||
continue;
|
||||
}
|
||||
pkg_set = new_pkg_set;
|
||||
package_diff_tx.send(diff).expect("failed to send to ui");
|
||||
}
|
||||
Err(FetchPackageError::Timeout) => {}
|
||||
Err(_log_this_later) => {
|
||||
device = None;
|
||||
pkg_set = BTreeSet::default();
|
||||
device_lost_tx.send(()).expect("failed to send to ui");
|
||||
}
|
||||
}
|
||||
ctx.request_repaint();
|
||||
|
||||
sleep(WORKER_THREAD_POLL);
|
||||
}
|
||||
}
|
||||
});
|
||||
spawn(move || worker_thread(package_diff_tx, device_lost_tx, action_rx, ctx));
|
||||
|
||||
Ok(Box::new(App {
|
||||
n_selected: 0,
|
||||
// n_selected: 0,
|
||||
disable_mode: false,
|
||||
have_device: false,
|
||||
uninstallable: false,
|
||||
@@ -85,39 +99,120 @@ fn main() -> eframe::Result {
|
||||
device_lost_rx,
|
||||
package_diff_rx,
|
||||
entries: Default::default(),
|
||||
action_tx,
|
||||
}))
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
type FrontendPayload = PackageDiff;
|
||||
impl Action {
|
||||
fn apply_on_device(self, device: &mut ADBUSBDevice) -> Result<(), ShellRunError> {
|
||||
match self {
|
||||
Action::Uninstall(pkg) => {
|
||||
if pkg.path.is_empty() {
|
||||
return Err(ShellRunError::BackupNotPossible(pkg.id));
|
||||
}
|
||||
|
||||
struct App {
|
||||
search_query: String,
|
||||
uninstallable: bool,
|
||||
reinstallable: bool,
|
||||
n_selected: usize,
|
||||
entries: BTreeMap<String, Entry>,
|
||||
package_diff_rx: Receiver<FrontendPayload>,
|
||||
device_lost_rx: Receiver<()>,
|
||||
disable_mode: bool,
|
||||
let _copy_command_no_output = device.shell_command_text(&format!(
|
||||
"cp {} /data/local/tmp/{}.apk",
|
||||
pkg.path, pkg.id
|
||||
))?;
|
||||
|
||||
have_device: bool,
|
||||
let output =
|
||||
device.shell_command_text(&format!("pm uninstall --user 0 -k {}", pkg.id))?;
|
||||
|
||||
if !output.contains("Success") {
|
||||
return Err(ShellRunError::UnsuccessfulOperation(pkg.id));
|
||||
}
|
||||
}
|
||||
Action::Revert(id) => {
|
||||
let revert_command = format!("package install-existing {id}");
|
||||
let output = device.shell_command_text(&revert_command)?;
|
||||
// eprintln!("revert output {output:?}");
|
||||
|
||||
if !output.contains("inaccessible or not found") {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let revert_command = format!("pm install -r --user 0 /data/local/tmp/{id}.apk");
|
||||
let output = device.shell_command_text(&revert_command)?;
|
||||
if !output.contains("Success") {
|
||||
return Err(ShellRunError::RevertFailed(id));
|
||||
}
|
||||
}
|
||||
Action::Disable(id) => {
|
||||
let disable_command = format!("pm disable --user 0 {id}");
|
||||
let output = device.shell_command_text(&disable_command)?;
|
||||
eprintln!("disable output {output:?}");
|
||||
|
||||
// for id in items {
|
||||
// let output =
|
||||
// device.shell_command_text(&format!("pm uninstall --user 0 -k {id}"))?;
|
||||
|
||||
// if !output.contains("Success") {
|
||||
// return Err(ShellRunError::UnsuccessfulOperation(id));
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Package {
|
||||
id: String,
|
||||
path: String,
|
||||
label: String,
|
||||
}
|
||||
fn worker_thread(
|
||||
package_diff_tx: Sender<PackageDiff>,
|
||||
device_lost_tx: Sender<()>,
|
||||
action_rx: Receiver<Action>,
|
||||
ctx: egui::Context,
|
||||
) {
|
||||
let mut maybe_device: Option<ADBUSBDevice> = None;
|
||||
let mut pkg_set: BTreeSet<PackageIdentifier> = Default::default();
|
||||
|
||||
struct Entry {
|
||||
id: String,
|
||||
label: String,
|
||||
expand_triggered: bool,
|
||||
enabled: bool,
|
||||
selected: bool,
|
||||
loop {
|
||||
while maybe_device.is_none() {
|
||||
maybe_device = ADBUSBDevice::autodetect().ok();
|
||||
if maybe_device.is_none() {
|
||||
sleep(WORKER_THREAD_POLL);
|
||||
} else {
|
||||
eprintln!("watermelon");
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(device) = maybe_device.as_mut() {
|
||||
eprintln!("cocomelon");
|
||||
let mut label_extractor_dex_stream = BufReader::new(&LABEL_EXTRACTOR[..]);
|
||||
let remote_path = "/data/local/tmp/extractor.dex";
|
||||
device
|
||||
.push(&mut label_extractor_dex_stream, &remote_path)
|
||||
.expect("failed to upload extractor to the device");
|
||||
eprintln!("pushed");
|
||||
}
|
||||
|
||||
while let Some(device) = maybe_device.as_mut() {
|
||||
if let Ok(action) = action_rx.try_recv() {
|
||||
action.apply_on_device(device);
|
||||
}
|
||||
match fetch_packages(device, &pkg_set) {
|
||||
Ok((diff, new_pkg_set)) => {
|
||||
if diff.added.is_empty() && diff.removed.is_empty() {
|
||||
sleep(WORKER_THREAD_POLL);
|
||||
continue;
|
||||
}
|
||||
pkg_set = new_pkg_set;
|
||||
package_diff_tx.send(diff).expect("failed to send to ui");
|
||||
}
|
||||
Err(ShellRunError::Timeout) => {}
|
||||
Err(_log_this_later) => {
|
||||
maybe_device = None;
|
||||
pkg_set = BTreeSet::default();
|
||||
device_lost_tx.send(()).expect("failed to send to ui");
|
||||
}
|
||||
}
|
||||
ctx.request_repaint();
|
||||
|
||||
sleep(WORKER_THREAD_POLL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl eframe::App for App {
|
||||
@@ -130,8 +225,7 @@ impl eframe::App for App {
|
||||
self.entries.insert(
|
||||
package.id.clone(),
|
||||
Entry {
|
||||
id: package.id,
|
||||
label: package.label,
|
||||
package,
|
||||
expand_triggered: false,
|
||||
enabled: true,
|
||||
selected: false,
|
||||
@@ -177,19 +271,13 @@ impl eframe::App for App {
|
||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||
self.uninstallable = false;
|
||||
self.reinstallable = false;
|
||||
self.n_selected = 0;
|
||||
|
||||
for (_id, entry) in self.entries.iter_mut() {
|
||||
render_entry(ui, entry);
|
||||
if !entry.selected {
|
||||
continue;
|
||||
}
|
||||
|
||||
self.n_selected += 1;
|
||||
if entry.enabled {
|
||||
self.uninstallable = true;
|
||||
} else {
|
||||
self.reinstallable = true;
|
||||
for (id, entry) in self.entries.iter_mut() {
|
||||
let query_lower = self.search_query.to_lowercase();
|
||||
if id.to_lowercase().contains(&query_lower)
|
||||
|| entry.package.label.to_lowercase().contains(&query_lower)
|
||||
{
|
||||
render_entry(ui, entry);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -209,20 +297,62 @@ impl eframe::App for App {
|
||||
Button::new("uninstall")
|
||||
};
|
||||
|
||||
let mut selected: Vec<&Entry> = vec![];
|
||||
for entry in self.entries.values().filter(|entry| entry.selected) {
|
||||
selected.push(entry);
|
||||
if entry.enabled {
|
||||
self.uninstallable = true;
|
||||
} else {
|
||||
self.reinstallable = true;
|
||||
}
|
||||
}
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
let button_size = [80.0, 30.0];
|
||||
|
||||
if self.uninstallable == self.reinstallable {
|
||||
ui.add_enabled(false, button);
|
||||
ui.add_enabled_ui(false, |ui| {
|
||||
ui.add_sized(button_size, button);
|
||||
});
|
||||
} else if self.uninstallable {
|
||||
ui.add_enabled(true, button);
|
||||
ui.add_enabled_ui(true, |ui| {
|
||||
if !ui.add_sized(button_size, button).clicked() {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.disable_mode {
|
||||
for entry in selected.iter() {
|
||||
self.action_tx
|
||||
.send(Action::Disable(entry.package.id.clone()))
|
||||
.expect("failed to send message to backend");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for entry in selected.iter() {
|
||||
self.action_tx
|
||||
.send(Action::Uninstall(entry.package.clone()))
|
||||
.expect("failed to send message to backend");
|
||||
}
|
||||
});
|
||||
} else if self.reinstallable {
|
||||
ui.add_enabled(true, Button::new("revert"));
|
||||
ui.add_enabled_ui(true, |ui| {
|
||||
if ui.add_sized(button_size, Button::new("revert")).clicked() {
|
||||
for entry in selected.iter() {
|
||||
self.action_tx
|
||||
.send(Action::Revert(entry.package.id.clone()))
|
||||
.expect("failed to send message to backend");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ui.checkbox(&mut self.disable_mode, "disable mode")
|
||||
.on_hover_text("prefer disabling apps to uninstalling");
|
||||
|
||||
ui.separator();
|
||||
ui.label(format!("{} selected", self.n_selected));
|
||||
ui.label(format!("{} selected", selected.len()));
|
||||
ui.separator();
|
||||
});
|
||||
ui.add_space(2.0);
|
||||
@@ -230,47 +360,28 @@ impl eframe::App for App {
|
||||
}
|
||||
}
|
||||
|
||||
const LABEL_EXTRACTOR: &[u8; 2124] = include_bytes!("./extractor.dex");
|
||||
|
||||
struct PackageDiff {
|
||||
added: Vec<Package>,
|
||||
removed: Vec<String>,
|
||||
}
|
||||
|
||||
pub enum FetchPackageError {
|
||||
Timeout,
|
||||
ParseError,
|
||||
Unrecoverable,
|
||||
}
|
||||
|
||||
pub trait ShellCommandExt {
|
||||
fn shell_command_ext(
|
||||
&mut self,
|
||||
command: &str,
|
||||
buf: &mut dyn Write,
|
||||
) -> Result<(), FetchPackageError>;
|
||||
fn shell_command_text(&mut self, command: &str) -> Result<String, ShellRunError>;
|
||||
}
|
||||
|
||||
impl ShellCommandExt for ADBUSBDevice {
|
||||
fn shell_command_ext(
|
||||
&mut self,
|
||||
command: &str,
|
||||
buf: &mut dyn Write,
|
||||
) -> Result<(), FetchPackageError> {
|
||||
self.shell_command(&[command], buf).map_err(|e| match e {
|
||||
adb_client::RustADBError::UsbError(rusb::Error::Timeout) => FetchPackageError::Timeout,
|
||||
_ => FetchPackageError::Unrecoverable,
|
||||
})
|
||||
fn shell_command_text(&mut self, command: &str) -> Result<String, ShellRunError> {
|
||||
let mut buf = Vec::with_capacity(4096);
|
||||
self.shell_command(&[command], &mut buf)
|
||||
.map_err(|e| match e {
|
||||
adb_client::RustADBError::UsbError(rusb::Error::Timeout) => ShellRunError::Timeout,
|
||||
_ => ShellRunError::Unrecoverable,
|
||||
})?;
|
||||
String::from_utf8(buf).map_err(|_| ShellRunError::ParseError)
|
||||
}
|
||||
}
|
||||
|
||||
fn fetch_packages(
|
||||
device: &mut ADBUSBDevice,
|
||||
pkg_set: &BTreeSet<String>,
|
||||
) -> Result<(PackageDiff, BTreeSet<String>), FetchPackageError> {
|
||||
let mut buffer = Vec::with_capacity(1024);
|
||||
device.shell_command_ext("pm list packages -f", &mut buffer)?;
|
||||
let raw_pkg_text = std::str::from_utf8(&buffer).map_err(|_| FetchPackageError::ParseError)?;
|
||||
) -> Result<(PackageDiff, BTreeSet<String>), ShellRunError> {
|
||||
let raw_pkg_text = device.shell_command_text("pm list packages -f")?;
|
||||
eprintln!("fucky fucky?");
|
||||
|
||||
let mut current_set = BTreeSet::new();
|
||||
|
||||
@@ -295,13 +406,9 @@ fn fetch_packages(
|
||||
|
||||
let need_to_fetch_labels = !new_packages.is_empty();
|
||||
if need_to_fetch_labels {
|
||||
let mut buffer = Vec::with_capacity(1024);
|
||||
device.shell_command_ext(
|
||||
"CLASSPATH=/data/local/tmp/extractor.dex app_process / Main",
|
||||
&mut buffer,
|
||||
)?;
|
||||
let raw_pkg_text =
|
||||
std::str::from_utf8(&buffer).map_err(|_| FetchPackageError::ParseError)?;
|
||||
let raw_pkg_text = device
|
||||
.shell_command_text("CLASSPATH=/data/local/tmp/extractor.dex app_process / Main")?;
|
||||
eprintln!("sucky sucky?");
|
||||
|
||||
for line in raw_pkg_text.lines() {
|
||||
let mut splitn = line.splitn(3, ' ');
|
||||
@@ -313,7 +420,6 @@ fn fetch_packages(
|
||||
if let Some(package_mut) = new_packages.get_mut(id) {
|
||||
package_mut.label = label.to_string();
|
||||
}
|
||||
// eprintln!("{line}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,8 +434,8 @@ fn fetch_packages(
|
||||
|
||||
fn create_button(entry: &'_ Entry) -> Button<'_> {
|
||||
let mut job = LayoutJob::default();
|
||||
let mut label = RichText::new(format!("{}\n", entry.label)).size(12.0);
|
||||
let mut package_id = RichText::new(&entry.id).monospace().size(10.0);
|
||||
let mut label = RichText::new(format!("{}\n", entry.package.label)).size(12.0);
|
||||
let mut package_id = RichText::new(&entry.package.id).monospace().size(10.0);
|
||||
let disabled_text_color = Color32::from_rgb(100, 100, 100);
|
||||
|
||||
if !entry.enabled {
|
||||
@@ -358,7 +464,7 @@ fn create_button(entry: &'_ Entry) -> Button<'_> {
|
||||
}
|
||||
|
||||
fn render_entry(ui: &mut egui::Ui, entry: &mut Entry) {
|
||||
let id = ui.make_persistent_id(format!("{}_state", entry.id));
|
||||
let id = ui.make_persistent_id(format!("{}_state", entry.package.id));
|
||||
let mut state =
|
||||
egui::collapsing_header::CollapsingState::load_with_default_open(ui.ctx(), id, false);
|
||||
|
||||
@@ -371,7 +477,7 @@ fn render_entry(ui: &mut egui::Ui, entry: &mut Entry) {
|
||||
ui.style_mut().spacing.button_padding = egui::vec2(20.0, 10.0);
|
||||
ui.with_layout(Layout::top_down_justified(egui::Align::LEFT), |ui| {
|
||||
let response = ui.add(create_button(entry));
|
||||
let id = ui.make_persistent_id(format!("{}_interact", entry.id));
|
||||
let id = ui.make_persistent_id(format!("{}_interact", entry.package.id));
|
||||
if ui
|
||||
.interact(response.rect, id, Sense::click())
|
||||
.double_clicked()
|
||||
|
||||
Reference in New Issue
Block a user