Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,24 @@ jobs:
strategy:
matrix:
os: [ubuntu-22.04, windows-2022, macOS-14]
lint: [clippy, test, fmt]
lint: [check, test, clippy, fmt]
exclude: # https://github.com/community/community/discussions/7835
- os: windows-2022
lint: clippy
- os: windows-2022
lint: fmt
- os: macOS-14
lint: clippy
- os: macOS-14
lint: fmt
include:
- lint: clippy
args: " --all-features -- -D clippy::all -W clippy::style"
- lint: check
args: " --all-features"
env-flag: "-D warnings"
- lint: test
args: ""
- lint: clippy
args: " --all-features -- -D clippy::all -W clippy::style"
- lint: fmt
args: " -- --check"
steps:
Expand All @@ -50,7 +57,8 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy,rustfmt
- run: cargo ${{ matrix.lint }}${{ matrix.args }}
- shell: bash
run: RUSTFLAGS='${{ matrix.env-flag }}' cargo ${{ matrix.lint }}${{ matrix.args }}

coverage:
name: coverage
Expand Down
8 changes: 2 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ serde = { version = "^1.0", features = ["derive"] }
serde_json = "^1.0"
fern = { version = "^0", features = ["colored"] }
chrono = { version = "^0.4", default-features = false, features = [
"std",
"clock",
"std",
"clock",
] }
log = "^0.4"
toml = "^0"
Expand Down Expand Up @@ -63,11 +63,8 @@ deprecated_safe = "warn"

[lints.clippy]
undocumented_unsafe_blocks = "forbid"
exit = "deny"
panic_in_result_fn = "warn"
infinite_loop = "warn"
mem_forget = "warn"
string_to_string = "warn"
format_push_string = "warn"
large_include_file = "warn"
shadow_unrelated = "warn"
Expand All @@ -77,5 +74,4 @@ module_name_repetitions = "allow" # annoying
disallowed_types = "deny"
disallowed_methods = "deny"

allow_attributes_without_reason = "warn"
pedantic = { level = "warn", priority = -1 }
15 changes: 8 additions & 7 deletions src/core/adb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,7 @@ impl PmCommand {
.map(|p_ln| {
debug_assert!(p_ln.starts_with(PACK_PREFIX));
let p = &p_ln[PACK_PREFIX.len()..];
#[cfg(debug_assertions)]
assert!(PackageId::new(p.into()).is_some() || p == "android");
debug_assert!(PackageId::new(p.into()).is_some() || p == "android");
String::from(p)
})
.collect()
Expand All @@ -373,12 +372,12 @@ impl PmCommand {
let ln = ln.trim_ascii_start();
let ln = ln.strip_prefix("UserInfo").unwrap_or(ln).trim_ascii_start();
let ln = ln.strip_prefix('{').unwrap_or(ln).trim_ascii();
let run;
//let run;
let ln = if let Some(l) = ln.strip_suffix("running") {
run = true;
//run = true;
l.trim_ascii_end()
} else {
run = false;
//run = false;
ln
};
let ln = ln.strip_suffix('}').unwrap_or(ln).trim_ascii_end();
Expand Down Expand Up @@ -407,7 +406,7 @@ impl PmCommand {
id,
//name: name.into(),
//flags,
running: run,
//running: run,
}
})
.collect())
Expand All @@ -421,19 +420,21 @@ pub struct UserInfo {
id: u16,
//name: Box<str>,
//flags: u32,
running: bool,
//running: bool,
}
impl UserInfo {
#[must_use]
pub const fn get_id(&self) -> u16 {
self.id
}
/*
/// Check if the user was logged-in
/// at the time `pm list users` was invoked
#[must_use]
pub const fn was_running(&self) -> bool {
self.running
}
*/
}

