Compare commits

...

20 commits

Author SHA1 Message Date
Anonymoussaurus
44abeefb71
Merge pull request #1451 from Universal-Debloater-Alliance/feat/default-disable
feat(settings): disable-mode by default
2026-08-09 02:57:12 +02:00
Rudxain
67f880b507
feat(settings): Disable-mode by default
- feat(settings): `disable_mode=true` if device supports it; update description
- refactor: define `supports_disabling` and use it whenever possible
- refactor(sync): inline `MULTI_USER_SDK`, with tiny comment
- docs(sync): rm redundant "Android"
2026-08-07 18:38:46 -04:00
Anonymoussaurus
14d2f29f0a
Merge pull request #1450 from jarekt/patch-1
pkg(com.android.networkstack.tethering.inprocess): change description and removal
2026-08-05 15:27:31 +02:00
Jarek
f3df24beb9
change com.android.networkstack.tethering.inprocess to unsafe 2026-08-05 14:57:22 +02:00
Anonymoussaurus
2379e852ce
Merge pull request #1438 from TechyDodoDevMan/patch-1
pkg(com.google.android.wearable.pixel.aspen): add package
2026-08-03 14:42:15 +02:00
TechyDodoDevMan
3c4011807b
Change removal recommendation from 'Recommended' to 'Advanced'
Resolved suggestion
2026-07-30 16:12:33 -04:00
TechyDodoDevMan
9dbdd59b0e
Merge branch 'main' into patch-1 2026-07-30 16:10:39 -04:00
Anonymoussaurus
ef94066d65
Merge pull request #1439 from insanebecauseimbestwheniminlove/main
pkg(xiaomi): add package
2026-07-25 15:16:21 +02:00
insanebecauseimbestwheniminlove
266f1b9597
Update uad_lists.json 2026-07-25 03:53:55 +02:00
TechyDodoDevMan
856606c58b
Update uad_lists.json
Added Fitbit Connected Fitness
2026-07-24 12:05:16 -04:00
Anonymoussaurus
9336f25e7d
Merge pull request #1433 from Wakelock/main
pkg(blackview, huawei): add and edit packages
2026-07-22 11:54:43 +02:00
Wakelock
3f55e6cdba
Update uad_lists.json 2026-07-18 10:25:28 +00:00
Wakelock
c38c1cd2d0
Update uad_lists.json 2026-07-18 10:05:39 +00:00
Wakelock
31234bed3c
Update uad_lists.json 2026-07-18 09:50:33 +00:00
Wakelock
067f2251e9
Update uad_lists.json 2026-07-18 09:43:54 +00:00
André Klein
43d323332f
fix(core): two bugs blocking package operations on real devices (#1430)
* fix(core): two bugs blocking package operations on real devices

- adb.rs: replace debug_assert! in list_packages_sys with filter_map
  to avoid panicking on nonstandard package names from real devices.
- sync.rs: fix inverted guard in request_builder (is_some -> is_none)
  that was rejecting every valid package name instead of invalid ones.
2026-07-16 17:35:15 -04:00
Wakelock
4ec90fa807
Update uad_lists.json 2026-07-16 10:07:28 +00:00
Wakelock
85c0d67776
Update uad_lists.json 2026-07-16 10:04:11 +00:00
Wakelock
3bc538292d
Update uad_lists.json 2026-07-16 07:47:04 +00:00
Wakelock
93c83863a6
Update uad_lists.json 2026-07-16 07:28:22 +00:00
5 changed files with 100 additions and 26 deletions

View file

@ -44,7 +44,7 @@ use std::rc::Rc;
use std::os::windows::process::CommandExt;
use crate::utils::is_all_w_c;
use log::{error, info};
use log::{error, info, warn};
/// Convert ADB output bytes to a trimmed UTF-8 string.
/// Uses lossy conversion to prevent panics on non-UTF8 output from certain OEMs.
@ -366,11 +366,15 @@ impl PmCommand {
self.0.0.run().map(|pack_ls| {
pack_ls
.lines()
.map(|p_ln| {
.filter_map(|p_ln| {
debug_assert!(p_ln.starts_with(PACK_PREFIX));
let p = &p_ln[PACK_PREFIX.len()..];
debug_assert!(PackageId::new(p).is_some());
String::from(p)
if PackageId::new(p).is_some() {
Some(String::from(p))
} else {
warn!("skipping nonstandard package name: {p:?}");
None
}
})
.collect()
})

View file

@ -37,7 +37,7 @@ pub struct BackupSettings {
pub struct DeviceSettings {
/// Unique serial identifier
pub device_id: String,
pub disable_mode: bool,
pub disable_mode: bool, // should be `enum RemovalMode`
pub multi_user_mode: bool,
#[serde(skip)]
pub backup: BackupSettings,

View file

@ -180,16 +180,19 @@ pub fn apply_pkg_state_commands(
_ => vec![],
},
PackageState::Disabled => match package.state {
PackageState::Uninstalled | PackageState::Enabled => match phone.android_sdk {
sdk if sdk >= 23 => vec!["pm disable-user", "am force-stop", PM_CLEAR_PACK],
_ => vec![],
},
PackageState::Uninstalled | PackageState::Enabled => {
if supports_disabling(phone) {
vec!["pm disable-user", "am force-stop", PM_CLEAR_PACK]
} else {
vec![]
}
}
_ => vec![],
},
PackageState::Uninstalled => match package.state {
PackageState::Enabled | PackageState::Disabled => match phone.android_sdk {
sdk if sdk >= 23 => vec!["pm uninstall"], // > Android Marshmallow (6.0)
21 | 22 => vec!["pm hide", PM_CLEAR_PACK], // Android Lollipop (5.x)
sdk if sdk >= 23 => vec!["pm uninstall"], // > Marshmallow (6.0)
21 | 22 => vec!["pm hide", PM_CLEAR_PACK], // Lollipop (5.x)
_ => vec!["pm block", PM_CLEAR_PACK], // Disable mode is unavailable on older devices because the specific ADB commands need root
},
_ => vec![],
@ -213,7 +216,7 @@ pub fn request_builder(commands: &[&str], package: &str, user: Option<User>) ->
// guarantee local to the sink instead of relying on each caller to sanitise.
// Fail closed: emit no command for a malformed name rather than an injectable
// device-shell string.
if PackageId::new(package).is_some() {
if PackageId::new(package).is_none() {
error!("request_builder: refusing invalid package name: {package:?}");
return Vec::new();
}
@ -401,10 +404,11 @@ pub fn detect_cross_user_behavior(
}
}
/// Minimum inclusive Android SDK version
/// that supports multi-user mode.
/// Lollipop 5.0
pub const MULTI_USER_SDK: u8 = 21;
#[must_use]
pub const fn supports_disabling(dev: &Phone) -> bool {
// >= Marshmallow (6.0)
dev.android_sdk >= 23
}
/// Check if it might support multi-user mode,
/// by simply comparing SDK version.
@ -415,7 +419,8 @@ pub const MULTI_USER_SDK: u8 = 21;
/// - <https://developer.android.com/reference/android/os/UserManager#supportsMultipleUsers()>
#[must_use]
pub const fn supports_multi_user(dev: &Phone) -> bool {
dev.android_sdk >= MULTI_USER_SDK
// >= Lollipop (5.0)
dev.android_sdk >= 21
}
/// Check if a `user_id` is protected on a device by trying

View file

@ -19,7 +19,7 @@ use uad_core::{
save::{backup_phone, list_available_backup_user, list_available_backups, restore_backup},
sync::{
AdbError, CorePackage, Phone, User, get_android_sdk, run_adb_shell_action,
supports_multi_user,
supports_disabling, supports_multi_user,
},
utils::{DisplayablePath, Error, NAME, export_packages, generate_backup_name, open_url},
};
@ -113,7 +113,7 @@ impl Settings {
}
fn handle_disable_mode(&mut self, phone: &Phone, toggled: bool) -> Task<Message> {
if phone.android_sdk >= 23 {
if supports_disabling(phone) {
self.device.disable_mode = toggled;
debug!("Config change: {self:?}");
let mut config = Config::load_configuration_file();
@ -170,8 +170,9 @@ impl Settings {
None => {
self.device = DeviceSettings {
device_id: phone.adb_id.clone(),
// see FAQ, and GH-issue #1426
disable_mode: supports_disabling(phone),
multi_user_mode: supports_multi_user(phone),
disable_mode: false,
backup,
};
}
@ -498,14 +499,14 @@ impl Settings {
.size(20)
.style(style::CheckBox::SettingsEnabled);
let disable_checkbox_style = if phone.android_sdk >= 23 {
let disable_checkbox_style = if supports_disabling(phone) {
style::CheckBox::SettingsEnabled
} else {
style::CheckBox::SettingsDisabled
};
let disable_mode_descr =
text("In some cases, it can be better to disable a package instead of uninstalling it")
text("In many cases, it's better to disable a package instead of uninstalling it")
.style(style::Text::Commentary);
let unavailable_btn = button(text("Unavailable").size(14))
@ -522,7 +523,7 @@ impl Settings {
.size(20)
.style(disable_checkbox_style);
let disable_setting_row = if phone.android_sdk >= 23 {
let disable_setting_row = if supports_disabling(phone) {
row![
disable_mode_checkbox,
Space::new().width(Length::Fill).height(Length::Shrink),

View file

@ -23,6 +23,14 @@
"labels": [],
"removal": "Unsafe"
},
"com.google.android.wearable.pixel.aspen": {
"list": "Oem",
"description": "Fitbit's Connected Fitness feature for the Pixel Watch. Can be safely removed if you don't need/use it.",
"dependencies": [],
"neededBy": [],
"labels": [],
"removal": "Advanced"
},
"org.lineageos.recorder": {
"list": "Oem",
"description": "LineageOS Voice Recorder App.\nSafe to remove if you don't need it or have replaced it with another app.",
@ -367,6 +375,14 @@
"labels": [],
"removal": "Advanced"
},
"com.xiaomi.aiservice": {
"list": "Oem",
"description": "Xiaomi on-device AI inference engine (HyperOS/MIUI). Runs many ML models (OCR, translation, etc.) in isolated per-model processes. \nEmbeds Xiaomi's OneTrack SDK, which collects OAID, android_id, device fingerprint, region, network type, and per-event usage data, then uploads it encrypted to tracking.*.miui.com. \nAlso embeds XCrash for crash reporting. Downloads AI model updates silently via Android DownloadManager (probably has to do with AI Core). \nRemoving probably breaks HyperOS AI features (I haven't tested) but does not affect core phone, SMS, or data functions.",
"dependencies": [],
"neededBy": [],
"labels": [],
"removal": "Advanced"
},
"com.xiaomi.phone.overlay": {
"list": "Oem",
"description": "An overlay needed for com.xiaomi.phone. Safe to remove if com.xiaomi.phone has been removed.",
@ -41220,7 +41236,7 @@
},
"com.blackview.filetrans": {
"list": "Oem",
"description": "Moving Assistant/Data Migration Assistant\nApp used to transfer data from one device to another.\nWARNING: Uninstalling it breaks the App info Settings page on Android 15, Blackview Tab 60 WiFi.",
"description": "Moving Assistant/Data Migration Assistant\nApp used to transfer data from one device to another.\nWARNING: Uninstalling it breaks the App info Settings page on Android 15, Blackview Tab 60 WiFi.\nTry disabling instead of uninstalling in case that happens.",
"dependencies": [],
"neededBy": [],
"labels": [],
@ -42212,11 +42228,11 @@
},
"com.android.networkstack.tethering.inprocess": {
"list": "Oem",
"description": "Completely empty package. Useless.",
"description": "Causes a lockscreen loop on some Xiaomi devices. Provides TetherableWifiRegexs, the lack of which crashes systemui and miui.home.",
"dependencies": [],
"neededBy": [],
"labels": [],
"removal": "Recommended"
"removal": "Unsafe"
},
"com.samsung.android.a20.d01.wallpapermulti": {
"list": "Oem",
@ -43131,5 +43147,53 @@
"neededBy": [],
"labels": [],
"removal": "Expert"
},
"com.blackview.systemmanager": {
"list": "Oem",
"description": "'System Manager'\nA pre-installed 'task killer', which ironically slows down the system. It also has internet and install apps permisions by default, making it a potential backdoor.\nAlthough 'systemmanager' might sound important, disabling it will significantly reduce scroll stuttering. Try disabling instead of uninstalling in case that breaks the App info Settings page.",
"dependencies": [],
"neededBy": [],
"labels": [],
"removal": "Advanced"
},
"com.blackview.apkupgrade": {
"list": "Oem",
"description": "System Message\nAdware, sends unwanted promotional notifications.\nTry disabling instead of uninstalling in case that breaks the App info Settings page.\nhttps://www.reddit.com/r/blackview/comments/1mo441x/get_rid_of_system_notification_that_contains_ads/",
"dependencies": [],
"neededBy": [],
"labels": [],
"removal": "Advanced"
},
"com.huawei.localBackup": {
"list": "Oem",
"description": "Backup\nA hidden app, which has storage, location, contacts, SMS, call logs and calendar permissions. Can be uninstalled via Settings.",
"dependencies": [],
"neededBy": [],
"labels": [],
"removal": "Recommended"
},
"com.huawei.aml": {
"list": "Oem",
"description": "Huawei AML\nA hidden app, which has phone, location and SMS permissions.",
"dependencies": [],
"neededBy": [],
"labels": [],
"removal": "Recommended"
},
"com.blackview.helper": {
"list": "Oem",
"description": "DKHelper\nTry disabling instead of uninstalling in case that breaks the App info Settings page.",
"dependencies": [],
"neededBy": [],
"labels": [],
"removal": "Advanced"
},
"com.softwinner.dragonatt": {
"list": "Oem",
"description": "DragonAtt",
"dependencies": [],
"neededBy": [],
"labels": [],
"removal": "Recommended"
}
}