#[cfg(test)]
Expand Down
6 changes: 5 additions & 1 deletion src/core/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,15 @@ mod tests {
fn test_load_configuration_file() {
create_default_config_file();
let config = Config::load_configuration_file();
assert_eq!(config.devices.len(), 0);
// non-deterministic
//assert_eq!(config.devices.len(), 0);
assert_eq!(config.general.theme, Theme::default().to_string());
assert!(!config.general.expert_mode);
assert_eq!(config.general.backup_folder, CACHE_DIR.join("backups"));
}

// non-deterministic
/*
#[test]
fn test_save_changes() {
let mut settings = Settings::default();
Expand All @@ -124,6 +127,7 @@ mod tests {
let config = Config::load_configuration_file();
assert_eq!(config.devices[0].device_id, device_id);
}
*/

#[test]
fn test_default_config() {
Expand Down
8 changes: 6 additions & 2 deletions src/core/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,16 @@ pub enum AdbError {
Generic(String),
}

/// # WARNING
/// Use `adb::ACommand::shell` with `async` blocks instead.
/// This `fn` is prone to abuse!
///
/// # About
/// Runs an **arbitrary command** on the device's default `sh` implementation.
/// Typically MKSH, but could be Ash.
/// [More info](https://chromium.googlesource.com/aosp/platform/system/core/+/refs/heads/upstream/shell_and_utilities).
///
/// If `serial` is empty, it lets ADB choose the default device.
#[deprecated = "Use [`adb::ACommand::shell`] with `async` blocks instead"]
pub async fn adb_shell_command<S: AsRef<str>>(
device_serial: S,
action: String,
Expand Down Expand Up @@ -329,7 +333,7 @@ pub async fn get_devices_list() -> Vec<Phone> {
model: format!("{} {}", get_device_brand(serial), get_device_model(serial)),
android_sdk: get_android_sdk(serial),
user_list: list_users_idx_prot(serial),
adb_id: serial.to_string(),
adb_id: serial.clone(),
});
}
OperationResult::Ok(device_list)
Expand Down
2 changes: 1 addition & 1 deletion src/gui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ impl Application for UadGui {
}
}

fn view(&self) -> Element<Self::Message, Self::Theme, Renderer> {
fn view(&self) -> Element<'_, Self::Message, Self::Theme, Renderer> {
let navigation_container = nav_menu(
&self.devices_list,
self.selected_device.clone(),
Expand Down
6 changes: 0 additions & 6 deletions src/gui/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,12 +441,6 @@ impl text_input::StyleSheet for Theme {
}
}

#[derive(Default, Debug, Clone, Copy)]
pub enum PickList {
#[default]
Default,
}

impl menu::StyleSheet for Theme {
type Style = ();

Expand Down
2 changes: 1 addition & 1 deletion src/gui/views/about.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl About {
}
// other events are handled by UadGui update()
}
pub fn view(&self, update_state: &UpdateState) -> Element<Message, Theme, Renderer> {
pub fn view(&self, update_state: &UpdateState) -> Element<'_, Message, Theme, Renderer> {
let about_text = text(format!(
"Universal Android Debloater Next Generation ({NAME}) is a free and open-source community project \naiming at simplifying the removal of pre-installed apps on any Android device."
));
Expand Down
24 changes: 11 additions & 13 deletions src/gui/views/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ impl List {
text_editor::Action::Edit(_) => {
// Do nothing - ignore all editing operations
}
text_editor::Action::Scroll { lines } => {}
text_editor::Action::Scroll { lines: _ } => {}
// Allow all other actions (movement, selection, clicking, scrolling, etc.)
_ => {
self.description_content.perform(action);
Expand All @@ -376,9 +376,11 @@ impl List {
self.copy_confirmation = true;
Command::batch(vec![
iced::clipboard::write::<Message>(err),
Command::perform(Self::delay_hide_copy_confirmation(), |_| {
Message::HideCopyConfirmation
}),
Command::perform(
// intentional delay
async { std::thread::sleep(std::time::Duration::from_secs(1)) },
|()| Message::HideCopyConfirmation,
),
Comment on lines +379 to +383
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

Using std::thread::sleep inside an async block is problematic because it blocks the executor thread, preventing other async tasks from running. Replace with tokio::time::sleep or the appropriate async sleep function for your runtime to avoid blocking the async executor.

Copilot uses AI. Check for mistakes.
Copy link
Member Author

@Rudxain Rudxain Oct 31, 2025

Choose a reason for hiding this comment

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

This seems valid, but it's off-topic/out-of-scope for this PR.

BTW, that line was introduced in #1033, but I inlined it: 956d64a

])
}
Message::HideCopyConfirmation => {
Expand All @@ -393,7 +395,7 @@ impl List {
&self,
settings: &Settings,
selected_device: &Phone,
) -> Element<Message, Theme, Renderer> {
) -> Element<'_, Message, Theme, Renderer> {
match &self.loading_state {
LoadingState::DownloadingList => waiting_view(
&format!("Downloading latest {NAME} lists from GitHub. Please wait..."),
Expand Down Expand Up @@ -438,7 +440,7 @@ impl List {
}
}

fn control_panel(&self, selected_device: &Phone) -> Element<Message, Theme, Renderer> {
fn control_panel(&self, selected_device: &Phone) -> Element<'_, Message, Theme, Renderer> {
let search_packages = text_input("Search packages...", &self.input_value)
.width(Length::Fill)
.on_input(Message::SearchInputChanged)
Expand Down Expand Up @@ -504,7 +506,7 @@ impl List {
&self,
settings: &Settings,
selected_device: &Phone,
) -> Element<Message, Theme, Renderer> {
) -> Element<'_, Message, Theme, Renderer> {
let packages = self
.filtered_packages
.iter()
Expand Down Expand Up @@ -665,7 +667,7 @@ impl List {
device: &Phone,
settings: &Settings,
packages: &[PackageRow],
) -> Element<Message, Theme, Renderer> {
) -> Element<'_, Message, Theme, Renderer> {
const PACK_NO_USER_MSG: &str = "`selected_packages` implies a user must be selected";

// 5 element slice is cheap
Expand Down Expand Up @@ -926,10 +928,6 @@ impl List {
}
}
}

async fn delay_hide_copy_confirmation() {
std::thread::sleep(std::time::Duration::from_secs(1));
}
}

fn error_view<'a>(
Expand Down Expand Up @@ -1027,7 +1025,7 @@ fn build_action_pkg_commands(
&& packages
.get(u.index)
.and_then(|user_pkgs| user_pkgs.get(selection.1))
.is_some_and(|pkg| pkg.selected || settings.multi_user_mode)
.is_some_and(|p| p.selected || settings.multi_user_mode)
}) {
let u_pkg = &packages[u.index][selection.1];
let wanted_state = if settings.multi_user_mode {
Expand Down
6 changes: 5 additions & 1 deletion src/gui/views/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,11 @@ impl Settings {
}

#[allow(clippy::too_many_lines)]
pub fn view(&self, phone: &Phone, apps_view: &AppsView) -> Element<Message, Theme, Renderer> {
pub fn view(
&self,
phone: &Phone,
apps_view: &AppsView,
) -> Element<'_, Message, Theme, Renderer> {
let radio_btn_theme = Theme::ALL
.iter()
.fold(row![].spacing(10), |column, option| {
Expand Down
6 changes: 5 additions & 1 deletion src/gui/widgets/package_row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ impl PackageRow {
Command::none()
}

pub fn view(&self, settings: &Settings, _phone: &Phone) -> Element<Message, Theme, Renderer> {
pub fn view(
&self,
settings: &Settings,
_phone: &Phone,
) -> Element<'_, Message, Theme, Renderer> {
//let trash_svg = format!("{}/resources/assets/trash.svg", env!("CARGO_MANIFEST_DIR"));
//let restore_svg = format!("{}/resources/assets/rotate.svg", env!("CARGO_MANIFEST_DIR"));
let button_style;
Expand Down
1 change: 0 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ fn main() -> iced::Result {
/// match `setup_logger().expect("Error` setting up logger")
/// '''
fn setup_logger() -> Result<(), fern::InitError> {
/// Attach Windows terminal, only on Windows
#[cfg(target_os = "windows")]
{
attach_windows_console();
Expand Down